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

streaming_lib.c (85311B)


      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  * Streaming library for diagnostic (TR) tests.
      8  * This library contains functions use by streaming diagnostic tests.
      9  */
     10 
     11 
     12 #include <appl/diag/system.h>
     13 #include <appl/diag/test.h>
     14 #include <appl/diag/parse.h>
     15 
     16 #include <shared/alloc.h>
     17 #include <shared/bsl.h>
     18 
     19 #include <soc/cmicm.h>
     20 #include <soc/mcm/cmicm.h>
     21 #include <soc/cmic.h>
     22 #include <soc/cm.h>
     23 #include <soc/dma.h>
     24 #include <soc/drv.h>
     25 #include <soc/dcb.h>
     26 #include <soc/iproc.h>
     27 #include <soc/phyctrl.h>
     28 
     29 #include <sal/types.h>
     30 #include <bcm/vlan.h>
     31 #include <bcm/port.h>
     32 
     33 #include "gen_pkt.h"
     34 #include "streaming_lib.h"
     35 
     36 #if defined(BCM_ESW_SUPPORT) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT))
     37 
     38 #define DMA_CHAN_PER_CMC(unit) (SOC_VCHAN_NUM(unit) / SOC_CMCS_NUM(unit))
     39 
     40 /*
     41  * Function:
     42  *      stream_print_port_config
     43  * Purpose:
     44  *      Print port config
     45  * Parameters:
     46  *      unit - StrataSwitch Unit #.
     47  *
     48  * Returns:
     49  *     Nothing
     50  */
     51 void
     52 stream_print_port_config(int unit, pbmp_t pbmp)
     53 {
     54     int cnt = 0,port, port_speed;
     55 
     56     LOG_INFO(BSL_LS_APPL_TESTS,
     57             (BSL_META_U(unit, "\n=========== PORT CONFIG INFO ============\n")));
     58     LOG_INFO(BSL_LS_APPL_TESTS,
     59             (BSL_META_U(unit, "\n%4s %4s %4s %6s %6s\n"),
     60                         "idx", "port", "spd", "LR/OS", "EH/HG"));
     61     PBMP_ITER(pbmp, port) {
     62         if (port < SOC_MAX_NUM_PORTS) {
     63             bcm_port_speed_get(unit, port, &port_speed);
     64             LOG_INFO(BSL_LS_APPL_TESTS,
     65                      (BSL_META_U(unit, "%4d "), cnt));
     66             LOG_INFO(BSL_LS_APPL_TESTS,
     67                      (BSL_META_U(unit, "%4d "), port));
     68             LOG_INFO(BSL_LS_APPL_TESTS,
     69                      (BSL_META_U(unit, "%3dG "), port_speed/1000));
     70             if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) {
     71                 LOG_INFO(BSL_LS_APPL_TESTS,
     72                          (BSL_META_U(unit, "%6s "), "OVSB"));
     73             } else {
     74                 LOG_INFO(BSL_LS_APPL_TESTS,
     75                          (BSL_META_U(unit, "%6s "), "LR"));
     76             }
     77             if (IS_HG_PORT(unit, port)) {
     78                 LOG_INFO(BSL_LS_APPL_TESTS,
     79                          (BSL_META_U(unit, "%6s "), "HG"));
     80             } else {
     81                 LOG_INFO(BSL_LS_APPL_TESTS,
     82                          (BSL_META_U(unit, "%6s "), "EHTN"));
     83             }
     84             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
     85             cnt++;
     86         }
     87     }
     88     LOG_INFO(BSL_LS_APPL_TESTS,(BSL_META_U(unit, "\n\n")));
     89 }
     90 
     91 /*
     92  * Function:
     93  *      stream_get_port_pipe
     94  * Purpose:
     95  *      Get pipe number for a given device port.
     96  * Parameters:
     97  *      unit: StrataSwitch Unit #.
     98  *      port: Device port #
     99  *
    100  * Returns:
    101  *     Pipe number.
    102  */
    103 uint32
    104 stream_get_port_pipe(int unit, int port)
    105 {
    106     uint32 pipe;
    107 
    108     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    109         if (SOC_PBMP_MEMBER(PBMP_PIPE(unit, pipe), port)) {
    110             break;
    111         }
    112     }
    113     return pipe;
    114 }
    115 
    116 /*
    117  * Function:
    118  *      stream_get_pkt_cell_cnt
    119  * Purpose:
    120  *      Get the cell count for a given packet size.
    121  * Parameters:
    122  *      unit: StrataSwitch Unit #
    123  *      pkt_size: packet size in bytes
    124  *      port: Device port #
    125  *
    126  * Returns:
    127  *     Cell count
    128  */
    129 uint32
    130 stream_get_pkt_cell_cnt(int unit, uint32 pkt_size, int port)
    131 {
    132     uint32 num_cells = 1;
    133     uint32 i;
    134 
    135     if (IS_HG_PORT(unit, port)) {
    136         i = FIRST_CELL_HG2;
    137     }
    138     else {
    139         i = FIRST_CELL_ENET;
    140     }
    141     while (i < pkt_size) {
    142         num_cells++;
    143         i += CELL_SIZE;
    144     }
    145     return num_cells;
    146 }
    147 
    148 /*
    149  * Function:
    150  *      stream_get_safe_pkt_size
    151  * Purpose:
    152  *      Calculate safe packet size based on oversub ratio. The assumption is that
    153  *      a front panel port will behave essentially as a line rate port and show no
    154  *      bandwidth degradation for packet sizes above the safe packet size.
    155  *      This is based on input from device microarchitects. Broadcom internal
    156  *      users of this test can contact microarchitecture for more info.
    157  * Parameters:
    158  *      unit: StrataSwitch Unit #.
    159  *      ovs_ratio_x1000: Oversub ratio x1000
    160  *
    161  * Returns:
    162  *     Safe packet size.
    163  */
    164 uint32
    165 stream_get_safe_pkt_size(int unit, int ovs_ratio_x1000)
    166 {
    167     uint32 safe_size = 64;
    168 
    169     if (ovs_ratio_x1000 <= 1507) {
    170         safe_size =
    171             145 +
    172             ((((229000 - 144000) / (1507 - 1000)) * (ovs_ratio_x1000 -
    173                                                      1000)) / 1000);
    174     } else if ((ovs_ratio_x1000 > 1507) && (ovs_ratio_x1000 <= 1760)) {
    175         safe_size =
    176             353 +
    177             ((((416000 - 353000) / (1760 - 1508)) * (ovs_ratio_x1000 -
    178                                                      1508)) / 1000);
    179     } else if ((ovs_ratio_x1000 > 1760) && (ovs_ratio_x1000 <= 1912)) {
    180         safe_size =
    181             562 +
    182             ((((611000 - 562000) / (1912 - 1760)) * (ovs_ratio_x1000 -
    183                                                      1760)) / 1000);
    184     } else {
    185         safe_size = 770;
    186     }
    187 
    188     return safe_size;
    189 }
    190 
    191 /*
    192  * Function:
    193  *      stream_get_ll_flood_cnt
    194  * Purpose:
    195  *      Calculates number of packets that need to be sent to a port for a
    196  *      lossless swirl
    197  * Parameters:
    198  *      unit - StrataSwitch Unit #.
    199  *      pkt_size : Packet size in bytes
    200  *      port: Device port #
    201  * Returns:
    202  *     Number of packets needed for lossless flooding
    203  */
    204 uint32
    205 stream_get_ll_flood_cnt(int unit, int port, uint32 pkt_size,
    206                         uint32 *rand_pkt_size)
    207 {
    208     uint32 flood_pkt_cnt = 0;
    209     uint32 total_cells = 0;
    210 
    211     if (pkt_size == 1 && rand_pkt_size != NULL) {
    212         while (total_cells < TARGET_CELL_COUNT &&
    213                flood_pkt_cnt < TARGET_CELL_COUNT) {
    214             total_cells += stream_get_pkt_cell_cnt(unit,
    215                                      rand_pkt_size[flood_pkt_cnt],
    216                                      port);
    217             flood_pkt_cnt++;
    218         }
    219     } else {
    220         total_cells = stream_get_pkt_cell_cnt(unit, pkt_size, port);
    221         if (total_cells > 0) {
    222             flood_pkt_cnt = TARGET_CELL_COUNT / total_cells;
    223         }
    224     }
    225 
    226     if (flood_pkt_cnt < 3) {
    227         flood_pkt_cnt = 3;
    228     }
    229     if ((flood_pkt_cnt % 2) == 1) {
    230         flood_pkt_cnt++;
    231     }
    232 
    233     return(flood_pkt_cnt);
    234 }
    235 
    236 /*
    237  * Function:
    238  *      stream_get_pipe_bandwidth
    239  * Purpose:
    240  *      Return bandwidth of the given pipe
    241  * Parameters:
    242  *      unit: StrataSwitch Unit #.
    243  *      flag: reserved for special pipe config, i.e. extra 2nd MGMT port.
    244  *
    245  * Returns:
    246  *    Nothing
    247  */
    248 uint32
    249 stream_get_pipe_bandwidth(int unit, uint32 flag)
    250 {
    251     int pipe_bandwidth;
    252     int freq;
    253     uint16 dev_id;
    254     uint8 rev_id;
    255     int cal_universal;
    256 
    257     soc_cm_get_id(unit, &dev_id, &rev_id);
    258     freq = SOC_INFO(unit).frequency;
    259     cal_universal = SOC_INFO(unit).fabric_port_enable ? 1 : 0;
    260 
    261     /* TH */
    262     if (dev_id == BCM56960_DEVICE_ID) {
    263         switch (freq) {
    264             case TH_FREQ_850: pipe_bandwidth = TH_BW_850; break;
    265             case TH_FREQ_765: pipe_bandwidth = TH_BW_765; break;
    266             case TH_FREQ_672: pipe_bandwidth = TH_BW_672; break;
    267             case TH_FREQ_645: pipe_bandwidth = TH_BW_645; break;
    268             case TH_FREQ_545: pipe_bandwidth = TH_BW_545; break;
    269             default: pipe_bandwidth = TH_BW_850; break;
    270         }
    271     }
    272     /* TD2P */
    273     else if (dev_id == BCM56860_DEVICE_ID || dev_id == BCM56850_DEVICE_ID) {
    274         switch (freq) {
    275             case TD2P_FREQ_793: pipe_bandwidth = TD2P_BW_793; break;
    276             case TD2P_FREQ_635: pipe_bandwidth = TD2P_BW_635; break;
    277             case TD2P_FREQ_529: pipe_bandwidth = TD2P_BW_529; break;
    278             case TD2P_FREQ_421: pipe_bandwidth = TD2P_BW_421; break;
    279             default: pipe_bandwidth = TD2P_BW_793; break;
    280         }
    281     }
    282     /* TH 2 */
    283     else if (dev_id == BCM56970_DEVICE_ID) {
    284         switch (freq) {
    285             case TH2_FREQ_1700: pipe_bandwidth = cal_universal ? 1050 : 1095; break;
    286             case TH2_FREQ_1625: pipe_bandwidth = cal_universal ? 1002 : 1047; break;
    287             case TH2_FREQ_1525: pipe_bandwidth = cal_universal ? 940 : 980; break;
    288             case TH2_FREQ_1425: pipe_bandwidth = cal_universal ? 877 : 915; break;
    289             case TH2_FREQ_1325: pipe_bandwidth = cal_universal ? 812 : 847; break;
    290             case TH2_FREQ_1275: pipe_bandwidth = cal_universal ? 782 : 815; break;
    291             case TH2_FREQ_1225: pipe_bandwidth = cal_universal ? 750 : 782; break;
    292             case TH2_FREQ_1125: pipe_bandwidth = cal_universal ? 687 : 717; break;
    293             case TH2_FREQ_1050: pipe_bandwidth = cal_universal ? 640 : 667; break;
    294             case TH2_FREQ_950:  pipe_bandwidth = cal_universal ? 575 : 600; break;
    295             case TH2_FREQ_850:  pipe_bandwidth = cal_universal ? 512 : 535; break;
    296             default: pipe_bandwidth = cal_universal ? 1050 : 1095; break;
    297         }
    298         pipe_bandwidth = pipe_bandwidth * 1000;
    299     }
    300     /* TD3 or TD3 2T or MV2*/
    301     else if (dev_id == BCM56870_DEVICE_ID || dev_id == BCM56873_DEVICE_ID ||
    302              dev_id == BCM56770_DEVICE_ID || dev_id == BCM56771_DEVICE_ID) {
    303         switch (freq) {
    304             case TD3_FREQ_1525: pipe_bandwidth = TD3_BW_1525; break;
    305             case TD3_FREQ_1425: pipe_bandwidth = TD3_BW_1425; break;
    306             case TD3_FREQ_1325: pipe_bandwidth = TD3_BW_1325; break;
    307             case TD3_FREQ_1275: pipe_bandwidth = TD3_BW_1275; break;
    308             case TD3_FREQ_1012: pipe_bandwidth = TD3_BW_1012; break;
    309             case TD3_FREQ_850:  pipe_bandwidth = TD3_BW_850;  break;
    310             default: pipe_bandwidth = TD3_FREQ_850; break;
    311         }
    312     }
    313     /* default */
    314     else {
    315         cli_out("\n*WARNING: Unrecognized DEVICE_ID %d\n", dev_id);
    316         pipe_bandwidth = TH_BW_850;
    317     }
    318 
    319     return pipe_bandwidth;
    320 }
    321 
    322 /*
    323  * Function:
    324  *      stream_get_ancl_bandwidth
    325  * Purpose:
    326  *      Return ancillary bandwidth of the given pipe
    327  * Parameters:
    328  *      unit: StrataSwitch Unit #.
    329  *      flag: reserved for special pipe config, i.e. extra 2nd MGMT port.
    330  *
    331  * Returns:
    332  *    Nothing
    333  */
    334 uint32
    335 stream_get_ancl_bandwidth(int unit, uint32 flag)
    336 {
    337     int ancl_bandwidth;
    338     uint16 dev_id;
    339     uint8 rev_id;
    340 
    341     soc_cm_get_id(unit, &dev_id, &rev_id);
    342     /* TH */
    343     if (dev_id == BCM56960_DEVICE_ID) {
    344         ancl_bandwidth = TH_MISC_BW;
    345     }
    346     /* TD2P */
    347     else if (dev_id == BCM56860_DEVICE_ID || dev_id == BCM56850_DEVICE_ID) {
    348         ancl_bandwidth = TD2P_MISC_BW;
    349     }
    350     /* TH 2 */
    351     else if (dev_id == BCM56970_DEVICE_ID) {
    352         ancl_bandwidth = TH2_MISC_BW;
    353     }
    354     /* TD3 or TD3 2T or MV2*/
    355     else if (dev_id == BCM56870_DEVICE_ID || dev_id == BCM56873_DEVICE_ID ||
    356              dev_id == BCM56770_DEVICE_ID || dev_id == BCM56771_DEVICE_ID) {
    357         ancl_bandwidth = TD3_MISC_BW;
    358     }
    359     /* default */
    360     else {
    361         cli_out("\n*WARNING: Unrecognized DEVICE_ID %d\n", dev_id);
    362         ancl_bandwidth = TH_MISC_BW;
    363     }
    364 
    365     return ancl_bandwidth;
    366 }
    367 
    368 /*
    369  * Function:
    370  *      stream_get_reg_tpkt_tbyt
    371  * Purpose:
    372  *      Get register of TPKTr and TBYTr
    373  * Parameters:
    374  *      unit: StrataSwitch Unit #.
    375  *      reg_tpkt: ptr to register TPKTr
    376  *      reg_tbyt: ptr to register TBYTr
    377  *
    378  * Returns:
    379  *    BCM_E_XXX
    380  */
    381 bcm_error_t
    382 stream_get_reg_tpkt_tbyt(int unit, int port, soc_reg_t* reg_tpkt, soc_reg_t* reg_tbyt)
    383 {
    384     int phy_port;
    385     bcm_error_t rv = BCM_E_NONE;
    386 
    387     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    388     if(phy_port == -1) {
    389         cli_out("\nERROR : stream_get_reg_tpkt_tbyt called with invalid "
    390                       "logical port %0d", port);
    391         return BCM_E_INTERNAL;
    392     }
    393 
    394     /* TH+ and later (TH+, TH2, TD3) */
    395     if (soc_feature(unit, soc_feature_cxl_mib)) {
    396         if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port),
    397                              SOC_BLK_CLPORT)) {
    398             (*reg_tpkt) = CLMIB_TPKTr;
    399             (*reg_tbyt) = CLMIB_TBYTr;
    400         } else if (IS_QSGMII_PORT(unit, port)) {
    401             (*reg_tpkt) = GTPKTr;
    402             (*reg_tbyt) = GTBYTr;
    403         } else {
    404             (*reg_tpkt) = XLMIB_TPKTr;
    405             (*reg_tbyt) = XLMIB_TBYTr;
    406         }
    407     /* TH, TD2P */
    408     } else if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT2PLUS(unit)) {
    409         (*reg_tpkt) = TPKTr;
    410         (*reg_tbyt) = TBYTr;
    411     }
    412     /* unrecognized device */
    413     else {
    414         rv = BCM_E_FAIL;
    415     }
    416 
    417     return rv;
    418 }
    419 
    420 /*
    421  * Function:
    422  *      stream_get_wc_pkt_size
    423  * Purpose:
    424  *      Get worst-case packet size for HiGig packet
    425  * Parameters:
    426  *      unit: StrataSwitch Unit #.
    427  *      hg_en: HiGig enable, 0->false, otherwise->true
    428  *
    429  * Returns:
    430  *      worst-case packet size
    431  */
    432 uint32
    433 stream_get_wc_pkt_size(int unit, int hg_en)
    434 {
    435     if (SOC_IS_TRIDENT3X(unit)) {
    436         return HG2_WC_PKT_SIZE;
    437     }
    438 
    439     if (hg_en == 0) {
    440         return ENET_WC_PKT_SIZE;
    441     } else {
    442         return HG2_WC_PKT_SIZE;
    443     }
    444 }
    445 
    446 /*
    447  * Function:
    448  *      stream_set_vlan
    449  * Purpose:
    450  *      Validates VLAN in VLAN table
    451  * Parameters:
    452  *      unit - StrataSwitch Unit #.
    453  *      vlan - VLAN ID
    454  *      enable - 0->disable, otherwise->enable.
    455  *
    456  * Returns:
    457  *     Nothing
    458  */
    459 void
    460 stream_set_vlan(int unit, bcm_vlan_t vlan, int enable)
    461 {
    462     uint32 value;
    463     vlan_tab_entry_t vlan_tab_entry;
    464     vlan_2_tab_entry_t vlan_2_tab_entry;
    465 
    466     if (SOC_MEM_IS_VALID(unit, VLAN_TABm)) {
    467         value = (enable == 0) ? (0x0) : (0x1);
    468         (void) soc_mem_read(unit, VLAN_TABm, COPYNO_ALL, vlan, vlan_tab_entry.entry_data);
    469         soc_mem_field32_set(unit, VLAN_TABm, vlan_tab_entry.entry_data,
    470                             VALIDf, value);
    471         (void) soc_mem_write(unit, VLAN_TABm, COPYNO_ALL, vlan, vlan_tab_entry.entry_data);
    472         if (SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) {
    473             (void) soc_mem_read(unit, VLAN_2_TABm, COPYNO_ALL, vlan,
    474                                 vlan_2_tab_entry.entry_data);
    475             soc_mem_field32_set(unit, VLAN_2_TABm, vlan_2_tab_entry.entry_data,
    476                                 VALIDf, value);
    477             (void) soc_mem_write(unit, VLAN_2_TABm, COPYNO_ALL, vlan,
    478                                  vlan_2_tab_entry.entry_data);
    479         }
    480     } else {
    481         cli_out("\n*ERROR, invalid mem VLAN_TABm\n");
    482     }
    483 }
    484 
    485 /*
    486  * Function:
    487  *      stream_set_vlan_valid
    488  * Purpose:
    489  *      Validates VLAN in VLAN table
    490  * Parameters:
    491  *      unit - StrataSwitch Unit #.
    492  *      vlan - VLAN ID
    493  *
    494  * Returns:
    495  *     Nothing
    496  */
    497 void
    498 stream_set_vlan_valid(int unit, bcm_vlan_t vlan)
    499 {
    500     stream_set_vlan(unit, vlan, 1);
    501 }
    502 
    503 /*
    504  * Function:
    505  *      stream_set_vlan_invalid
    506  * Purpose:
    507  *      InValidates VLAN in VLAN table
    508  * Parameters:
    509  *      unit - StrataSwitch Unit #.
    510  *      vlan - VLAN ID
    511  *
    512  * Returns:
    513  *     Nothing
    514  */
    515 void
    516 stream_set_vlan_invalid(int unit, bcm_vlan_t vlan)
    517 {
    518     stream_set_vlan(unit, vlan, 0);
    519 }
    520 
    521 /*
    522  * Function:
    523  *      stream_set_l3mtu
    524  * Purpose:
    525  *      set L3_MTU_VALUES
    526  * Parameters:
    527  *      unit - StrataSwitch Unit #.
    528  *      vlan - VLAN ID
    529  *      mtu_value - MTU value
    530  *
    531  * Returns:
    532  *     Nothing
    533  */
    534 static bcm_error_t
    535 stream_set_l3mtu(int unit, bcm_vlan_t vlan, uint32 mtu_value)
    536 {
    537     bcm_error_t rv = BCM_E_NONE;
    538     mtu_values_entry_t l3_mtu_values_entry;
    539 
    540     /*cli_out("Setting MTU to %0d for vlan/oif 0x%0x\n", mtu_value, vlan);*/
    541     SOC_IF_ERROR_RETURN(READ_L3_MTU_VALUESm(
    542                         unit, MEM_BLOCK_ANY, vlan, &l3_mtu_values_entry));
    543     soc_L3_MTU_VALUESm_field32_set(
    544                         unit, &l3_mtu_values_entry, MTU_SIZEf, mtu_value);
    545     SOC_IF_ERROR_RETURN(WRITE_L3_MTU_VALUESm(
    546                         unit, MEM_BLOCK_ALL, vlan, &l3_mtu_values_entry));
    547 
    548     return rv;
    549 }
    550 
    551 /*
    552  * Function:
    553  *      stream_set_l3mtu_valid
    554  * Purpose:
    555  *      set L3_MTU_VALUES to a valid value (max value)
    556  * Parameters:
    557  *      unit - StrataSwitch Unit #.
    558  *      vlan - VLAN ID
    559  *
    560  * Returns:
    561  *     Nothing
    562  */
    563 void
    564 stream_set_l3mtu_valid(int unit, bcm_vlan_t vlan)
    565 {
    566     (void) stream_set_l3mtu(unit, vlan, MTU);
    567 }
    568 
    569 /*
    570  * Function:
    571  *      stream_set_l3mtu_invalid
    572  * Purpose:
    573  *      set L3_MTU_VALUES to an invalid value (min_pkt_size-1)
    574  * Parameters:
    575  *      unit - StrataSwitch Unit #.
    576  *      vlan - VLAN ID
    577  *
    578  * Returns:
    579  *     Nothing
    580  */
    581 static void
    582 stream_set_l3mtu_invalid(int unit, bcm_vlan_t vlan)
    583 {
    584     (void) stream_set_l3mtu(unit, vlan, 63);
    585 }
    586 
    587 /*
    588  * Function:
    589  *      stream_set_lpbk
    590  * Purpose:
    591  *      Enable and disable MAC/PHY loopback on all ports specified by pbmp.
    592  * Parameters:
    593  *      unit: StrataSwitch Unit #.
    594  *      pbmp: port bitmap
    595  *      loopback: loopback mode
    596  *
    597  * Returns:
    598  *     SOC_E_XXXX
    599  */
    600 STATIC int _last_lpbk = BCM_PORT_LOOPBACK_NONE;
    601 bcm_error_t
    602 stream_set_lpbk(int unit, pbmp_t pbmp, int loopback)
    603 {
    604     int port, lp_invalid = 0;
    605 
    606     _last_lpbk = loopback;
    607 
    608     if (loopback == BCM_PORT_LOOPBACK_MAC) {
    609         cli_out("\nEnabling MAC loopback");
    610     } else if (loopback == BCM_PORT_LOOPBACK_PHY) {
    611         cli_out("\nEnabling PCS local loopback");
    612     } else if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) {
    613         cli_out("\nEnabling PMD loopback");
    614     } else if (loopback == BCM_PORT_LOOPBACK_NONE) {
    615         cli_out("\nDisabling loopback");
    616     } else {
    617         lp_invalid = 1;
    618         loopback = BCM_PORT_LOOPBACK_NONE;
    619         cli_out("\nInvalid loopback mode");
    620     }
    621 
    622     if (lp_invalid == 0) {
    623         PBMP_ITER(pbmp, port) {
    624             if (port < SOC_MAX_NUM_PORTS) {
    625                 if (loopback == BCM_PORT_LOOPBACK_NONE) {
    626                      if (_last_lpbk == BCM_PORT_LOOPBACK_PHY_REMOTE) {
    627                         BCM_IF_ERROR_RETURN(stream_set_pmd_lpbk(unit, port,
    628                                     BCM_PORT_PHY_CONTROL_LOOPBACK_PMD, 0));
    629                      } else {
    630                         BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port,
    631                                     loopback));
    632                     }
    633                 } else if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) {
    634                     BCM_IF_ERROR_RETURN(stream_set_pmd_lpbk(unit, port,
    635                                     BCM_PORT_PHY_CONTROL_LOOPBACK_PMD, 1));
    636                 } else {
    637                     BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port,
    638                                     loopback));
    639                 }
    640             }
    641         }
    642     }
    643 
    644     return BCM_E_NONE;
    645 }
    646 
    647 /*
    648  * Function:
    649  *      stream_set_pmd_lpbk
    650  * Purpose:
    651  *      Enable PMD local loopback on a port.
    652  * Parameters:
    653  *      unit: StrataSwitch Unit #.
    654  *      port: Device port number.
    655  *      type: PHY control type.
    656  *      value: PHY control value.
    657  *
    658  * Returns:
    659  *     SOC_E_XXXX
    660  */
    661 bcm_error_t
    662 stream_set_pmd_lpbk( int unit, bcm_port_t port, bcm_port_phy_control_t type, uint32 value)
    663 {
    664     BCM_IF_ERROR_RETURN(bcm_port_phy_control_set(unit, port, type, value));
    665     BCM_IF_ERROR_RETURN(bcm_port_enable_set(unit, port, 1));
    666     return BCM_E_NONE;
    667 }
    668 
    669 /*
    670  * Function:
    671  *      stream_set_mac_lpbk
    672  * Purpose:
    673  *      Enable MAC loopback on all ports specified by pbmp.
    674  * Parameters:
    675  *      unit: StrataSwitch Unit #.
    676  *      pbmp: port bitmap
    677  *
    678  * Returns:
    679  *     Nothing
    680  */
    681 void
    682 stream_set_mac_lpbk(int unit, pbmp_t pbmp)
    683 {
    684     stream_set_lpbk(unit, pbmp, BCM_PORT_LOOPBACK_MAC);
    685 }
    686 
    687 /*
    688  * Function:
    689  *      stream_set_phy_lpbk
    690  * Purpose:
    691  *      Enable PHY loopback on all ports specified by pbmp.
    692  * Parameters:
    693  *      unit: StrataSwitch Unit #.
    694  *      pbmp: port bitmap
    695  *
    696  * Returns:
    697  *     Nothing
    698  */
    699 void
    700 stream_set_phy_lpbk(int unit, pbmp_t pbmp)
    701 {
    702     stream_set_lpbk(unit, pbmp, BCM_PORT_LOOPBACK_PHY);
    703 }
    704 
    705 /*
    706  * Function:
    707  *      stream_set_no_lpbk
    708  * Purpose:
    709  *      Clear loopback on all ports specified by pbmp.
    710  * Parameters:
    711  *      unit: StrataSwitch Unit #.
    712  *      pbmp: port bitmap
    713  *
    714  * Returns:
    715  *     Nothing
    716  */
    717 void
    718 stream_set_no_lpbk(int unit, pbmp_t pbmp)
    719 {
    720     stream_set_lpbk(unit, pbmp, BCM_PORT_LOOPBACK_NONE);
    721 }
    722 
    723 /*
    724  * Function:
    725  *      stream_turn_off_cmic_mmu_bkp
    726  * Purpose:
    727  *      Turn off CMIC to MMU backpressure on all channels
    728  * Parameters:
    729  *      unit: StrataSwitch Unit #.
    730  *
    731  * Returns:
    732  *     Nothing
    733  */
    734 void
    735 stream_turn_off_cmic_mmu_bkp(int unit)
    736 {
    737     int cmc, ch;
    738     int vchan;
    739     uint32 threshold = CMICM_MMU_BKP_OFF_THRESHOLD;
    740 
    741     if (soc_feature(unit, soc_feature_cmicm) ||
    742         soc_feature(unit, soc_feature_cmicd_v2) ||
    743         soc_feature(unit, soc_feature_cmicd_v3)) {
    744         threshold = CMICM_MMU_BKP_OFF_THRESHOLD;
    745     } else if (soc_feature(unit, soc_feature_cmicx)) {
    746         threshold = CMICX_MMU_BKP_OFF_THRESHOLD;
    747     }
    748 
    749     for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
    750         for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) {
    751             vchan = cmc * DMA_CHAN_PER_CMC(unit) + ch;
    752             soc_dma_chan_rxbuf_threshold_cfg(unit, vchan, threshold);
    753         }
    754     }
    755 
    756     if (soc_feature(unit, soc_feature_cmicx)) {
    757         for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
    758             soc_dma_cmc_rxbuf_threshold_cfg(unit, cmc, threshold);
    759         }
    760     }
    761 }
    762 
    763 /*
    764  * Function:
    765  *      stream_turn_off_idb_fc
    766  * Purpose:
    767  *      Turn off IDB flow control.
    768  * Parameters:
    769  *      unit: StrataSwitch Unit #.
    770  *      idb_fcc_regs - ptr to idb flow control registers.
    771  *      a_size - number of registers in the input ptr.
    772  *
    773  * Returns:
    774  *     Nothing
    775  */
    776 static void
    777 stream_turn_off_idb_fc(int unit, soc_reg_t *idb_fcc_regs, int obm_per_pipe)
    778 {
    779     int obm_subp;
    780     int pipe, obm, idx;
    781     uint64 idb_fc;
    782     soc_field_t idb_flow_control_config_fields[] = {
    783         PORT_FC_ENf,
    784         LOSSLESS1_FC_ENf,
    785         LOSSLESS0_FC_ENf,
    786         LOSSLESS1_PRIORITY_PROFILEf,
    787         LOSSLESS0_PRIORITY_PROFILEf
    788     };
    789     uint32 idb_flow_control_config_values[] = {0x0, 0x0, 0x0, 0xff, 0xff};
    790 
    791     cli_out("\nTurning off flow control at IDB/MMU");
    792 
    793     COMPILER_64_SET(idb_fc, 0x0, 0x0);
    794 
    795     if (SOC_REG_IS_VALID(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r)) {
    796         soc_reg_fields32_modify(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
    797                                 REG_PORT_ANY, 5, idb_flow_control_config_fields,
    798                                 idb_flow_control_config_values);
    799         (void) soc_reg_get(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 0, 0,
    800                            &idb_fc);
    801     }
    802 
    803     for(pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    804         for(obm = 0; obm < obm_per_pipe; obm++) {
    805             idx = (pipe * obm_per_pipe) + obm;
    806             if(SOC_REG_IS_VALID(unit, idb_fcc_regs[idx])) {
    807                 for (obm_subp = 0; obm_subp < NUM_SUBP_OBM; obm_subp++) {
    808                     (void) soc_reg_set(unit, idb_fcc_regs[idx], 0, obm_subp, idb_fc);
    809                 }
    810             }
    811         }
    812     }
    813 }
    814 
    815 /*
    816  * Function:
    817  *      stream_turn_off_fc
    818  * Purpose:
    819  *      Turn off flow control at the MAC, IDB and MMU.
    820  * Parameters:
    821  *      unit: StrataSwitch Unit #.
    822  *      pbmp - Device port bitmap
    823  *
    824  * Returns:
    825  *     Nothing
    826  */
    827 void
    828 stream_turn_off_fc(int unit, pbmp_t pbmp)
    829 {
    830     int port, idx, obm_per_pipe;
    831 
    832     soc_reg_t idb_fcc_regs[] = {
    833         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
    834         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r,
    835         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r,
    836         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r,
    837         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r,
    838         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r,
    839         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r,
    840         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r,
    841         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r,
    842         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r,
    843         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r,
    844         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r,
    845         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r,
    846         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r,
    847         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r,
    848         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r,
    849         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r,
    850         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r,
    851         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r,
    852         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r,
    853         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE1r,
    854         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE1r,
    855         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE1r,
    856         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE1r,
    857         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE1r,
    858         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE1r,
    859         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE1r,
    860         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE1r,
    861         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE1r,
    862         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE1r,
    863         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE1r,
    864         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE1r,
    865         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r,
    866         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r,
    867         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r,
    868         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r,
    869         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE2r,
    870         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE2r,
    871         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE2r,
    872         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE2r,
    873         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE2r,
    874         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE2r,
    875         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE2r,
    876         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE2r,
    877         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE2r,
    878         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE2r,
    879         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE2r,
    880         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE2r,
    881         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r,
    882         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r,
    883         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r,
    884         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r,
    885         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE3r,
    886         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE3r,
    887         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE3r,
    888         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE3r,
    889         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE3r,
    890         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE3r,
    891         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE3r,
    892         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE3r,
    893         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE3r,
    894         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE3r,
    895         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE3r,
    896         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE3r
    897     };
    898 
    899     soc_reg_t pgw_fcc_regs[] = {
    900         PGW_OBM_PORT0_FC_CONFIGr,
    901         PGW_OBM_PORT1_FC_CONFIGr,
    902         PGW_OBM_PORT2_FC_CONFIGr,
    903         PGW_OBM_PORT3_FC_CONFIGr,
    904         PGW_OBM_PORT4_FC_CONFIGr,
    905         PGW_OBM_PORT5_FC_CONFIGr,
    906         PGW_OBM_PORT6_FC_CONFIGr,
    907         PGW_OBM_PORT7_FC_CONFIGr,
    908         PGW_OBM_PORT8_FC_CONFIGr,
    909         PGW_OBM_PORT9_FC_CONFIGr,
    910         PGW_OBM_PORT10_FC_CONFIGr,
    911         PGW_OBM_PORT11_FC_CONFIGr,
    912         PGW_OBM_PORT12_FC_CONFIGr,
    913         PGW_OBM_PORT13_FC_CONFIGr,
    914         PGW_OBM_PORT14_FC_CONFIGr,
    915         PGW_OBM_PORT15_FC_CONFIGr
    916     };
    917 
    918     soc_reg_t idb_mv2_fcc_regs[] = {
    919         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
    920         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r,
    921         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r,
    922         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r,
    923         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r,
    924         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r,
    925         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r,
    926         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r,
    927         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r,
    928         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r,
    929         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r,
    930         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r,
    931         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r,
    932         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r,
    933         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r,
    934         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r,
    935         IDB_OBM16_FLOW_CONTROL_CONFIG_PIPE0r,
    936         IDB_OBM17_FLOW_CONTROL_CONFIG_PIPE0r,
    937         IDB_OBM18_FLOW_CONTROL_CONFIG_PIPE0r,
    938         IDB_OBM19_FLOW_CONTROL_CONFIG_PIPE0r
    939     };
    940 
    941     if (SOC_REG_IS_VALID(unit, THDI_INPUT_PORT_XON_ENABLESr)) {
    942         PBMP_ITER(pbmp, port) {
    943             if (port < SOC_MAX_NUM_PORTS) {
    944                 bcm_port_pause_set(unit, port, FALSE, FALSE);
    945                 soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr,
    946                                        port, PORT_PAUSE_ENABLEf, 0x0);
    947             }
    948         }
    949         soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr,
    950                                0, PORT_PAUSE_ENABLEf, 0x0);
    951     }
    952 
    953     if(SOC_IS_TOMAHAWK(unit)) { /*TH, TH+*/
    954         obm_per_pipe = 8;
    955     } else if (SOC_IS_MAVERICK2(unit)) {
    956         obm_per_pipe = 20;
    957     }
    958     else { /* All other devices are using 16 obm per pipe */
    959         obm_per_pipe = 16;
    960     }
    961     if (SOC_IS_MAVERICK2(unit)) stream_turn_off_idb_fc(unit, idb_mv2_fcc_regs, obm_per_pipe);
    962     else stream_turn_off_idb_fc(unit, idb_fcc_regs, obm_per_pipe);
    963     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2PLUS(unit)) {
    964         for (idx = 0; idx < (sizeof(pgw_fcc_regs) / sizeof(soc_reg_t)); idx++) {
    965             if (SOC_REG_IS_VALID(unit, pgw_fcc_regs[idx])) {
    966                 soc_reg_field32_modify(unit, pgw_fcc_regs[idx], REG_PORT_ANY,
    967                                        PORT_FC_ENABLEf, 0x0);
    968             }
    969         }
    970     }
    971 }
    972 
    973 /*
    974  * Function:
    975  *      stream_gen_random_l2_pkt
    976  * Purpose:
    977  *      Generate random L2 packet with seq ID
    978  * Parameters:
    979  *      pkt_ptr - ptr to packet.
    980  *      pkt_size - Packet size in bytes
    981  *      mac_da - Destination MAC Address
    982  *      mac_sa - Source MAC Address
    983  *      tpid - TPID
    984  *      vlan_id - VLAN
    985  *      seq_id - Sequence ID
    986  *
    987  * Returns:
    988  *     Nothing
    989  */
    990 void
    991 stream_gen_random_l2_pkt(uint8 *pkt_ptr, uint32 pkt_size, uint32 seq_id,
    992                          uint8 mac_da[NUM_BYTES_MAC_ADDR],
    993                          uint8 mac_sa[NUM_BYTES_MAC_ADDR],
    994                          uint16 tpid, uint16 vlan_id)
    995 {
    996     int i, offset;
    997     uint32 crc;
    998 
    999     tgp_gen_random_l2_pkt(pkt_ptr, pkt_size, mac_da, mac_sa, tpid, vlan_id);
   1000 
   1001     /* Replace First 4 Payload Bytes with Sequence ID */
   1002     offset = NUM_BYTES_L2_HDR;
   1003     pkt_ptr[offset + 0] = (seq_id >> (3 * 8)) & 0xff;
   1004     pkt_ptr[offset + 1] = (seq_id >> (2 * 8)) & 0xff;
   1005     pkt_ptr[offset + 2] = (seq_id >> (1 * 8)) & 0xff;
   1006     pkt_ptr[offset + 3] = (seq_id >> (0 * 8)) & 0xff;
   1007 
   1008     /* Replace Next 2 Payload Bytes with Packet Size */
   1009     pkt_ptr[offset + 4] = (pkt_size >> 8) & 0xff;
   1010     pkt_ptr[offset + 5] = (pkt_size) & 0xff;
   1011 
   1012     /* Recalculate CRC */
   1013     tgp_populate_crc_table();
   1014     crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size);
   1015 
   1016     offset = pkt_size - NUM_BYTES_CRC;
   1017     for (i = NUM_BYTES_CRC; i > 0 ; i--) {
   1018         pkt_ptr[offset++] = (crc >> ((i - 1) * 8)) & 0xff;
   1019     }
   1020 }
   1021 
   1022 /*
   1023  * Function:
   1024  *      stream_gen_random_l3_pkt
   1025  * Purpose:
   1026  *      Generate random L3 packet with seq ID
   1027  * Parameters:
   1028  *
   1029  * Returns:
   1030  *     Nothing
   1031  */
   1032 void
   1033 stream_gen_random_l3_pkt(uint8 *pkt_ptr, uint8 ipv6_en,
   1034                          uint32 pkt_size, uint32 seq_id,
   1035                          uint8 mac_da[NUM_BYTES_MAC_ADDR],
   1036                          uint8 mac_sa[NUM_BYTES_MAC_ADDR],
   1037                          uint16 vlan_id, uint32 ip_da, uint32 ip_sa,
   1038                          uint8 ttl, uint8 tos)
   1039 {
   1040     int i, offset;
   1041     uint32 crc;
   1042 
   1043     tgp_gen_random_ip_pkt(ipv6_en, pkt_ptr, pkt_size, mac_da, mac_sa,
   1044                           vlan_id, ip_da, ip_sa, ttl, tos);
   1045 
   1046     /* Replace First 4 Payload Bytes with Sequence ID */
   1047     if (ipv6_en == 1) {
   1048         offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV6_HDR;
   1049     } else {
   1050         offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV4_HDR;
   1051     }
   1052     pkt_ptr[offset + 0] = (seq_id >> (3 * 8)) & 0xff;
   1053     pkt_ptr[offset + 1] = (seq_id >> (2 * 8)) & 0xff;
   1054     pkt_ptr[offset + 2] = (seq_id >> (1 * 8)) & 0xff;
   1055     pkt_ptr[offset + 3] = (seq_id >> (0 * 8)) & 0xff;
   1056 
   1057     /* Replace Next 2 Payload Bytes with Packet Size */
   1058     pkt_ptr[offset + 4] = (pkt_size >> 8) & 0xff;
   1059     pkt_ptr[offset + 5] = (pkt_size) & 0xff;
   1060 
   1061     /* Recalculate CRC */
   1062     tgp_populate_crc_table();
   1063     crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size);
   1064 
   1065     offset = pkt_size - NUM_BYTES_CRC;
   1066     for (i = NUM_BYTES_CRC; i > 0 ; i--) {
   1067         pkt_ptr[offset++] = (crc >> ((i - 1) * 8)) & 0xff;
   1068     }
   1069 }
   1070 
   1071 /*
   1072  * Function:
   1073  *      stream_gen_random_mpls_l3_pkt
   1074  * Purpose:
   1075  *      Generate random L3 packet with seq ID
   1076  * Parameters:
   1077  *
   1078  * Returns:
   1079  *     Nothing
   1080  */
   1081 void
   1082 stream_gen_random_mpls_l3_pkt(
   1083     uint8 *pkt_ptr,
   1084     stream_pkt_t *tx_pkt,
   1085     uint32 pkt_size,
   1086     uint32 seq_id,
   1087     uint8 tos)
   1088 {
   1089     int i, offset;
   1090     uint32 crc;
   1091     int l2_hdr_size, mpls_hdr_size, ip_hdr_size;
   1092 
   1093     tgp_gen_random_mpls_ip_pkt(
   1094         pkt_ptr,
   1095         pkt_size,
   1096         tx_pkt->mac_da,
   1097         tx_pkt->mac_sa,
   1098         tx_pkt->tx_vlan,
   1099         tx_pkt->l3_en,
   1100         tx_pkt->l3_mpls_en,
   1101         tx_pkt->mpls_labels,
   1102         tx_pkt->ipv6_en,
   1103         tx_pkt->ipv6_da,
   1104         tx_pkt->ipv6_sa,
   1105         tx_pkt->ttl,
   1106         tos);
   1107 
   1108     l2_hdr_size = NUM_BYTES_L2_HDR;
   1109     mpls_hdr_size = (tx_pkt->l3_mpls_en == 1) ? (3 * NUM_BYTES_MPLS_HDR) : 0;
   1110     ip_hdr_size = (tx_pkt->l3_en == 1) ?
   1111                       ((tx_pkt->ipv6_en == 1) ? NUM_BYTES_IPV6_HDR :
   1112                                                 NUM_BYTES_IPV4_HDR) : 0;
   1113     offset = l2_hdr_size + mpls_hdr_size + ip_hdr_size;
   1114 
   1115     pkt_ptr[offset + 0] = (seq_id >> (3 * 8)) & 0xff;
   1116     pkt_ptr[offset + 1] = (seq_id >> (2 * 8)) & 0xff;
   1117     pkt_ptr[offset + 2] = (seq_id >> (1 * 8)) & 0xff;
   1118     pkt_ptr[offset + 3] = (seq_id >> (0 * 8)) & 0xff;
   1119 
   1120     /* Replace Next 2 Payload Bytes with Packet Size */
   1121     pkt_ptr[offset + 4] = (pkt_size >> 8) & 0xff;
   1122     pkt_ptr[offset + 5] = (pkt_size) & 0xff;
   1123 
   1124     pkt_ptr[offset + 6] = (tx_pkt->port) & 0xff;
   1125 
   1126     /* Recalculate CRC */
   1127     tgp_populate_crc_table();
   1128     crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size);
   1129 
   1130     offset = pkt_size - NUM_BYTES_CRC;
   1131     for (i = NUM_BYTES_CRC; i > 0 ; i--) {
   1132         pkt_ptr[offset++] = (crc >> ((i - 1) * 8)) & 0xff;
   1133     }
   1134 }
   1135 
   1136 /*
   1137  * Function:
   1138  *      stream_gen_ref_l2_pkt
   1139  * Purpose:
   1140  *      Generate reference L2 packet by retrieving pkt_size and seq_id
   1141  *      from the given rx packet.
   1142  * Parameters:
   1143  *      unit - StrataSwitch Unit #.
   1144  *      port - device port number
   1145  *      pkt_intg - ptr to packet integrity struct, containing all necessary
   1146  *                 parameters needed for integrity check.
   1147  *      rx_pkt - ptr to rx packet.
   1148  *      ref_pkt - ptr to reference packet.
   1149  *      ref_pkt_size - packet size of reference packet
   1150  *
   1151  * Returns:
   1152  *     Nothing
   1153  */
   1154 static void
   1155 stream_gen_ref_l2_pkt(int unit, int port, stream_integrity_t *pkt_intg,
   1156                       uint8 *rx_pkt, uint8 *ref_pkt, uint32 *ref_pkt_size)
   1157 {
   1158     uint32 offset, seq_id, pkt_size;
   1159     uint32 header_size = 0;
   1160 
   1161     soc_dma_header_size_get(unit, &header_size);
   1162     seq_id   = 0x00000000;
   1163     pkt_size = 0x00000000;
   1164     offset   = NUM_BYTES_L2_HDR + header_size;
   1165 
   1166     seq_id   |= (rx_pkt[offset] << 24);
   1167     seq_id   |= (rx_pkt[offset + 1] << 16);
   1168     seq_id   |= (rx_pkt[offset + 2] << 8);
   1169     seq_id   |= (rx_pkt[offset + 3]);
   1170     pkt_size |= (rx_pkt[offset + 4] << 8);
   1171     pkt_size |= (rx_pkt[offset + 5]);
   1172 
   1173     sal_srand(pkt_intg->port_pkt_seed[port] + seq_id);
   1174     stream_gen_random_l2_pkt(ref_pkt, pkt_size, seq_id,
   1175                              pkt_intg->mac_da[port],
   1176                              pkt_intg->mac_sa[port],
   1177                              TPID, pkt_intg->tx_vlan[port]);
   1178 
   1179     (*ref_pkt_size) = pkt_size;
   1180 }
   1181 
   1182 /*
   1183  * Function:
   1184  *      stream_gen_ref_l3_pkt
   1185  * Purpose:
   1186  *      Generate reference L3 packet by retrieving pkt_size and seq_id
   1187  *      from the given rx packet.
   1188  * Parameters:
   1189  *      unit - StrataSwitch Unit #.
   1190  *      port - device port number
   1191  *      pkt_intg - ptr to packet integrity struct, containing all necessary
   1192  *                 parameters needed for integrity check.
   1193  *      rx_pkt - ptr to rx packet.
   1194  *      ref_pkt - ptr to reference packet.
   1195  *      ref_pkt_size - packet size of reference packet
   1196  *
   1197  * Returns:
   1198  *     Nothing
   1199  */
   1200 static void
   1201 stream_gen_ref_l3_pkt(int unit, int port, stream_integrity_t *pkt_intg,
   1202                       uint8 *rx_pkt, uint8 *ref_pkt, uint32 *ref_pkt_size)
   1203 {
   1204     uint32 offset, seq_id, pkt_size;
   1205     uint8 ttl, tos = 0;
   1206     uint32 header_size = 0;
   1207 
   1208     soc_dma_header_size_get(unit, &header_size);
   1209     seq_id   = 0x00000000;
   1210     pkt_size = 0x00000000;
   1211     if (pkt_intg->ipv6_en == 1) {
   1212         offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV6_HDR;
   1213     } else {
   1214         offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV4_HDR;
   1215     }
   1216     offset += header_size;
   1217 
   1218     seq_id   |= (rx_pkt[offset] << 24);
   1219     seq_id   |= (rx_pkt[offset + 1] << 16);
   1220     seq_id   |= (rx_pkt[offset + 2] << 8);
   1221     seq_id   |= (rx_pkt[offset + 3]);
   1222     pkt_size |= (rx_pkt[offset + 4] << 8);
   1223     pkt_size |= (rx_pkt[offset + 5]);
   1224 
   1225     if (pkt_intg->ipv6_en == 1) {
   1226         offset = NUM_BYTES_L2_HDR + 7; /* Byte 25 */
   1227     } else {
   1228         offset = NUM_BYTES_L2_HDR + 1; /* Byte 19 */
   1229         tos = rx_pkt[offset + header_size];
   1230         offset = NUM_BYTES_L2_HDR + 8; /* Byte 26 */
   1231     }
   1232     offset += header_size;
   1233     ttl = rx_pkt[offset];
   1234 
   1235     sal_srand(pkt_intg->port_pkt_seed[port] + seq_id);
   1236     stream_gen_random_l3_pkt(ref_pkt, pkt_intg->ipv6_en,
   1237                              pkt_size, seq_id,
   1238                              pkt_intg->mac_da[port],
   1239                              pkt_intg->mac_sa[port],
   1240                              pkt_intg->tx_vlan[port],
   1241                              pkt_intg->ip_da[port],
   1242                              pkt_intg->ip_sa[port],
   1243                              ttl, tos);
   1244 
   1245     (*ref_pkt_size) = pkt_size;
   1246 }
   1247 
   1248 /*
   1249  * Function:
   1250  *      stream_gen_ref_pkt
   1251  * Purpose:
   1252  *      Generate reference packet by retrieving pkt_size and seq_id
   1253  *      from the given rx packet.
   1254  * Parameters:
   1255  *      pkt_intg - ptr to packet integrity struct, containing all necessary
   1256  *                 parameters needed for integrity check.
   1257  *      rx_pkt - ptr to rx packet.
   1258  *      ref_pkt - ptr to reference packet.
   1259  *      pkt_size - packet size of reference packet
   1260  *
   1261  * Returns:
   1262  *     SOC_E_XXXX
   1263  */
   1264 bcm_error_t
   1265 stream_gen_ref_pkt(int unit, int port, stream_integrity_t *pkt_intg,
   1266                    uint8 *rx_pkt, uint8 *ref_pkt, uint32 *pkt_size)
   1267 {
   1268     bcm_error_t rv = BCM_E_NONE;
   1269 
   1270     if (pkt_intg->type == PKT_TYPE_L2 ||
   1271         pkt_intg->type == PKT_TYPE_L2_TS) {
   1272         stream_gen_ref_l2_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt, pkt_size);
   1273     } else if (pkt_intg->type == PKT_TYPE_IPMC ||
   1274                pkt_intg->type == PKT_TYPE_L3UC) {
   1275         stream_gen_ref_l3_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt, pkt_size);
   1276     } else {
   1277         rv = BCM_E_FAIL;
   1278     }
   1279 
   1280     return rv;
   1281 }
   1282 
   1283 /*
   1284  * Function:
   1285  *      stream_pktdma_tx
   1286  * Purpose:
   1287  *      Transmit one packet from CPU
   1288  * Parameters:
   1289  *      unit - StrataSwitch Unit #.
   1290  *      dv - ptr to tx dma descriptor vector
   1291  *      pkt - ptr to store tx packet
   1292  *      cnt - number of bytes for tx packet
   1293  *
   1294  * Returns:
   1295  *     SOC_E_XXXX
   1296  */
   1297 bcm_error_t
   1298 stream_pktdma_tx(int unit, dv_t *dv, uint8 *pkt, uint16 cnt)
   1299 {
   1300     bcm_error_t rv = BCM_E_NONE;
   1301     int channel_done = 0;
   1302     uint32 timeout = TXDMA_TIMEOUT;
   1303     uint32 flags = 0;
   1304     pbmp_t lp_pbmp;
   1305     pbmp_t empty_pbmp0;
   1306     pbmp_t empty_pbmp1;
   1307 
   1308     SOC_PBMP_CLEAR(lp_pbmp);
   1309     SOC_PBMP_PORT_ADD(lp_pbmp, 1);
   1310     SOC_PBMP_CLEAR(empty_pbmp0);
   1311     SOC_PBMP_CLEAR(empty_pbmp1);
   1312 
   1313     soc_dma_abort_dv(unit, dv);
   1314     soc_dma_dv_reset(DV_TX, dv);
   1315     soc_dma_desc_add(dv, (sal_vaddr_t) (pkt), cnt,
   1316                      lp_pbmp, empty_pbmp0, empty_pbmp1, flags, NULL);
   1317     soc_dma_desc_end_packet(dv);
   1318     SOC_IF_ERROR_RETURN(
   1319         soc_dma_chan_config(unit, TX_CHAN, DV_TX, SOC_DMA_F_POLL));
   1320     soc_dma_start(unit, TX_CHAN, dv);
   1321 
   1322     while (channel_done == 0 && (timeout--) > 0) {
   1323         soc_dma_chan_poll_done(unit, TX_CHAN, SOC_DMA_POLL_CHAIN_DONE,
   1324                                &channel_done);
   1325     }
   1326     if (channel_done == 0) {
   1327         rv = BCM_E_FAIL;
   1328     }
   1329     soc_dma_done_desc(unit, TX_CHAN);
   1330 
   1331     return rv;
   1332 }
   1333 
   1334 /*
   1335  * Function:
   1336  *      stream_pktdma_rx
   1337  * Purpose:
   1338  *      Receive packet by CPU from given vlan
   1339  * Parameters:
   1340  *      unit - StrataSwitch Unit #.
   1341  *      rst_vlan - reset vlan
   1342  *                     0 -> no reset
   1343  *                     1 -> invalid vlan for L2 packet
   1344  *                     2 -> invalid vlan for L3 packet
   1345  *      vlan - vlan ID
   1346  *      dv - ptr to rx dma descriptor
   1347  *      pkt - ptr to store rx packet
   1348  *      cnt - number of bytes of rx packet
   1349  *
   1350  * Returns:
   1351  *     SOC_E_XXXX
   1352  */
   1353 bcm_error_t
   1354 stream_pktdma_rx(int unit, int rst_vlan, bcm_vlan_t vlan,
   1355                  dv_t *dv, uint8 *pkt, uint16 cnt)
   1356 {
   1357     bcm_error_t rv = BCM_E_NONE;
   1358     int k;
   1359     int channel_done = 0;
   1360     uint32 timeout = RXDMA_TIMEOUT;
   1361     uint32 flags = 0;
   1362     pbmp_t lp_pbmp;
   1363     pbmp_t empty_pbmp0;
   1364     pbmp_t empty_pbmp1;
   1365 
   1366     SOC_PBMP_CLEAR(lp_pbmp);
   1367     SOC_PBMP_PORT_ADD(lp_pbmp, 1);
   1368     SOC_PBMP_CLEAR(empty_pbmp0);
   1369     SOC_PBMP_CLEAR(empty_pbmp1);
   1370 
   1371     cnt = (cnt <= MTU) ? (cnt) : (MTU);
   1372     for (k = 0; k < cnt; k++) {
   1373         pkt[k] = 0x00;
   1374     }
   1375 
   1376     /* set up dma to receive packet */
   1377     channel_done = 0;
   1378     soc_dma_abort_dv(unit, dv);
   1379     soc_dma_dv_reset(DV_RX, dv);
   1380     soc_dma_desc_add(dv, (sal_vaddr_t) (pkt), cnt,
   1381                      lp_pbmp, empty_pbmp0, empty_pbmp1, flags, NULL);
   1382     soc_dma_desc_end_packet(dv);
   1383     SOC_IF_ERROR_RETURN(
   1384         soc_dma_chan_config(unit, RX_CHAN, DV_RX, SOC_DMA_F_POLL));
   1385     soc_dma_start(unit, RX_CHAN, dv);
   1386 
   1387     /* forward packet to CPU by making packet size invalid */
   1388     if (rst_vlan != 0) {
   1389         if (rst_vlan == 1) {
   1390             stream_set_vlan_invalid(unit, vlan);
   1391         } else if (rst_vlan == 2) {
   1392             stream_set_l3mtu_invalid(unit, vlan);
   1393         }
   1394     }
   1395 
   1396     /* wait until packet received or timeout */
   1397     while (channel_done == 0 && (timeout--) > 0) {
   1398         soc_dma_chan_poll_done(unit, RX_CHAN, SOC_DMA_POLL_CHAIN_DONE,
   1399                                &channel_done);
   1400     }
   1401     if (channel_done == 0) {
   1402         rv = BCM_E_FAIL;
   1403     }
   1404 
   1405     /* valid vlan to disable forwarding packet to CPU */
   1406     /* stream_set_vlan_valid(unit, vlan); */
   1407 
   1408     return rv;
   1409 }
   1410 
   1411 /*
   1412  * Function:
   1413  *      stream_tx_pkt
   1414  * Purpose:
   1415  *      Transmit packet from CPU through pkt_dma
   1416  * Parameters:
   1417  *      unit - StrataSwitch Unit #.
   1418  *      dv - ptr to tx dma descriptor vector
   1419  *      pkt - ptr to store tx packet
   1420  *      cnt - number of bytes for tx packet
   1421  *
   1422  * Returns:
   1423  *     SOC_E_XXXX
   1424  */
   1425 bcm_error_t
   1426 stream_tx_pkt(int unit, stream_pkt_t *tx_pkt)
   1427 {
   1428     bcm_error_t rv = BCM_E_NONE;
   1429     uint32 j;
   1430     uint32 pkt_size;
   1431     uint8 tos;
   1432     uint8 *pkt_ptr;
   1433     dv_t *dv_tx;
   1434 
   1435     dv_tx = soc_dma_dv_alloc(unit, DV_TX, 3);
   1436     soc_dma_init(unit);
   1437 
   1438     tx_pkt->cnt_pkt = 0;
   1439     pkt_size = tx_pkt->pkt_size;
   1440     for (j = 0; j < tx_pkt->num_pkt; j++) {
   1441         if (tx_pkt->rand_pkt_size_en == 1 && tx_pkt->rand_pkt_size != NULL) {
   1442             pkt_size = tx_pkt->rand_pkt_size[j];
   1443         }
   1444         tos = (j%2) ? 0x55: 0xaa;
   1445         pkt_ptr = sal_dma_alloc(pkt_size * sizeof(uint8), "packet");
   1446         sal_srand(tx_pkt->pkt_seed + j);
   1447         if (tx_pkt->new_flow_en == 1) {
   1448             tos = 0;
   1449             stream_gen_random_mpls_l3_pkt(pkt_ptr,
   1450                                      tx_pkt,
   1451                                      pkt_size,
   1452                                      j,
   1453                                      tos);
   1454         } else if (tx_pkt->l3_en == 1) {
   1455             stream_gen_random_l3_pkt(pkt_ptr,
   1456                                      tx_pkt->ipv6_en,
   1457                                      pkt_size,
   1458                                      j,
   1459                                      tx_pkt->mac_da,
   1460                                      tx_pkt->mac_sa,
   1461                                      (uint16) tx_pkt->tx_vlan,
   1462                                      tx_pkt->ip_da,
   1463                                      tx_pkt->ip_sa,
   1464                                      tx_pkt->ttl, tos);
   1465         } else {
   1466             stream_gen_random_l2_pkt(pkt_ptr,
   1467                                      pkt_size,
   1468                                      j,
   1469                                      tx_pkt->mac_da,
   1470                                      tx_pkt->mac_sa,
   1471                                      TPID,
   1472                                      (uint16) tx_pkt->tx_vlan);
   1473         }
   1474 
   1475         if (stream_pktdma_tx(unit, dv_tx, pkt_ptr, pkt_size) != BCM_E_NONE) {
   1476             rv = BCM_E_FAIL;
   1477             cli_out("*ERROR: Waiting for tx_pkt done, "
   1478                     "port %0d, pkt_num %0d\n",
   1479                     tx_pkt->port, j);
   1480         } else {
   1481             tx_pkt->cnt_pkt++;
   1482         }
   1483         sal_dma_free(pkt_ptr);
   1484     }
   1485 
   1486     soc_dma_abort_dv(unit, dv_tx);
   1487     soc_dma_dv_reset(DV_TX, dv_tx);
   1488     soc_dma_dv_free(unit, dv_tx);
   1489 
   1490     return rv;
   1491 }
   1492 
   1493 /*
   1494  * Function:
   1495  *      stream_calc_pipe_ovs_ratio
   1496  * Purpose:
   1497  *      Calculate oversub ratio for each pipe based on port config
   1498  * Parameters:
   1499  *      unit: StrataSwitch Unit #.
   1500  *      pkt_size: packet size in bytes
   1501  *      num_pipe: number of pipes per device
   1502  *      pipe_ovs_ratio_x1000: ptr to pipe oversub ratio array
   1503  *
   1504  * Returns:
   1505  *    SOC_E_XXXX
   1506  */
   1507 static bcm_error_t
   1508 stream_calc_pipe_ovs_ratio(int unit, uint32 pkt_size, int num_pipe,
   1509                            uint32 *pipe_ovs_ratio_x1000)
   1510 {
   1511     int port, port_speed;
   1512     int pipe, pipe_bandwidth = 0;
   1513     int lr_bandwidth = 0, ov_bandwidth = 0;
   1514     bcm_error_t rv = BCM_E_NONE;
   1515 
   1516     cli_out("\nCalculate pipe oversub ratio\n");
   1517 
   1518     /* initialize */
   1519     pipe_bandwidth = stream_get_pipe_bandwidth(unit, 0) -
   1520                      stream_get_ancl_bandwidth(unit, 0);
   1521 
   1522     for (pipe = 0; pipe < num_pipe; pipe++) {
   1523         pipe_ovs_ratio_x1000[pipe] = 0;
   1524     }
   1525 
   1526     cli_out("Freq = %0d, BW_per_pipe = %0d\n",
   1527             SOC_INFO(unit).frequency, pipe_bandwidth);
   1528 
   1529     /* calculate oversub ratio for each pipe */
   1530     for (pipe = 0; pipe < num_pipe; pipe++) {
   1531         lr_bandwidth = 0;
   1532         ov_bandwidth = 0;
   1533         PBMP_ITER(PBMP_PORT_ALL(unit), port) {
   1534             if (port < SOC_MAX_NUM_PORTS) {
   1535                 if (SOC_PBMP_MEMBER(PBMP_PIPE(unit, pipe), port)) {
   1536                     bcm_port_speed_get(unit, port, &port_speed);
   1537                     if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) {
   1538                         ov_bandwidth += port_speed;
   1539                     } else {
   1540                         lr_bandwidth += port_speed;
   1541                     }
   1542                 }
   1543             }
   1544         }
   1545 
   1546         if ((pipe_bandwidth - lr_bandwidth) > 0) {
   1547             pipe_ovs_ratio_x1000[pipe] =
   1548                 (ov_bandwidth * 1000) / (pipe_bandwidth - lr_bandwidth);
   1549             if (pkt_size >
   1550                 stream_get_safe_pkt_size(unit, pipe_ovs_ratio_x1000[pipe])) {
   1551                 pipe_ovs_ratio_x1000[pipe] = 1000;
   1552             }
   1553             if (pipe_ovs_ratio_x1000[pipe] < 1000) {
   1554                 pipe_ovs_ratio_x1000[pipe] = 1000;
   1555             }
   1556         } else {
   1557             pipe_ovs_ratio_x1000[pipe] = 0;
   1558         }
   1559 
   1560         cli_out("Pipe %0d, LR_BW = %0d, OV_BW = %0d, ovs_ratio_x1000 = %0d\n",
   1561                 pipe, lr_bandwidth, ov_bandwidth,
   1562                 pipe_ovs_ratio_x1000[pipe]);
   1563     }
   1564 
   1565     return rv;
   1566 }
   1567 
   1568 /*
   1569  * Function:
   1570  *      stream_adjust_port_exp_rate_Mbps
   1571  * Purpose:
   1572  *      Guarantee port expected rate is no greater than port max speed.
   1573  * Parameters:
   1574  *      unit: StrataSwitch Unit #.
   1575  *      port: physical port number.
   1576  *      exp_rate_Mbps: ptr to port rate in Mbps.
   1577  *
   1578  * Returns:
   1579  *     SOC_E_XXXX
   1580  */
   1581 static void
   1582 stream_adjust_port_exp_rate_Mbps(int unit, int port, uint64 *exp_rate_Mbps)
   1583 {
   1584     int port_speed, encap;
   1585     uint64 max_rate_64;
   1586 
   1587     if (exp_rate_Mbps != NULL) {
   1588         if (port < SOC_MAX_NUM_PORTS) {
   1589             /* get 64bit speed in Mbps */
   1590             bcm_port_speed_get(unit, port, &port_speed);
   1591             encap = (IS_HG_PORT(unit, port) | IS_HG2_ENABLED_PORT(unit, port)) ?
   1592                     BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE;
   1593             if (!SOC_IS_TOMAHAWKX(unit)) {
   1594                 port_speed = stream_get_exact_speed(port_speed, encap);
   1595             }
   1596             COMPILER_64_ZERO(max_rate_64);
   1597             COMPILER_64_SET(max_rate_64, 0, port_speed);
   1598 
   1599             /* check exp_rate with max_rate*/
   1600             if (COMPILER_64_GT((*exp_rate_Mbps), max_rate_64)) {
   1601                 COMPILER_64_SET((*exp_rate_Mbps),
   1602                                 COMPILER_64_HI(max_rate_64),
   1603                                 COMPILER_64_LO(max_rate_64));
   1604             }
   1605         }
   1606     }
   1607 }
   1608 
   1609 /*
   1610  * Function:
   1611  *      stream_calc_exp_rate_by_rx
   1612  * Purpose:
   1613  *      Calculate expected rate array for all ports. This is based on port
   1614  *      speed and pipe oversub ratio (for oversubscribed ports).
   1615  * Parameters:
   1616  *      unit: StrataSwitch Unit #.
   1617  *      port_rate_exp: ptr to expected rate array
   1618  *      rate_calc: interface containing all necessary parameters for rate
   1619  *                 calculation
   1620  *
   1621  * Returns:
   1622  *     SOC_E_XXXX
   1623  */
   1624 bcm_error_t
   1625 stream_calc_exp_rate_by_rx(int unit, uint64 *port_rate_exp,
   1626                                 stream_rate_t *rate_calc)
   1627 {
   1628     int port, port_src, port_speed, encap;
   1629     uint32 pkt_size, num_pipe;
   1630     uint64 meg;
   1631     uint64 ovs_ratio_x1000_64,traffic_load_64;
   1632     uint32 *pipe_ovs_ratio;
   1633     uint64 *port_rate;
   1634     uint32 *param_src_port;
   1635 
   1636     bcm_error_t rv = BCM_E_NONE;
   1637 
   1638     cli_out("\nCalculate expected port rate\n");
   1639 
   1640     /* initialize */
   1641     pkt_size = rate_calc->pkt_size;
   1642     param_src_port = rate_calc->src_port;
   1643     num_pipe = NUM_PIPE(unit);
   1644     port_rate = port_rate_exp;
   1645     pipe_ovs_ratio = (uint32 *) sal_alloc(num_pipe * sizeof(uint32),
   1646                                           "pipe_ovs_ratio");
   1647     if (pipe_ovs_ratio == NULL) {
   1648         test_error(unit, "Failed to allocate memory for exp rate check\n");
   1649         return BCM_E_FAIL;
   1650     }
   1651     sal_memset(pipe_ovs_ratio, 0, num_pipe * sizeof(uint32));
   1652 
   1653     COMPILER_64_SET(meg, 0, 1000000);
   1654     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   1655         COMPILER_64_ZERO(port_rate[port]);
   1656     }
   1657 
   1658     /* calculate oversub ratio for each pipe */
   1659     stream_calc_pipe_ovs_ratio(unit, pkt_size, num_pipe, pipe_ovs_ratio);
   1660 
   1661 
   1662     COMPILER_64_ZERO(traffic_load_64);
   1663     /* calculate expected port rate */
   1664     PBMP_ITER(PBMP_PORT_ALL(unit), port) {
   1665         if (port < SOC_MAX_NUM_PORTS) {
   1666             bcm_port_speed_get(unit, port, &port_speed);
   1667             encap = (IS_HG_PORT(unit, port) | IS_HG2_ENABLED_PORT(unit, port)) ?
   1668                          BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE;
   1669             if (!SOC_IS_TOMAHAWKX(unit)) {
   1670                 port_speed = stream_get_exact_speed(port_speed, encap);
   1671             }
   1672 
   1673             if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) {
   1674                 COMPILER_64_SET(port_rate[port], 0, port_speed);
   1675                 COMPILER_64_UMUL_32(port_rate[port], 1000000);
   1676                 COMPILER_64_SET(ovs_ratio_x1000_64, 0,
   1677                             pipe_ovs_ratio[stream_get_port_pipe(unit, port)]);
   1678                 COMPILER_64_UMUL_32(port_rate[port], 1000);
   1679                 COMPILER_64_SET(traffic_load_64, 0, 1000 * 100);
   1680                 if ( rate_calc->traffic_load != 0) {
   1681                     COMPILER_64_UDIV_32(traffic_load_64,  rate_calc->traffic_load);
   1682                 }
   1683                 if (rate_calc->traffic_load != 0 &&
   1684                     (!COMPILER_64_IS_ZERO(traffic_load_64)) &&
   1685                     COMPILER_64_GT(traffic_load_64, ovs_ratio_x1000_64)) {
   1686                     COMPILER_64_UDIV_64(port_rate[port], traffic_load_64);
   1687                 }
   1688                 else {
   1689                     if (!COMPILER_64_IS_ZERO(ovs_ratio_x1000_64)) {
   1690                         COMPILER_64_UDIV_64(port_rate[port], ovs_ratio_x1000_64);
   1691                     }
   1692                 }
   1693             } else {
   1694                 COMPILER_64_SET(port_rate[port], 0, port_speed);
   1695                 if (rate_calc->traffic_load != 0 &&
   1696                     !COMPILER_64_IS_ZERO(traffic_load_64)) {
   1697                     COMPILER_64_UDIV_64(port_rate[port], traffic_load_64);
   1698                 }
   1699                 COMPILER_64_UMUL_32(port_rate[port], 1000000);
   1700             }
   1701             COMPILER_64_UDIV_64(port_rate[port], meg); /* translate to Mbps */
   1702         }
   1703     }
   1704 
   1705     /* adjust expected port rate with src port rate */
   1706     PBMP_ITER(PBMP_PORT_ALL(unit), port) {
   1707         if (port < SOC_MAX_NUM_PORTS) {
   1708             char rate_str[32];
   1709             port_src = param_src_port[port];
   1710             format_uint64_decimal(rate_str, port_rate[port], ',');
   1711             LOG_INFO(BSL_LS_APPL_TESTS,
   1712                      (BSL_META_U(unit, "adjust expected port rate with src port rate dst_port = %8d src_port = %8d src_port rate = %7sM \n"),
   1713                                  port, port_src, rate_str));
   1714             if (port_src < SOC_MAX_NUM_PORTS &&
   1715                 port_src != port && port_src > 0) {
   1716                 COMPILER_64_SET(port_rate[port],
   1717                                 COMPILER_64_HI(port_rate[port_src]),
   1718                                 COMPILER_64_LO(port_rate[port_src]));
   1719             }
   1720         }
   1721     }
   1722 
   1723     sal_free(pipe_ovs_ratio);
   1724     return rv;
   1725 }
   1726 
   1727 /*
   1728  * Function:
   1729  *      stream_calc_exp_rate_by_tx
   1730  * Purpose:
   1731  *      Calculate expected rate array for all ports. This is based on port
   1732  *      speed and pipe oversub ratio (for oversubscribed ports).
   1733  * Parameters:
   1734  *      unit: StrataSwitch Unit #.
   1735  *      port_rate_exp: ptr to expected rate array
   1736  *      port_rate_act: ptr to actual rate array
   1737  *      rate_calc: interface containing all necessary parameters for rate
   1738  *                 calculation
   1739  *
   1740  * Returns:
   1741  *     SOC_E_XXXX
   1742  */
   1743 static bcm_error_t
   1744 stream_calc_exp_rate_by_tx(int unit, pbmp_t pbmp, uint64 *rate_exp,
   1745                            uint64 *rate_act, stream_rate_t *rate_calc)
   1746 {
   1747     uint32 port, p, n;
   1748     uint32 *src_port_array;
   1749     uint32 *num_rep_array;
   1750     bcm_error_t rv = BCM_E_NONE;
   1751 
   1752     cli_out("\nCalculate expected port rate\n");
   1753 
   1754     /* initialize */
   1755     src_port_array = rate_calc->src_port;
   1756     num_rep_array  = rate_calc->num_rep;
   1757 
   1758     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   1759         COMPILER_64_ZERO(rate_exp[port]);
   1760     }
   1761 
   1762     PBMP_ITER(PBMP_PORT_ALL(unit), port) {
   1763         if (port < SOC_MAX_NUM_PORTS) {
   1764             p = src_port_array[port];
   1765             n = num_rep_array[port];
   1766             COMPILER_64_SET(rate_exp[port], COMPILER_64_HI(rate_act[p]),
   1767                                             COMPILER_64_LO(rate_act[p]));
   1768             if (n > 0) {
   1769                 COMPILER_64_UMUL_32(rate_exp[port], n);
   1770             }
   1771             /* make sure expected rate is no greater than config rate */
   1772             stream_adjust_port_exp_rate_Mbps(unit, port, &(rate_exp[port]));
   1773         }
   1774     }
   1775 
   1776     return rv;
   1777 }
   1778 
   1779 
   1780 bcm_error_t
   1781 record_rate_information(int unit, uint32 emulation_param, pbmp_t pbmp, uint64 *time, uint64 *pkt_cnt, uint64 *byt_cnt)
   1782 {
   1783     int port;
   1784     uint64 rdata;
   1785     soc_reg_t reg_tpkt, reg_tbyt;
   1786 
   1787     PBMP_ITER(pbmp, port) {
   1788         if (port < SOC_MAX_NUM_PORTS) {
   1789             time[port] = get_cur_time(unit, emulation_param);
   1790             if (SOC_IS_TOMAHAWK3(unit)){
   1791                 bcm_stat_sync_get(unit, port, snmpIfInUcastPkts, &(pkt_cnt[port]));
   1792                 bcm_stat_sync_get(unit, port, snmpIfInOctets, &(byt_cnt[port]));
   1793             } else {
   1794                 BCM_IF_ERROR_RETURN(stream_get_reg_tpkt_tbyt(unit, port,
   1795                                      &reg_tpkt, &reg_tbyt));
   1796                 (void) soc_reg_get(unit, reg_tpkt, port, 0, &rdata);
   1797                 COMPILER_64_SET(pkt_cnt[port], COMPILER_64_HI(rdata),
   1798                                            COMPILER_64_LO(rdata));
   1799 
   1800                 (void) soc_reg_get(unit, reg_tbyt, port, 0, &rdata);
   1801                 COMPILER_64_SET(byt_cnt[port], COMPILER_64_HI(rdata),
   1802                                            COMPILER_64_LO(rdata));
   1803             }
   1804         }
   1805     }
   1806     return BCM_E_NONE;
   1807 }
   1808 
   1809 void
   1810 calc_act_port_rate(int unit, pbmp_t pbmp, uint64 *time_start, uint64 *time_end,
   1811                 uint64 *pkt_start, uint64 *pkt_end, uint64 *byt_start,
   1812                 uint64 *byt_end, uint64 *port_rate)
   1813 {
   1814     int port;
   1815     uint32 ipg, preamble;
   1816     uint64 time_delta, pkt_delta, byt_delta;
   1817 
   1818     PBMP_ITER(pbmp, port) {
   1819         if (port < SOC_MAX_NUM_PORTS) {
   1820             if (IS_HG_PORT(unit, port)) {
   1821                 ipg = HG2_IPG;
   1822                 preamble = 0;
   1823             } else {
   1824                 ipg = ENET_IPG;
   1825                 preamble = ENET_PREAMBLE;
   1826             }
   1827             COMPILER_64_DELTA(time_delta, time_start[port], time_end[port]);
   1828 
   1829             COMPILER_64_DELTA(pkt_delta, pkt_start[port], pkt_end[port]);
   1830             COMPILER_64_DELTA(byt_delta, byt_start[port], byt_end[port]);
   1831             COMPILER_64_UMUL_32(pkt_delta, (ipg + preamble));
   1832             COMPILER_64_ADD_64(byt_delta, pkt_delta);
   1833             COMPILER_64_UMUL_32(byt_delta, 8);
   1834             COMPILER_64_SET(port_rate[port], COMPILER_64_HI(byt_delta),
   1835                                              COMPILER_64_LO(byt_delta));
   1836             COMPILER_64_UDIV_64(port_rate[port], time_delta);
   1837         }
   1838     }
   1839 }
   1840 
   1841 
   1842 /*
   1843  * Function:
   1844  *      stream_calc_act_port_rate
   1845  * Purpose:
   1846  *      Calculate actual rate array for all ports. This is based on port
   1847  *      speed and pipe oversub ratio (for oversubscribed ports).
   1848  * Parameters:
   1849  *      unit: StrataSwitch Unit #.
   1850  *      scaling_factor: emulator speedup scaling factor, default 1;
   1851  *      rate_interval: interval length for rate calculation
   1852  *      port_rate_act : ptr to port actual rate array (x1000)
   1853  *
   1854  * Returns:
   1855  *     SOC_E_XXXX
   1856  */
   1857 static bcm_error_t
   1858 stream_calc_act_port_rate(int unit, uint32 emulation_param,
   1859                           uint32 rate_interval, uint64 *port_rate_act)
   1860 {
   1861     int port;
   1862     bcm_error_t rv = BCM_E_NONE;
   1863     uint32 interval_len;
   1864     uint64 *port_rate;
   1865     uint64 *time_start, *time_end;
   1866     uint64 *tpkt_start, *tpkt_end,
   1867            *tbyt_start, *tbyt_end;
   1868 
   1869     cli_out("\nCalculate actual port rate\n");
   1870 
   1871     /* initialize */
   1872     interval_len = rate_interval;
   1873     port_rate = port_rate_act;
   1874 
   1875     time_start = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1876                                            "time_start");
   1877     time_end   = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1878                                            "time_end");
   1879     tpkt_start = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1880                                       "tpkt_start");
   1881     tpkt_end   = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1882                                       "tpkt_end");
   1883     tbyt_start = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1884                                       "tbyt_start");
   1885     tbyt_end   = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   1886                                       "tbyt_end");
   1887     if (time_start == NULL || time_end == NULL ||
   1888         tpkt_start == NULL || tpkt_end == NULL ||
   1889         tbyt_start == NULL || tbyt_end == NULL) {
   1890         sal_free(time_start);
   1891         sal_free(time_end);
   1892         sal_free(tpkt_start);
   1893         sal_free(tpkt_end);
   1894         sal_free(tbyt_start);
   1895         sal_free(tbyt_end);
   1896         cli_out("*ERROR, Failed to allocate memory in "
   1897                 "stream_calc_act_port_rate()\n");
   1898         return BCM_E_FAIL;
   1899     }
   1900 
   1901     sal_memset(time_start, 0, SOC_MAX_NUM_PORTS * sizeof(uint64));
   1902     sal_memset(time_end,   0, SOC_MAX_NUM_PORTS * sizeof(uint64));
   1903     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   1904         COMPILER_64_ZERO(port_rate[port]);
   1905         COMPILER_64_ZERO(tpkt_start[port]);
   1906         COMPILER_64_ZERO(tpkt_end[port]);
   1907         COMPILER_64_ZERO(tbyt_start[port]);
   1908         COMPILER_64_ZERO(tbyt_end[port]);
   1909     }
   1910 
   1911     /* wait 2s for traffic to stabilize */
   1912     cli_out("-- Wait 2s for traffic to stabilize\n");
   1913     sal_usleep(2000000);
   1914     /* read counters at the beginning of interval */
   1915     record_rate_information(unit, emulation_param, PBMP_PORT_ALL(unit), time_start,
   1916                                                tpkt_start, tbyt_start);
   1917 
   1918     /* wait xs according to interval_len value */
   1919     cli_out("-- Measure Rate over a period of %0ds\n", interval_len);
   1920     sal_usleep(interval_len * 1000000);
   1921     /* read counters at the end of interval */
   1922     record_rate_information(unit, emulation_param, PBMP_PORT_ALL(unit), time_end,
   1923                                                tpkt_end, tbyt_end);
   1924 
   1925     calc_act_port_rate(unit, PBMP_PORT_ALL(unit), time_start, time_end,
   1926                        tpkt_start, tpkt_end, tbyt_start, tbyt_end,
   1927                        port_rate);
   1928 
   1929     sal_free(time_start);
   1930     sal_free(time_end);
   1931     sal_free(tpkt_start);
   1932     sal_free(tpkt_end);
   1933     sal_free(tbyt_start);
   1934     sal_free(tbyt_end);
   1935     return rv;
   1936 }
   1937 
   1938 /*
   1939  * Function:
   1940  *      stream_chk_dma_chain_done
   1941  * Purpose:
   1942  *      Check chain done or desc done bit in DMA status register.
   1943  * Parameters:
   1944  *      unit - StrataSwitch Unit #.
   1945  *      vchan - Virtual channel number
   1946  *      type -  check desc done or chain done
   1947  *      detected - whether desc done or chain done was detected
   1948  *
   1949  * Returns:
   1950  *     SOC_E_XXXX
   1951  */
   1952 bcm_error_t
   1953 stream_chk_dma_chain_done(int unit, int vchan, soc_dma_poll_type_t type,
   1954                           int *detected)
   1955 {
   1956     int rv = SOC_E_NONE;
   1957     int cmc = vchan / N_DMA_CHAN;
   1958     int chan = vchan % N_DMA_CHAN;
   1959 
   1960     switch (type) {
   1961     case SOC_DMA_POLL_DESC_DONE:
   1962         *detected = (soc_pci_read(unit, CMIC_CMCx_DMA_STAT_OFFSET(cmc))
   1963                      & DS_CMCx_DMA_DESC_DONE(chan));
   1964         break;
   1965     case SOC_DMA_POLL_CHAIN_DONE:
   1966         *detected = (soc_pci_read(unit, CMIC_CMCx_DMA_STAT_OFFSET(cmc))
   1967                      & DS_CMCx_DMA_CHAIN_DONE(chan));
   1968         break;
   1969     default:
   1970         break;
   1971     }
   1972 
   1973     return rv;
   1974 }
   1975 
   1976 /*
   1977  * Function:
   1978  *      stream_chk_mib_counters
   1979  * Purpose:
   1980  *      Checks MIB counters in MAC, IP, and EP
   1981  * Parameters:
   1982  *      unit - StrataSwitch Unit #.
   1983  *      pbmp - Device port bitmap to be checked
   1984  *      flag - set to 1 to check extra counter registers, default 0.
   1985  *
   1986  * Returns:
   1987  *     SOC_E_XXXX
   1988  */
   1989 bcm_error_t
   1990 stream_chk_mib_counters(int unit, pbmp_t pbmp, int flag)
   1991 {
   1992     uint32 port, j, column;
   1993     uint32 good_reg_num, error_reg_num;
   1994     uint64 rdata;
   1995     int pblk, phy_port;
   1996     bcm_error_t rv = BCM_E_NONE;
   1997     soc_reg_t good_counters[][4] = {
   1998                                     {RUCr,    RUC_64r,       RUC_64r,     RUC_64r},
   1999                                     {RPKTr,   XLMIB_RPKTr,   CLMIB_RPKTr, GRPKTr},
   2000                                     {RUCAr,   XLMIB_RUCAr,   CLMIB_RUCAr, GRUCr},
   2001                                     {RVLNr,   XLMIB_RVLNr,   CLMIB_RVLNr, INVALIDr},
   2002                                     {RBYTr,   XLMIB_RBYTr,   CLMIB_RBYTr, GRBYTr},
   2003                                     {RIPC4r,  RIPC4_64r,     RIPC4_64r,   RIPC4_64r},
   2004                                     {TPKTr,   XLMIB_TPKTr,   CLMIB_TPKTr, GTPKTr},
   2005                                     {TUCAr,   XLMIB_TUCAr,   CLMIB_TUCAr, GTUCr},
   2006                                     {TVLNr,   XLMIB_TVLNr,   CLMIB_TVLNr, INVALIDr},
   2007                                     {TBYTr,   XLMIB_TBYTr,   CLMIB_TBYTr, GTBYTr}
   2008                                 };
   2009     soc_reg_t error_counters[][4] = {
   2010                                     {RFLRr,   XLMIB_RFLRr,   CLMIB_RFLRr,   GRFLRr},
   2011                                     {RFCSr,   XLMIB_RFCSr,   CLMIB_RFCSr,   GRFCSr},
   2012                                     {RJBRr,   XLMIB_RJBRr,   CLMIB_RJBRr,   GRJBRr},
   2013                                     {RMTUEr,  XLMIB_RMTUEr,  CLMIB_RMTUEr,  GRMTUEr},
   2014                                     {RTRFUr,  XLMIB_RTRFUr,  CLMIB_RTRFUr,  INVALIDr},
   2015                                     {RERPKTr, XLMIB_RERPKTr, CLMIB_RERPKTr, GRCDEr},
   2016                                     {RRPKTr,  XLMIB_RRPKTr,  CLMIB_RRPKTr,  GRRPKTr},
   2017                                     {RUNDr,   XLMIB_RUNDr,   CLMIB_RUNDr,   GRUNDr},
   2018                                     {RFRGr,   XLMIB_RFRGr,   CLMIB_RFRGr,   GRFRGr},
   2019                                     {RRBYTr,  XLMIB_RRBYTr,  CLMIB_RRBYTr,  GRRBYTr},
   2020                                     {TJBRr,   XLMIB_TJBRr,   CLMIB_TJBRr,   GTJBRr},
   2021                                     {TFCSr,   XLMIB_TFCSr,   CLMIB_TFCSr,   GTFCSr},
   2022                                     {TERRr,   XLMIB_TERRr,   CLMIB_TERRr,   GTXCLr},
   2023                                     {TFRGr,   XLMIB_TFRGr,   CLMIB_TFRGr,   GTFRGr},
   2024                                     {TRPKTr,  XLMIB_TRPKTr,  CLMIB_TRPKTr,  INVALIDr},
   2025                                     {TUFLr,   XLMIB_TUFLr,   CLMIB_TUFLr,   INVALIDr},
   2026                                     {TPCEr,   TPCE_64r,      TPCE_64r,      TPCE_64r},
   2027                                     {RDISCr,  RDISC_64r,     RDISC_64r,     RDISC_64r},
   2028                                     {RIPHE4r, RIPHE4_64r,    RIPHE4_64r,    RIPHE4_64r},
   2029                                     {RIPHE6r, RIPHE6_64r,    RIPHE6_64r,    RIPHE6_64r},
   2030                                     {RIPD4r,  RIPD4_64r,     RIPD4_64r,     RIPD4_64r},
   2031                                     {RIPD6r,  RIPD6_64r,     RIPD6_64r,     RIPD6_64r},
   2032                                     {RPORTDr, RPORTD_64r,    RPORTD_64r,    RPORTD_64r}
   2033                                  };
   2034 
   2035     good_reg_num = sizeof(good_counters) / sizeof(good_counters[0]);
   2036     error_reg_num = sizeof(error_counters) / sizeof(error_counters[0]);
   2037     cli_out("\n==================================================\n");
   2038     cli_out("Checking Counter ...\n");
   2039 
   2040     PBMP_ITER(pbmp, port) {
   2041         if (port < SOC_MAX_NUM_PORTS) {
   2042             column = 0;
   2043 
   2044             phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   2045             if(phy_port == -1) {
   2046                 cli_out("\nERROR : Invalid logical port %0d used in counter "
   2047                               "check.", port);
   2048                 return BCM_E_INTERNAL;
   2049             }
   2050 
   2051             if (soc_feature(unit, soc_feature_cxl_mib)) {
   2052                 pblk = SOC_PORT_BLOCK(unit, phy_port);
   2053                 if (SOC_BLOCK_IS_CMP(unit, pblk, SOC_BLK_CLPORT)) {
   2054                     column = 2;
   2055                 } else if (IS_QSGMII_PORT(unit, port)) {
   2056                     column = 3;
   2057                 } else {
   2058                     column = 1;
   2059                 }
   2060             }
   2061             if (flag != 0) {
   2062                 for (j = 0; j < good_reg_num; j++) {
   2063                     if (SOC_REG_IS_VALID(unit, good_counters[j][column])) {
   2064                         SOC_IF_ERROR_RETURN(
   2065                             soc_reg_get(unit, good_counters[j][column], port, 0, &rdata));
   2066                         if (COMPILER_64_IS_ZERO(rdata)) {
   2067                             cli_out("*ERROR: (a) Counter %s "
   2068                                     "has a zero value for port %0d\n",
   2069                                     SOC_REG_NAME(unit, good_counters[j][column]), port);
   2070                             rv = BCM_E_FAIL;
   2071                         }
   2072                     }
   2073                 }
   2074             }
   2075 
   2076             for (j = 0; j < error_reg_num; j++) {
   2077                 if (SOC_REG_IS_VALID(unit, error_counters[j][column])) {
   2078                     SOC_IF_ERROR_RETURN(
   2079                         soc_reg_get(unit, error_counters[j][column], port, 0, &rdata));
   2080                     if (!COMPILER_64_IS_ZERO(rdata)) {
   2081                         cli_out("*ERROR: (b) Counter %s "
   2082                                 "has a non zero value for port %0d\n",
   2083                                 SOC_REG_NAME(unit, error_counters[j][column]), port);
   2084                         rv = BCM_E_FAIL;
   2085                     }
   2086                 }
   2087             }
   2088         }
   2089     }
   2090 
   2091     if (rv != BCM_E_NONE) {
   2092         cli_out("\n********* COUNTER CHECK FAILED *********\n");
   2093     } else {
   2094         cli_out("\n********* COUNTER CHECK PASSED *********\n");
   2095     }
   2096     return rv;
   2097 }
   2098 
   2099 
   2100 /*
   2101  * Function:
   2102  *      compare_rates
   2103  * Purpose:
   2104  *      Helper funtion to compare actual and expected rates.
   2105  * Parameters:
   2106  *      unit - StrataSwitch Unit #.
   2107  *      pbmp - Device port bitmap to be checked
   2108  *      tolerance_lr - Rate tolerance allowed for LR ports
   2109  *      tolerance_os - Rate tolerance allowed for OVS ports
   2110  *      port_rate_exp - expected port rate array
   2111  *      port_rate_act - actual port rate array
   2112  *
   2113  * Returns:
   2114  *     SOC_E_XXXX
   2115  */
   2116 bcm_error_t
   2117 compare_rates(int unit, pbmp_t pbmp, uint32 tolerance_lr, uint32 tolerance_os,
   2118               uint64 *port_rate_exp, uint64 *port_rate_act)
   2119 {
   2120     int cnt = 0, port, port_speed, encap;
   2121     uint32 tolerance;
   2122     uint64 min_rate, max_rate, hundred_64, margin_of_error;
   2123     char exp_rate_str[32], act_rate_str[32],
   2124          max_rate_str[32], min_rate_str[32];
   2125     bcm_error_t rv = BCM_E_NONE;
   2126 
   2127     COMPILER_64_SET(hundred_64, 0, 100);
   2128 
   2129     /* check actual rate against expected rate under tolerant range */
   2130     LOG_INFO(BSL_LS_APPL_TESTS,
   2131             (BSL_META_U(unit, "\n%4s %8s %8s %8s %8s %8s %8s \n"),
   2132                         "idx", "Dev_Port", "Speed", "Exp_Rate",
   2133                         "Min_Rate", "Max_Rate", "Act_Rate"));
   2134 
   2135     PBMP_ITER(pbmp, port) {
   2136         if (port < SOC_MAX_NUM_PORTS) {
   2137             bcm_port_speed_get(unit, port, &port_speed);
   2138             encap = (IS_HG_PORT(unit, port) | IS_HG2_ENABLED_PORT(unit, port)) ?
   2139                          BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE;
   2140             if (!SOC_IS_TOMAHAWKX(unit)) {
   2141                 port_speed = stream_get_exact_speed(port_speed, encap);
   2142             }
   2143 
   2144             /* margin_of_error */
   2145             if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) {
   2146                 tolerance = tolerance_os;
   2147             } else {
   2148                 tolerance = tolerance_lr;
   2149             }
   2150 
   2151             /* adjust speed tolerance */
   2152             if (SOC_IS_TRIDENT3X(unit)) {
   2153                 /* plus 1% extra tolerance for 10G higig */
   2154                 if ((encap == BCM_PORT_ENCAP_HIGIG2) &&
   2155                     (port_speed <= 11000 && port_speed >= 10000)) {
   2156                     tolerance +=1;
   2157                 }
   2158             }
   2159 
   2160             /* max_rate */
   2161             COMPILER_64_SET(max_rate, 0, port_speed);
   2162             COMPILER_64_SET(margin_of_error, 0, port_speed);
   2163             COMPILER_64_UMUL_32(margin_of_error, tolerance);
   2164             COMPILER_64_UDIV_64(margin_of_error, hundred_64);
   2165             COMPILER_64_ADD_64(max_rate, margin_of_error);
   2166 
   2167             /* min_rate */
   2168             COMPILER_64_SET(margin_of_error,
   2169                             COMPILER_64_HI(port_rate_exp[port]),
   2170                             COMPILER_64_LO(port_rate_exp[port]));
   2171             COMPILER_64_UMUL_32(margin_of_error, tolerance);
   2172             COMPILER_64_UDIV_64(margin_of_error, hundred_64);
   2173             COMPILER_64_DELTA(min_rate, margin_of_error, port_rate_exp[port]);
   2174 
   2175             /* printout */
   2176             format_uint64_decimal(min_rate_str, min_rate, ',');
   2177             format_uint64_decimal(max_rate_str, max_rate, ',');
   2178             format_uint64_decimal(exp_rate_str, port_rate_exp[port], ',');
   2179             format_uint64_decimal(act_rate_str, port_rate_act[port], ',');
   2180             LOG_INFO(BSL_LS_APPL_TESTS,
   2181                      (BSL_META_U(unit, "%4d %8d %7dG %7sM %7sM %7sM %7sM "),
   2182                                  cnt, port, port_speed/1000,
   2183                                  exp_rate_str, min_rate_str,
   2184                                  max_rate_str, act_rate_str));
   2185 
   2186             /* check */
   2187             if (COMPILER_64_LT(port_rate_act[port], min_rate)) {
   2188                 rv = BCM_E_FAIL;
   2189                 LOG_INFO(BSL_LS_APPL_TESTS,
   2190                          (BSL_META_U(unit, " %s"), "*FAIL"));
   2191             } else if (COMPILER_64_GT(port_rate_act[port], max_rate)) {
   2192                 LOG_INFO(BSL_LS_APPL_TESTS,
   2193                          (BSL_META_U(unit, " %s"), "*WARNING"));
   2194             }
   2195             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
   2196 
   2197             cnt++;
   2198         }
   2199     }
   2200     return rv;
   2201 }
   2202 
   2203 /*
   2204  * Function:
   2205  *      stream_chk_port_rate_new
   2206  * Purpose:
   2207  *      Check rates against expected rates.
   2208  * Parameters:
   2209  *      unit - StrataSwitch Unit #.
   2210  *      pbmp - Device port bitmap to be checked
   2211  *      rate_calc - ptr to rate struct, containing all necessary
   2212  *                 parameters needed for port rate check.
   2213  *
   2214  * Returns:
   2215  *     SOC_E_XXXX
   2216  */
   2217 bcm_error_t
   2218 stream_chk_port_rate(int unit, pbmp_t pbmp, stream_rate_t *rate_calc)
   2219 {
   2220     uint32 mode, interval_len, jitter_lr, jitter_os;
   2221     uint64 *port_rate_exp, *port_rate_act;
   2222     bcm_error_t rv = BCM_E_NONE;
   2223 
   2224     cli_out("\n==================================================\n");
   2225     cli_out("Checking Port Rate ...\n\n");
   2226     /* initialize */
   2227     mode = rate_calc->mode;
   2228     interval_len = rate_calc->interval_len;
   2229     jitter_lr = rate_calc->tolerance_lr;
   2230     jitter_os = rate_calc->tolerance_os;
   2231 
   2232     port_rate_exp = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   2233                                          "port_rate_exp");
   2234     port_rate_act = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64),
   2235                                          "port_rate_act");
   2236     if (port_rate_exp == NULL || port_rate_act == NULL) {
   2237         sal_free(port_rate_exp);
   2238         sal_free(port_rate_act);
   2239         test_error(unit, "Failed to allocate memory for rate check\n");
   2240         return BCM_E_FAIL;
   2241     }
   2242 
   2243     /* calculate actual rate */
   2244     stream_calc_act_port_rate(unit, rate_calc->emulation_param, interval_len,
   2245                               port_rate_act);
   2246 
   2247     /* calculate expected rate */
   2248     if (mode == 1) {
   2249         /* mode -> 1, calculate expected rate by tx_rate */
   2250         stream_calc_exp_rate_by_tx(unit, pbmp, port_rate_exp,
   2251                                         port_rate_act, rate_calc);
   2252     } else {
   2253         /* mode -> 0, calculate expected rate by rx config rate */
   2254         stream_calc_exp_rate_by_rx(unit, port_rate_exp, rate_calc);
   2255     }
   2256 
   2257 
   2258     rv = compare_rates(unit, rate_calc->pbmp, jitter_lr, jitter_os, port_rate_exp, port_rate_act);
   2259     if (rv != BCM_E_NONE) {
   2260         cli_out("\n********** RATE CHECK FAILED ***********\n");
   2261     } else {
   2262         cli_out("\n********** RATE CHECK PASSED ***********\n");
   2263     }
   2264 
   2265     sal_free(port_rate_exp);
   2266     sal_free(port_rate_act);
   2267     return rv;
   2268 }
   2269 
   2270 /*
   2271  * Function:
   2272  *      stream_chk_pkt_integrity
   2273  * Purpose:
   2274  *      Redirect all packets back to CPU and check packet integrity
   2275  * Parameters:
   2276  *      unit - StrataSwitch Unit #.
   2277  *      pkt_intg - ptr to packet integrity struct, containing all necessary
   2278  *                 parameters needed for integrity check.
   2279  *
   2280  * Returns:
   2281  *     SOC_E_XXXX
   2282  */
   2283 bcm_error_t
   2284 stream_chk_pkt_integrity(int unit, stream_integrity_t *pkt_intg)
   2285 {
   2286     bcm_error_t rv = BCM_E_NONE;
   2287     uint8 *rx_pkt, *ref_pkt;
   2288     int port, port_speed, j, k, chk_fail = 0, stream_cnt = 0;
   2289     int rst_vlan;
   2290     dv_t *dv_rx;
   2291     uint32 vlan;
   2292     uint32 pkt_size;
   2293     uint32 port_exp_pkt_cnt, port_act_pkt_cnt, pkt_cnt_sum = 0;
   2294     uint32 header_size = 0;
   2295     uint32 ts1, ts2, latency, max = 0, min = -1, sum = 0, average;
   2296 
   2297     cli_out("\n==================================================\n");
   2298     cli_out("Checking Packet Integrity ...\n\n");
   2299     /* initialize */
   2300     soc_dma_header_size_get(unit, &header_size);
   2301     dv_rx   = soc_dma_dv_alloc(unit, DV_RX, 3);
   2302     ref_pkt = sal_dma_alloc(MTU * sizeof(uint8), "ref_packet");
   2303     rx_pkt  = sal_dma_alloc(MTU * sizeof(uint8) + header_size, "rx_pkt");
   2304     if (dv_rx == NULL || ref_pkt == NULL || rx_pkt == NULL) {
   2305         soc_dma_dv_free(unit, dv_rx);
   2306         sal_dma_free(ref_pkt);
   2307         sal_dma_free(rx_pkt);
   2308         test_error(unit, "Failed to allocate memory for integrity check\n");
   2309         return BCM_E_FAIL;
   2310     }
   2311 
   2312     /* config all channels as RX */
   2313     soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 1, 0xffffffff);
   2314     soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 2, 0xffffffff);
   2315 
   2316     /* config unmatched VLAN packet to be forwarded to CPU */
   2317     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_0r, 0,
   2318                                                UVLAN_TOCPUf, 0x1));
   2319     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_1r, 0,
   2320                                                L3_MTU_FAIL_TOCPUf, 0x1));
   2321 
   2322     /* check packet integrity for each port */
   2323     LOG_INFO(BSL_LS_APPL_TESTS,
   2324              (BSL_META_U(unit, "%4s %4s %4s %8s %8s\n"),
   2325                          "idx", "port", "spd", "tx_pkt", "rx_pkt"));
   2326     PBMP_ITER(pkt_intg->rx_pbmp, port) {
   2327         if (port < SOC_MAX_NUM_PORTS) {
   2328             /* check integrity of each packet */
   2329             port_exp_pkt_cnt = pkt_intg->port_flood_cnt[port];
   2330             port_act_pkt_cnt = 0;
   2331             vlan = pkt_intg->rx_vlan[port];
   2332             for (j = 0; j < port_exp_pkt_cnt; j++) {
   2333                 rst_vlan = 0;
   2334                 if (j == 0) {
   2335                     if (pkt_intg->type == PKT_TYPE_L3UC) {
   2336                         rst_vlan = 2; /* L3 packet*/
   2337                     } else {
   2338                         rst_vlan = 1; /* L2 packet*/
   2339                     }
   2340                 }
   2341                 /* receive one packet from CPU though rx_pkt_dma */
   2342                 if (stream_pktdma_rx(unit, rst_vlan, vlan, dv_rx, rx_pkt,
   2343                                      MTU + header_size) != BCM_E_NONE) {
   2344                     /*
   2345                     cli_out("*ERROR, failed to receive pkt from CPU"
   2346                             "for integrity check, port %d\n",
   2347                             port);
   2348                     chk_fail = 1; */
   2349                     break;
   2350                 }
   2351                 port_act_pkt_cnt ++;
   2352 
   2353                 /* generate reference packet */
   2354                 if (stream_gen_ref_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt,
   2355                                        &pkt_size) != BCM_E_NONE) {
   2356                     cli_out("*ERROR, failed to generate ref_pkt "
   2357                             "for integrity check, port %d\n",
   2358                             port);
   2359                     chk_fail = 1;
   2360                     break;
   2361                 }
   2362 
   2363                 /* check packet content (payload) */
   2364                 for (k = 0; k < (pkt_size - NUM_BYTES_CRC); k++) {
   2365                     if (rx_pkt[k + header_size] != ref_pkt[k]) {
   2366                         cli_out("*ERROR: Packet corruption, "
   2367                                 "Stream %d, Port %d, Packet %d\n",
   2368                                 stream_cnt, port, j);
   2369                         cli_out("-- Expected Packet:");
   2370                         tgp_print_pkt(ref_pkt, pkt_size);
   2371                         cli_out("-- Received Packet:");
   2372                         tgp_print_pkt(rx_pkt, pkt_size+header_size);
   2373                         chk_fail = 1;
   2374                         break;
   2375                     }
   2376                 }
   2377 
   2378                 /* latency calculation */
   2379                 if (pkt_intg->type == PKT_TYPE_L2_TS) {
   2380                     ts1 = (rx_pkt[pkt_size+header_size+2] << 24) + (rx_pkt[pkt_size+header_size+3] << 16) +
   2381                           (rx_pkt[pkt_size+header_size+4] << 8) + rx_pkt[pkt_size+header_size+5];
   2382                     ts2 = (rx_pkt[pkt_size+header_size+16] << 24) + (rx_pkt[pkt_size+header_size+17] << 16) +
   2383                           (rx_pkt[pkt_size+header_size+18] << 8) + rx_pkt[pkt_size+header_size+19];
   2384                     latency = ts2 - ts1;
   2385                     if (latency < min) {
   2386                         min = latency;
   2387                     }
   2388                     if (latency > max) {
   2389                         max = latency;
   2390                     }
   2391                     sum += latency;
   2392                     LOG_INFO(BSL_LS_APPL_TESTS,
   2393                              (BSL_META_U(unit, "-- Packet %0d TS2 %0x TS1 %0x Latency %0d\n"),
   2394                                          j, ts2, ts1, latency));
   2395                 }
   2396             }
   2397 
   2398             /* disable forwarding pkt to cpu for current port */
   2399             if (pkt_intg->type == PKT_TYPE_L3UC) {
   2400                 stream_set_l3mtu_valid(unit, vlan);
   2401             } else {
   2402                 stream_set_vlan_valid(unit, vlan);
   2403             }
   2404 
   2405             /* check packet count */
   2406             bcm_port_speed_get(unit, port, &port_speed);
   2407             LOG_INFO(BSL_LS_APPL_TESTS,
   2408                      (BSL_META_U(unit, "%4d %4d %3dG %8d %8d "),
   2409                                  stream_cnt, port, port_speed/1000,
   2410                                  port_exp_pkt_cnt, port_act_pkt_cnt));
   2411             if (port_act_pkt_cnt == 0) {
   2412                 chk_fail = 1;
   2413                 LOG_INFO(BSL_LS_APPL_TESTS,
   2414                          (BSL_META_U(unit, "*WARNING")));
   2415             } else if (port_act_pkt_cnt < port_exp_pkt_cnt &&
   2416                 !(SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port))) {
   2417                 chk_fail = 1;
   2418                 LOG_INFO(BSL_LS_APPL_TESTS,
   2419                          (BSL_META_U(unit, "*WARNING")));
   2420             }
   2421             LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
   2422 
   2423             /* print latency */
   2424             if (pkt_intg->type == PKT_TYPE_L2_TS) {
   2425                 average = _shr_div_exp10(sum, port_act_pkt_cnt, 2);
   2426                 cli_out("Latency: max %0d ns, min %0d ns, average %0d.%02d ns\n",
   2427                         max, min, average / 100, average % 100);
   2428             }
   2429 
   2430             pkt_cnt_sum += port_act_pkt_cnt;
   2431             stream_cnt++;
   2432         }
   2433     }
   2434 
   2435     cli_out("Total packets received: %d\n", pkt_cnt_sum);
   2436     if (chk_fail == 0) {
   2437         cli_out("\n**** PACKET INTEGRITY CHECK PASSED *****\n");
   2438     } else {
   2439         cli_out("\n**** PACKET INTEGRITY CHECK FAILED *****\n");
   2440         rv = BCM_E_FAIL;
   2441     }
   2442 
   2443     soc_dma_abort_dv(unit, dv_rx);
   2444     soc_dma_dv_free(unit, dv_rx);
   2445     sal_dma_free(rx_pkt);
   2446     sal_dma_free(ref_pkt);
   2447 
   2448     return rv;
   2449 }
   2450 
   2451 
   2452 int
   2453 stream_get_exact_speed(int speed, int encap) {
   2454     if(encap == BCM_PORT_ENCAP_IEEE) return speed;
   2455     else {
   2456         switch (speed) {
   2457             case 120000: speed = 127000; break;
   2458             case 100000: speed = 106000; break;
   2459             case 50000:  speed = 53000;  break;
   2460             case 40000:  speed = 42000;  break;
   2461             case 25000:  speed = 27000;  break;
   2462             case 20000:  speed = 21000;  break;
   2463             case 10000:  speed = 11000;  break;
   2464             default: break;
   2465         }
   2466         return speed;
   2467     }
   2468 }
   2469 
   2470 /*
   2471  * Function:
   2472  *      start_cmic_timesync
   2473  * Purpose:
   2474  *      Enable CMIC timesync module to run NS timestamp
   2475  * Parameters:
   2476  *      unit - StrataSwitch Unit #.
   2477  *
   2478  * Returns:
   2479  *     Nothing
   2480  */
   2481 void start_cmic_timesync(int unit)
   2482 {
   2483     uint32 rval;
   2484 
   2485     /* Enable Timestamp Generation */
   2486     READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, &rval);
   2487     /* 250 Mhz - 4.000 ns */
   2488     soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr, &rval, FRACf,
   2489                       0x40000000);
   2490     WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, rval);
   2491 
   2492     READ_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, &rval);
   2493     soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &rval,
   2494                       TIME_CAPTURE_ENABLEf, 1);
   2495     WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, rval);
   2496 
   2497     READ_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval);
   2498     soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_COUNTER_ENABLEr, &rval,
   2499                       ENABLEf, 1);
   2500     WRITE_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval);
   2501 }
   2502 
   2503 uint64 get_ts_count(int unit)
   2504 {
   2505     uint64 ts, div_64;
   2506     uint32 rval, valid, ts_lower, ts_upper;
   2507 
   2508     if (soc_feature(unit, soc_feature_cmicx)) {
   2509         /*soc_iproc_getreg(unit,
   2510               soc_reg_addr(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr,
   2511               REG_PORT_ANY, 0), &rval);
   2512         cli_out("\n ts capture %0x", rval);*/
   2513         rval = 0;
   2514         soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &rval,
   2515                           TIME_CAPTURE_MODEf, 1);
   2516         /*soc_iproc_setreg(unit,
   2517               soc_reg_addr(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr,
   2518               REG_PORT_ANY, 0), rval);*/
   2519         soc_pci_write(unit, 0x35024, rval);
   2520 
   2521         rval = soc_pci_read(unit, 0x3502c);
   2522         /*soc_iproc_getreg(unit,
   2523               soc_reg_addr(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr,
   2524               REG_PORT_ANY, 0), &rval);
   2525         cli_out("\n ts lower %0x", rval);*/
   2526         ts_lower = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr,
   2527                               rval, TIMESTAMPf);
   2528         rval = soc_pci_read(unit, 0x35030);
   2529         /*soc_iproc_getreg(unit,
   2530               soc_reg_addr(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
   2531               REG_PORT_ANY, 0), &rval);
   2532         cli_out("\n ts upper %0x", rval);*/
   2533         valid = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
   2534                                   rval, VALIDf);
   2535         ts_upper = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
   2536                                   rval, TIMESTAMPf);
   2537     } else {
   2538         READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &rval);
   2539         soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &rval,
   2540                           TIME_CAPTURE_MODEf, 1);
   2541         WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, rval);
   2542         READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr(unit, &rval);
   2543         ts_lower = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr,
   2544                               rval, TIMESTAMPf);
   2545         READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr(unit, &rval);
   2546         valid = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
   2547                                   rval, VALIDf);
   2548         ts_upper = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr,
   2549                                   rval, TIMESTAMPf);
   2550     }
   2551 
   2552     COMPILER_64_SET(div_64, 0, 1000);
   2553     COMPILER_64_ZERO(ts);
   2554     if(valid) {
   2555             COMPILER_64_SET(ts, ts_upper, ts_lower);
   2556             COMPILER_64_UDIV_64(ts, div_64);
   2557     }
   2558     return ts;
   2559 }
   2560 
   2561 uint64 get_cur_time(int unit, uint32 emulation_param)
   2562 {
   2563     uint64 time;
   2564 
   2565     if(emulation_param) time = get_ts_count(unit);
   2566     else COMPILER_64_SET(time, 0, sal_time_usecs());
   2567 
   2568     return time;
   2569 }
   2570 
   2571 #endif /* BCM_ESW_SUPPORT */