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

pktdma_soc_test.c (192967B)


      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  * CMIC Packet DMA performance test.
      8  * This test is intended to test the CMIC packet DMA performance. It can also
      9  * also be used as a feature test. The test can simultaneously exercise multiple
     10  * TX and RX channels across multiple CMCs.
     11  *
     12  * Parameters passed from the CLI:
     13  * TxBitmap : 12-bit bitmap of TX channels. For example 0x333 signifies channels
     14  *            0 and 1 of all 3 CMCs.
     15  * RxBitmap : 12-bit bitmap of RX channels. For example 0xccc signifies channels
     16  *            2 and 3 of all 3 CMCs. Please note that the Tx and Rx bitmaps
     17  *            should be mutually exclusive and there should be at
     18  *            least 1 Tx channel enabled if Rx is enabled.
     19  * PktSize :  Packet size in bytes. Use 0 for random packet sizes.
     20  * StreamTx : Continuously stream packets on TX.
     21  * StreamRx : Continuously stream packets on RX.
     22  * NumPktsTx : Number of packets for which descriptors are set up at one time.
     23  *             If StreamTx=0, this is the number of packets transmitted. If
     24  *             chaining is enabled by the TestTypeTx parameter, this is also the
     25  *             number of packets-per-chain.
     26  * NumPktsRx : Number of packets for which descriptors are set up at one time.
     27  *             If StreamRx=0, this is the number of packets transmitted. If
     28  *             chaining is enabled by the TestTypeRx parameter, this is also the
     29  *             number of packets-per-chain.
     30  * TestTypeTx : Used to set the descriptor type or test type.
     31  *              0: Simple Packet DMA: Each descriptor points to a single packet
     32  *              1: Scatter/Gather without packet chaining: Each packet is split
     33  *                 among 2 descriptors. However there is only 1 packet per chain.
     34  *              2: Chained DMA: Each descriptor points to 1 packet. However we
     35  *                 have descriptor chaining. Number of packets per chain is
     36  *                 specified by NumPktsTx.
     37  *              3: Scatter/Gather with packet chaining: Each packet split among
     38  *                 2 descriptors. Number of packets per chain specified by
     39  *                 NumPktsTx.
     40  *              4: Reload in infinite loop: Reload descriptor added at the end
     41  *                 that points to the top of the descriptor chain whose length
     42  *                 is specified by NumPktsTx. This creates an infinite HW loop.
     43  *                 This is very useful for measuring the raw HW performance of
     44  *                 the DMA engine..
     45  * TestTypeRx : Used to set the descriptor type.
     46  *              0: Simple Packet DMA: Each descriptor points to a single packet
     47  *              1: Scatter/Gather without packet chaining: Each packet is split
     48  *                 among 2 descriptors. However there is only 1 packet per chain.
     49  *              2: Chained DMA: Each descriptor points to 1 packet. However we
     50  *                 have descriptor chaining. Number of packets per chain
     51  *                 specified by NumPktsRx.
     52  *              3: Scatter/Gather with packet chaining: Each packet is split
     53  *                 among 2 descriptors. Number of packets per chain specified by
     54  *                 NumPktsRx.
     55  *              4: Reload in infinite loop: Reload descriptor added at the end
     56  *                 that points to the top of the descriptor chain whose length
     57  *                 is specified by NumPktsRx. This creates an infinite HW loop.
     58  *                 This is very useful for measuring the raw HW performance of
     59  *                 the DMA engine.
     60  * ChkPktInteg : Enable packet integrity checks
     61  * RateCalcInt : Interval in seconds over which TX/RX rates are calculated.
     62  * PollIntr : Set to 0 for polling mode, 1 to enable chain done interrupts and
     63  *            2 to enable both descriptor done and chain done interrupts
     64  * Verbose : Print descriptors and packet pointers
     65  * SwThOff: Turn off memscan, linkscan and counter collection threads
     66  * SkipCosBmp: Skip COS Ctrl bitmap programming in CMIC
     67  * SVOverride: Special override for internal SV testing
     68  * PktChkInt: Interval between successive packet content checks in streaming
     69  *            mode. It is specified in terms of NumPktsRx. For example setting
     70  *            this parameterto 100 with NumPktsRx=20 means 20 pkts will be
     71  *            checked for content every 20*100=2000 received packets.
     72  * MaxPktSize: Max packet size if random packet sizes are used (PktSize=0).
     73  * NumLbPorts: Number of front panel ports used for looping back packets if
     74  *             streaming enabled.
     75  * CmicxLoopBack: Perform cmicx loopback
     76  */
     77 
     78 #include <appl/diag/system.h>
     79 #include <shared/alloc.h>
     80 #include <sal/core/alloc.h>
     81 #include <shared/bsl.h>
     82 
     83 #include <soc/cm.h>
     84 #include <soc/dma.h>
     85 #include <soc/drv.h>
     86 #include <soc/dcb.h>
     87 #include <soc/cmicm.h>
     88 #include <soc/cmic.h>
     89 
     90 #include <sal/types.h>
     91 #include <appl/diag/parse.h>
     92 #include <bcm/port.h>
     93 #include <bcm/vlan.h>
     94 #include <bcm/link.h>
     95 
     96 #if defined(BCM_TOMAHAWK3_SUPPORT)
     97 #include <soc/format.h>
     98 #include <soc/mcm/formatacc.h>
     99 #endif
    100 
    101 #include "testlist.h"
    102 #include "gen_pkt.h"
    103 
    104 #define MAC_DA {0x12,0x34,0x56,0x78,0x9a,0xbc}
    105 #define MAC_SA {0xfe,0xdc,0xba,0x98,0x76,0x54}
    106 #define TPID 0x8100
    107 #define VLAN 0x0abc
    108 #define XLATE_VLAN 0xdef
    109 
    110 #define DESC_TX_SINGLE_PKT 0x0
    111 #define DESC_TX_SINGLE_PKT_SPLIT 0x1
    112 #define DESC_TX_CHAIN_PKT 0x2
    113 #define DESC_TX_CHAIN_PKT_SPLIT 0x3
    114 #define DESC_TX_CHAIN_PKT_RELOAD 0x4
    115 #define DESC_RX_SINGLE_PKT 0x0
    116 #define DESC_RX_SINGLE_PKT_SPLIT 0x1
    117 #define DESC_RX_CHAIN_PKT 0x2
    118 #define DESC_RX_CHAIN_PKT_SPLIT 0x3
    119 #define DESC_RX_CHAIN_PKT_RELOAD 0x4
    120 #define NUM_BYTES_PER_DESC 64
    121 #define MAX_MTU_CHAIN_LENGTH 30
    122 #define MAX_DESC_CHAIN_LENGTH 150
    123 #define MTU 9216
    124 #define MAX_SPLITS 4
    125 #define MAX_CHANNELS 16
    126 #define POLL 0
    127 #define CHAIN_DONE_INTR_ONLY 1
    128 #define BOTH_DESC_CHAIN_INTR 2
    129 #define ENET_IPG 12
    130 #define ENET_PREAMBLE 8
    131 
    132 #define TX_BITMAP_PARAM_DEFAULT 0x001
    133 #define RX_BITMAP_PARAM_DEFAULT 0x002
    134 #define PKT_SIZE_PARAM_DEFAULT 250
    135 #define STREAM_PARAM_DEFAULT_TX 0
    136 #define STREAM_PARAM_DEFAULT_RX 0
    137 #define NUM_PKTS_PARAM_DEFAULT_TX 2
    138 #define NUM_PKTS_PARAM_DEFAULT_RX 2
    139 #define TEST_TYPE_PARAM_DEFAULT_TX 0x2
    140 #define TEST_TYPE_PARAM_DEFAULT_RX 0x2
    141 #define DISABLE_RX_FC_PARAM_DEFAULT 0x1
    142 #define CHECK_PACKET_INTEGRITY_PARAM_DEFAULT 0x0;
    143 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10;
    144 #define POLL_INTR_PARAM_DEFAULT 0
    145 #define VERBOSE_PARAM_DEFAULT 0
    146 #define SW_THREADS_OFF_PARAM_DEFAULT 1
    147 #define SKIP_COS_CTRL_BMP_PARAM_DEFAULT 0
    148 #define SV_OVERRIDE_PARAM_DEFAULT 0
    149 #define CMICX_LOOPBACK_PARAM_DEFAULT 0
    150 #define PKT_CHK_INT_PARAM_DEFAULT 100
    151 #define MAX_PKT_SIZE_PARAM_DEFAULT 9216
    152 #define NUM_LB_PORTS_PARAM_DEFAULT 20
    153 #define CPU_TIME_COST_PARAM_DEFAULT 0
    154 
    155 #define NUM_CONT_DMA_DV 12
    156 
    157 #define MAX_COS 16
    158 #define MIN_PKT_SIZE 64
    159 
    160 #define NUM_SUBP_OBM 4
    161 #define NUM_BYTES_MAC_ADDR 6
    162 #define NUM_BYTES_CRC 4
    163 
    164 #define TD2P_PGWS_PER_DEV 8
    165 
    166 #define CMICM_MMU_BKP_OFF_THRESHOLD 0x20
    167 #define CMICX_MMU_BKP_OFF_THRESHOLD 0xff
    168 
    169 #define DMA_CHAN_PER_CMC(unit) (SOC_VCHAN_NUM(unit) / SOC_CMCS_NUM(unit))
    170 
    171 #if defined(BCM_ESW_SUPPORT) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT))
    172 
    173 typedef void (*isr_chain_done_t) (int, dv_t *);
    174 typedef void (*isr_reload_done_t) (int, dv_t *);
    175 typedef void (*isr_desc_done_t) (int, dv_t *, dcb_t *);
    176 
    177 typedef struct pktdma_s {
    178     uint32 tx_bitmap_param;
    179     uint32 rx_bitmap_param;
    180     uint32 pkt_size_param;
    181     uint32 stream_param_tx;
    182     uint32 stream_param_rx;
    183     uint32 num_pkts_param_tx;
    184     uint32 num_pkts_param_rx;
    185     uint32 test_type_param_tx;
    186     uint32 test_type_param_rx;
    187     uint32 check_packet_integrity_param;
    188     uint32 rate_calc_interval_param;
    189     uint32 poll_intr_param;
    190     uint32 verbose_param;
    191     uint32 sw_threads_off_param;
    192     uint32 skip_cos_ctrl_bmp_param;
    193     uint32 sv_override_param;
    194     uint32 pkt_chk_int_param;
    195     uint32 max_pkt_size_param;
    196     uint32 num_lb_ports_param;
    197     uint32 cpu_time_cost_param;
    198     uint8 ***pkt_tx_array;
    199     uint8 ***pkt_rx_array;
    200     uint32 desc_done_count_tx[MAX_CHANNELS];
    201     uint32 desc_done_count_rx[MAX_CHANNELS];
    202     uint32 chain_done_count_tx[MAX_CHANNELS];
    203     uint32 chain_done_count_rx[MAX_CHANNELS];
    204     uint32 reload_done_count_tx[MAX_CHANNELS];
    205     uint32 reload_done_count_rx[MAX_CHANNELS];
    206     uint32 chain_done_tx[MAX_CHANNELS];
    207     uint32 chain_done_rx[MAX_CHANNELS];
    208     uint32 reload_done_tx[MAX_CHANNELS];
    209     uint32 reload_done_rx[MAX_CHANNELS];
    210     uint32 **random_packet_sizes;
    211     uint32 source_ch[MAX_CHANNELS];
    212     uint32 kill_dma;
    213     uint32 chain_tx;
    214     uint32 sg_tx;
    215     uint32 reload_tx;
    216     uint32 chain_rx;
    217     uint32 sg_rx;
    218     uint32 reload_rx;
    219     uint32 *cmic_tx_counters;
    220     uint32 *cmic_rx_counters;
    221     uint32 cont_dma;
    222     uint32 pkt_seed;
    223     uint32 cmicx_loopback_param;
    224     uint32 header_offset;
    225     isr_desc_done_t desc_done_intr_tx_table[MAX_CHANNELS];
    226     isr_desc_done_t desc_done_intr_rx_table[MAX_CHANNELS];
    227     isr_chain_done_t chain_done_intr_tx_table[MAX_CHANNELS];
    228     isr_chain_done_t chain_done_intr_rx_table[MAX_CHANNELS];
    229     isr_chain_done_t reload_done_intr_tx_table[MAX_CHANNELS];
    230     isr_chain_done_t reload_done_intr_rx_table[MAX_CHANNELS];
    231     sal_thread_t pid_tx;
    232     sal_thread_t pid_rx;
    233     dv_t *dv_tx;
    234     dv_t *dv_rx;
    235     dv_t ***dv_tx_array[NUM_CONT_DMA_DV];
    236     dv_t ***dv_rx_array[NUM_CONT_DMA_DV];
    237     uint32 bad_input;
    238     int test_fail;
    239     uint32 tx_thread_done;
    240     uint32 rx_thread_done;
    241 } pktdma_t;
    242 
    243 static pktdma_t *pktdma_parray[SOC_MAX_NUM_DEVICES];
    244 
    245 /*
    246  * Function:
    247  *      pktdma_soc_parse_test_params
    248  * Purpose:
    249  *      Parse CLI parameters, create test structure and flag bad inputs.
    250  * Parameters:
    251  *      unit - StrataSwitch Unit #.
    252  *      a - Pointer to arguments
    253  *
    254  * Returns:
    255  *     Nothing
    256  * Notes:
    257  *      pktdma_p->bad_input set from here - tells test to crash out in case CLI
    258  *      input combination is invalid.
    259  */
    260 
    261 static void
    262 pktdma_soc_parse_test_params(int unit, args_t *a)
    263 {
    264     parse_table_t parse_table;
    265     pktdma_t *pktdma_p = pktdma_parray[unit];
    266     int32 min_pkt_size = MIN_PKT_SIZE;
    267     int32 num_tx_channels_active = 0;
    268     int32 num_rx_channels_active = 0;
    269     int32 i;
    270 
    271     char tr500_test_usage[] =
    272 #ifdef COMPILER_STRING_CONST_LIMIT
    273     "\nDocumentation too long to be displayed with -pedantic compiler\n";
    274 #else
    275     "CMIC Packet DMA performance test.\n"
    276     "This test is intended to test the CMIC packet DMA performance. It can also\n"
    277     "also be used as a feature test. The test can simultaneously exercise multiple\n"
    278     "TX and RX channels across multiple CMCs.\n"
    279     "\n"
    280     "Parameters passed from the CLI:\n"
    281     "TxBitmap : 12-bit bitmap of TX channels. For example 0x333 signifies channels\n"
    282     "           0 and 1 of all 3 CMCs.\n"
    283     "RxBitmap : 12-bit bitmap of RX channels. For example 0xccc signifies channels\n"
    284     "           2 and 3 of all 3 CMCs. Please note that the Tx and Rx bitmaps\n"
    285     "           should be mutually exclusive and there should be at\n"
    286     "           least 1 Tx channel enabled if Rx is enabled.\n"
    287     "PktSize :  Packet size in bytes. Use 0 for random packet sizes.\n"
    288     "StreamTx : Continuously stream packets on TX.\n"
    289     "StreamRx : Continuously stream packets on RX.\n"
    290     "NumPktsTx : Number of packets for which descriptors are set up at one time.\n"
    291     "            If StreamTx=0, this is the number of packets transmitted. If\n"
    292     "            chaining is enabled by the TestTypeTx parameter, this is also the\n"
    293     "            number of packets-per-chain.\n"
    294     "NumPktsRx : Number of packets for which descriptors are set up at one time.\n"
    295     "            If StreamRx=0, this is the number of packets transmitted. If\n"
    296     "            chaining is enabled by the TestTypeRx parameter, this is also the\n"
    297     "            number of packets-per-chain.\n"
    298     "TestTypeTx : Used to set the descriptor type or test type.\n"
    299     "             0: Simple Packet DMA: Each descriptor points to a single packet\n"
    300     "             1: Scatter/Gather without packet chaining: Each packet is split\n"
    301     "                among 2 descriptors. However there is only 1 packet per chain.\n"
    302     "             2: Chained DMA: Each descriptor points to 1 packet. However we\n"
    303     "                have descriptor chaining. Number of packets per chain is\n"
    304     "                specified by NumPktsTx.\n"
    305     "             3: Scatter/Gather with packet chaining: Each packet split among\n"
    306     "                2 descriptors. Number of packets per chain specified by\n"
    307     "                NumPktsTx.\n"
    308     "             4: Reload in infinite loop: Reload descriptor added at the end\n"
    309     "                that points to the top of the descriptor chain whose length\n"
    310     "                is specified by NumPktsTx. This creates an infinite HW loop.\n"
    311     "                This is very useful for measuring the raw HW performance of\n"
    312     "                the DMA engine..\n"
    313     "TestTypeRx : Used to set the descriptor type.\n"
    314     "             0: Simple Packet DMA: Each descriptor points to a single packet\n"
    315     "             1: Scatter/Gather without packet chaining: Each packet is split\n"
    316     "                among 2 descriptors. However there is only 1 packet per chain.\n"
    317     "             2: Chained DMA: Each descriptor points to 1 packet. However we\n"
    318     "                have descriptor chaining. Number of packets per chain\n"
    319     "                specified by NumPktsRx.\n"
    320     "             3: Scatter/Gather with packet chaining: Each packet is split\n"
    321     "                among 2 descriptors. Number of packets per chain specified by\n"
    322     "                NumPktsRx.\n"
    323     "             4: Reload in infinite loop: Reload descriptor added at the end\n"
    324     "                that points to the top of the descriptor chain whose length\n"
    325     "                is specified by NumPktsRx. This creates an infinite HW loop.\n"
    326     "                This is very useful for measuring the raw HW performance of\n"
    327     "                the DMA engine.\n"
    328     "ChkPktInteg : Enable packet integrity checks\n"
    329     "RateCalcInt : Interval in seconds over which TX/RX rates are calculated.\n"
    330     "PollIntr : Set to 0 for polling mode, 1 to enable chain done interrupts and\n"
    331     "           2 to enable both descriptor done and chain done interrupts\n"
    332     "Verbose : Print descriptors and packet pointers\n"
    333     "SwThOff: Turn off memscan, linkscan and counter collection threads\n"
    334     "SkipCosBmp: Skip COS Ctrl bitmap programming in CMIC\n"
    335     "SVOverride: Special override for internal SV testing\n"
    336     "CmicxLoopBack: Perform cmicx loopback\n"
    337     "PktChkInt: Interval between successive packet content checks in streaming\n"
    338     "           mode. It is specified in terms of NumPktsRx. For example setting\n"
    339     "           this parameterto 100 with NumPktsRx=20 means 20 pkts will be\n"
    340     "           checked for content every 20100=2000 received packets.\n"
    341     "MaxPktSize: Max packet size if random packet sizes are used (PktSize=0).\n"
    342     "NumLbPorts: Number of front panel ports used for looping back packets if\n"
    343     "            streaming enabled.\n";
    344 #endif
    345     pktdma_p->bad_input = 0;
    346 
    347     /*Assign Default values */
    348     pktdma_p->tx_bitmap_param = TX_BITMAP_PARAM_DEFAULT;
    349     pktdma_p->rx_bitmap_param = RX_BITMAP_PARAM_DEFAULT;
    350     pktdma_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT;
    351     pktdma_p->stream_param_tx = STREAM_PARAM_DEFAULT_TX;
    352     pktdma_p->stream_param_rx = STREAM_PARAM_DEFAULT_RX;
    353     pktdma_p->num_pkts_param_tx = NUM_PKTS_PARAM_DEFAULT_TX;
    354     pktdma_p->num_pkts_param_rx = NUM_PKTS_PARAM_DEFAULT_RX;
    355     pktdma_p->test_type_param_tx = TEST_TYPE_PARAM_DEFAULT_TX;
    356     pktdma_p->test_type_param_rx = TEST_TYPE_PARAM_DEFAULT_RX;
    357     pktdma_p->check_packet_integrity_param =
    358         CHECK_PACKET_INTEGRITY_PARAM_DEFAULT;
    359     pktdma_p->rate_calc_interval_param = RATE_CALC_INTERVAL_PARAM_DEFAULT;
    360     pktdma_p->poll_intr_param = POLL_INTR_PARAM_DEFAULT;
    361     pktdma_p->verbose_param = VERBOSE_PARAM_DEFAULT;
    362     pktdma_p->sw_threads_off_param = SW_THREADS_OFF_PARAM_DEFAULT;
    363     pktdma_p->skip_cos_ctrl_bmp_param = SKIP_COS_CTRL_BMP_PARAM_DEFAULT;
    364     pktdma_p->sv_override_param = SV_OVERRIDE_PARAM_DEFAULT;
    365     pktdma_p->cmicx_loopback_param = CMICX_LOOPBACK_PARAM_DEFAULT;
    366     pktdma_p->pkt_chk_int_param = PKT_CHK_INT_PARAM_DEFAULT;
    367     pktdma_p->max_pkt_size_param = MAX_PKT_SIZE_PARAM_DEFAULT;
    368     pktdma_p->num_lb_ports_param = NUM_LB_PORTS_PARAM_DEFAULT;
    369     pktdma_p->cpu_time_cost_param = CPU_TIME_COST_PARAM_DEFAULT;
    370 
    371     /*Parse CLI opts */
    372 
    373     parse_table_init(unit, &parse_table);
    374     parse_table_add(&parse_table, "TxBitmap", PQ_HEX|PQ_DFL, 0,
    375                     &(pktdma_p->tx_bitmap_param), NULL);
    376     parse_table_add(&parse_table, "RxBitmap", PQ_HEX|PQ_DFL, 0,
    377                     &(pktdma_p->rx_bitmap_param), NULL);
    378     parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0,
    379                     &(pktdma_p->pkt_size_param), NULL);
    380     parse_table_add(&parse_table, "StreamTx", PQ_INT|PQ_DFL, 0,
    381                     &(pktdma_p->stream_param_tx), NULL);
    382     parse_table_add(&parse_table, "StreamRx", PQ_INT|PQ_DFL, 0,
    383                     &(pktdma_p->stream_param_rx), NULL);
    384     parse_table_add(&parse_table, "NumPktsTx", PQ_INT|PQ_DFL, 0,
    385                     &(pktdma_p->num_pkts_param_tx), NULL);
    386     parse_table_add(&parse_table, "NumPktsRx", PQ_INT|PQ_DFL, 0,
    387                     &(pktdma_p->num_pkts_param_rx), NULL);
    388     parse_table_add(&parse_table, "TestTypeTx", PQ_INT|PQ_DFL, 0,
    389                     &(pktdma_p->test_type_param_tx), NULL);
    390     parse_table_add(&parse_table, "TestTypeRx", PQ_INT|PQ_DFL, 0,
    391                     &(pktdma_p->test_type_param_rx), NULL);
    392     parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0,
    393                     &(pktdma_p->check_packet_integrity_param), NULL);
    394     parse_table_add(&parse_table, "RateCalcInt", PQ_INT|PQ_DFL, 0,
    395                     &(pktdma_p->rate_calc_interval_param), NULL);
    396     parse_table_add(&parse_table, "PollIntr", PQ_INT|PQ_DFL, 0,
    397                     &(pktdma_p->poll_intr_param), NULL);
    398     parse_table_add(&parse_table, "Verbose", PQ_INT|PQ_DFL, 0,
    399                     &(pktdma_p->verbose_param), NULL);
    400     parse_table_add(&parse_table, "SwThOff", PQ_INT|PQ_DFL, 0,
    401                     &(pktdma_p->sw_threads_off_param), NULL);
    402     parse_table_add(&parse_table, "SkipCosBmp", PQ_INT|PQ_DFL, 0,
    403                     &(pktdma_p->skip_cos_ctrl_bmp_param), NULL);
    404     parse_table_add(&parse_table, "SVOverride", PQ_INT|PQ_DFL, 0,
    405                     &(pktdma_p->sv_override_param), NULL);
    406     parse_table_add(&parse_table, "CmicxLoopBack", PQ_INT|PQ_DFL, 0,
    407                     &(pktdma_p->cmicx_loopback_param), NULL);
    408     parse_table_add(&parse_table, "PktChkInt", PQ_INT|PQ_DFL, 0,
    409                     &(pktdma_p->pkt_chk_int_param), NULL);
    410     parse_table_add(&parse_table, "MaxPktSize", PQ_INT|PQ_DFL, 0,
    411                     &(pktdma_p->max_pkt_size_param), NULL);
    412     parse_table_add(&parse_table, "NumLbPorts", PQ_INT|PQ_DFL, 0,
    413                     &(pktdma_p->num_lb_ports_param), NULL);
    414     parse_table_add(&parse_table, "CpuTimeCost", PQ_INT|PQ_DFL, 0,
    415                     &(pktdma_p->cpu_time_cost_param), NULL);
    416 
    417     if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) {
    418         test_msg("%s", tr500_test_usage);
    419         test_error(unit,
    420                    "%s: Invalid option: %s\n",
    421                    ARG_CMD(a),
    422                    ARG_CUR(a) ? ARG_CUR(a) : "*");
    423         pktdma_p->bad_input = 1;
    424         parse_arg_eq_done(&parse_table);
    425     } else {
    426         cli_out("\n ------------- PRINTING TEST PARAMS ------------------");
    427         cli_out("\ntx_bitmap_param = 0x%04x", pktdma_p->tx_bitmap_param);
    428         cli_out("\nrx_bitmap_param = 0x%04x", pktdma_p->rx_bitmap_param);
    429         cli_out("\npkt_size_param = %0d", pktdma_p->pkt_size_param);
    430         cli_out("\nstream_param_tx = %0d", pktdma_p->stream_param_tx);
    431         cli_out("\nstream_param_rx = %0d", pktdma_p->stream_param_rx);
    432         cli_out("\nnum_pkts_param_tx = %0d", pktdma_p->num_pkts_param_tx);
    433         cli_out("\nnum_pkts_param_rx = %0d", pktdma_p->num_pkts_param_tx);
    434         cli_out("\ntest_type_param_tx = %0d", pktdma_p->test_type_param_tx);
    435         cli_out("\ntest_type_param_rx = %0d", pktdma_p->test_type_param_rx);
    436         cli_out("\ncheck_packet_integrity_param = %0d",
    437                 pktdma_p->check_packet_integrity_param);
    438         cli_out("\nrate_calc_interval_param = %0d",
    439                 pktdma_p->rate_calc_interval_param);
    440         cli_out("\npoll_intr_param = %0d", pktdma_p->poll_intr_param);
    441         cli_out("\nverbose_param = %0d", pktdma_p->verbose_param);
    442         cli_out("\nsw_threads_off_param = %0d", pktdma_p->sw_threads_off_param);
    443         cli_out("\nskip_cos_ctrl_bmp_param = %0d",
    444                 pktdma_p->skip_cos_ctrl_bmp_param);
    445         cli_out("\nsv_override_param = %0d", pktdma_p->sv_override_param);
    446         cli_out("\ncmicx_loopback_param = %0d", pktdma_p->cmicx_loopback_param);
    447         cli_out("\npkt_chk_int_param = %0d", pktdma_p->pkt_chk_int_param);
    448         cli_out("\nmax_pkt_size_param = %0d", pktdma_p->max_pkt_size_param);
    449         cli_out("\nnum_lb_ports_param = %0d", pktdma_p->num_lb_ports_param);
    450         cli_out("\ncpu_time_cost_param = %0d", pktdma_p->cpu_time_cost_param);
    451         cli_out("\n -----------------------------------------------------");
    452     }
    453 
    454     if (pktdma_p->cont_dma == 1) {
    455         if ((!
    456              (pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT
    457               || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_SPLIT))
    458             ||
    459             (!(pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT
    460                || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_SPLIT))) {
    461             pktdma_p->bad_input = 1;
    462             test_error
    463                 (unit, ("\n*ERROR: Only TestTypeTx/Rx= 2 or 3 supported by test"
    464                  " in Cont DMA mode\n"));
    465         }
    466     }
    467 
    468     if (pktdma_p->stream_param_rx == 0
    469         && pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
    470         test_error
    471             (unit,
    472              "\n*WARNING: TestTypeRx=4 sets up an infinite descriptor loop"
    473              " in hardware. Test will be treated as a performance test"
    474              " even though StreamTx=0\n");
    475     }
    476 
    477     if (pktdma_p->stream_param_tx == 0
    478         && pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD) {
    479         test_error
    480             (unit,
    481              "\n*WARNING: TestTypeTx=4 sets up an infinite descriptor loop in"
    482              " hardware. Test will be treated as a performance test"
    483              " even though StreamRx=0\n");
    484     }
    485 
    486     if ((pktdma_p->stream_param_tx == 0)
    487         && (pktdma_p->test_type_param_tx != DESC_TX_CHAIN_PKT_RELOAD)
    488         && (pktdma_p->rx_bitmap_param != 0)) {
    489         if (pktdma_p->stream_param_rx == 1
    490             || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
    491             pktdma_p->bad_input = 1;
    492             test_error(unit,
    493                        "\n*ERROR: Streaming enabled on RX but not on TX\n");
    494         }
    495     }
    496 
    497     if (pktdma_p->pkt_size_param == 0) {
    498         cli_out("\nUsing random packet sizes");
    499         if (pktdma_p->max_pkt_size_param > MTU) {
    500             pktdma_p->bad_input = 1;
    501             test_error(unit,
    502                    "\n*ERROR: Packet size cannot be higher than %0dB "
    503                    "(Device MTU)\n",  MTU);
    504         }
    505     } else if (pktdma_p->pkt_size_param < min_pkt_size) {
    506         pktdma_p->bad_input = 1;
    507         test_error
    508             (unit,
    509              "\n*ERROR: Packet size cannot be lower than %0dB\n",
    510              MIN_PKT_SIZE);
    511     } else if (pktdma_p->pkt_size_param > MTU) {
    512         pktdma_p->bad_input = 1;
    513         test_error(unit,
    514                    "\n*ERROR: Packet size cannot be higher than %0dB (Device MTU)\n",
    515                     MTU);
    516     }
    517 
    518     if ((pktdma_p->poll_intr_param != 0)
    519         && (pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD
    520             || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD)) {
    521         pktdma_p->bad_input = 1;
    522         test_error
    523             (unit,
    524              "\n*ERROR: Interrupts cannot be enabled with TestTypeTx/Rx=4 "
    525              "since this sets up an infinite loop in hardware.\n");
    526     }
    527 
    528     for (i = 0; i < MAX_CHANNELS; i++) {
    529         if (((pktdma_p->tx_bitmap_param >> i) % 2) != 0) {
    530             num_tx_channels_active++;
    531         }
    532         if (((pktdma_p->rx_bitmap_param >> i) % 2) != 0) {
    533             num_rx_channels_active++;
    534         }
    535     }
    536 
    537     if (!
    538         (pktdma_p->stream_param_tx == 1
    539          || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD
    540          || pktdma_p->stream_param_rx == 1
    541          || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD)) {
    542         if (num_tx_channels_active != num_rx_channels_active) {
    543             pktdma_p->bad_input = 1;
    544             test_error
    545                 (unit,
    546                  "\n*ERROR: Test is set up as a feature test with finite "
    547                  "packet counts. Cannot do counter or packet integrity"
    548                  " checks if the number of active TX channels do not match"
    549                  " the number of active RX channels, since they cannot"
    550                  " be paired\n");
    551         }
    552     }
    553 
    554     if (pktdma_p->check_packet_integrity_param == 1) {
    555         if (pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD
    556             || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
    557             pktdma_p->bad_input = 1;
    558             test_error
    559                 (unit,
    560                  "\n*ERROR: Cannot do packet integrity check with "
    561                  "in desc loop mode\n");
    562         }
    563         if (pktdma_p->num_pkts_param_tx != pktdma_p->num_pkts_param_rx) {
    564             pktdma_p->bad_input = 1;
    565             test_error
    566                 (unit,
    567                  "\n*ERROR: Cannot do packet integrity check in a finite "
    568                  "packet count test unless NumPktsTx==NumPktsRx\n");
    569         }
    570     }
    571 
    572 }
    573 
    574 /*
    575  * Function:
    576  *      pktdma_soc_gen_random_l2_pkt
    577  * Purpose:
    578  *      Generate random L2 packet with seq ID
    579  * Parameters:
    580  *      unit - StrataSwitch Unit #.
    581  *
    582  * Returns:
    583  *     Nothing
    584  */
    585 
    586 void
    587 pktdma_soc_gen_random_l2_pkt(uint8 *pkt_ptr, uint32 pkt_size,
    588                   uint8 mac_da[NUM_BYTES_MAC_ADDR],
    589                   uint8 mac_sa[NUM_BYTES_MAC_ADDR], uint16 tpid,
    590                   uint16 vlan_id, uint32 seq_id, uint32 channel,
    591                   uint32 cmicx_loopback_param)
    592 {
    593     uint32 crc;
    594     tgp_gen_random_l2_pkt(pkt_ptr, pkt_size, mac_da, mac_sa, tpid, vlan_id);
    595     pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 6] = (seq_id >> 24) & 0xff;
    596     pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 7] = (seq_id >> 16) & 0xff;
    597     pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 8] = (seq_id >> 8) & 0xff;
    598     pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 9] = (seq_id) & 0xff;
    599     pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 10] = (pkt_size >> 8) & 0xff;
    600     pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 11] = (pkt_size) & 0xff;
    601     pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 12] = (channel) & 0xff;
    602 
    603     tgp_populate_crc_table();
    604     crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size);
    605 
    606     pkt_ptr[pkt_size - NUM_BYTES_CRC + 3] = (crc >> 24) & 0xff;
    607     pkt_ptr[pkt_size - NUM_BYTES_CRC + 2] = (crc >> 16) & 0xff;
    608     pkt_ptr[pkt_size - NUM_BYTES_CRC + 1] = (crc >> 8) & 0xff;
    609     pkt_ptr[pkt_size - NUM_BYTES_CRC] = (crc) & 0xff;
    610 
    611     if (cmicx_loopback_param) {
    612         pkt_ptr[4] = 0x0;
    613         
    614         pkt_ptr[7] = 0x0;
    615     }
    616 }
    617 
    618 /*
    619  * Function:
    620  *      pktdma_soc_set_source_ch_array
    621  * Purpose:
    622  *      Fill up pktdma_p->source_ch_array. Provides the TX channel for
    623  *      correspoding RX channels when channels are paired in a non-streaming
    624  *      mode.
    625  * Parameters:
    626  *      unit - StrataSwitch Unit #.
    627  *      tx_bitmap - 12 bit bitmap of TX channels
    628  *      rx_bitmap - 12 bit bitmap of RX channels
    629  * Returns:
    630  *     Nothing
    631  */
    632 
    633 static void
    634 pktdma_soc_set_source_ch_array(int unit, uint32 tx_bitmap, uint32 rx_bitmap)
    635 {
    636     uint32 tx_ch;
    637     uint32 rx_ch;
    638     pktdma_t *pktdma_p = pktdma_parray[unit];
    639 
    640     tx_ch = 0;
    641 
    642     for (rx_ch = 0; rx_ch < MAX_CHANNELS; rx_ch++) {
    643         pktdma_p->source_ch[rx_ch] = 99;
    644     }
    645 
    646     for (rx_ch = 0; rx_ch < MAX_CHANNELS; rx_ch++) {
    647         if (((rx_bitmap >> rx_ch) % 2) != 0) {
    648             while (tx_ch < MAX_CHANNELS) {
    649                 if (((tx_bitmap >> tx_ch) % 2) != 0) {
    650                     pktdma_p->source_ch[rx_ch] = tx_ch;
    651                     tx_ch++;
    652                     break;
    653                 }
    654                 tx_ch++;
    655             }
    656         }
    657     }
    658 }
    659 
    660 /*
    661  * Function:
    662  *      store_l2_packets
    663  * Purpose:
    664  *      Store L2 packets for TX, allocate space for received packets
    665  * Parameters:
    666  *      unit - StrataSwitch Unit #.
    667  *
    668  * Returns:
    669  *     Nothing
    670  */
    671 
    672 static void
    673 store_l2_packets(int unit)
    674 {
    675     pktdma_t *pktdma_p;
    676     uint32 min_pkt_size = MIN_PKT_SIZE;
    677     uint32 i, j;
    678     uint32 use_random_packet_sizes = 0;
    679     uint32 prio = 0;
    680     uint32 prio_cfi = 0;
    681     uint32 num_rx_channels_active = 0;
    682     uint8 mac_sa[] = MAC_SA;
    683     uint8 mac_da[] = MAC_DA;
    684 
    685     pktdma_p = pktdma_parray[unit];
    686 
    687     LOG_INFO(BSL_LS_APPL_TESTS,
    688              (BSL_META_U(unit, "\nCalling store_l2_packets")));
    689 
    690     LOG_INFO(BSL_LS_APPL_TESTS,
    691              (BSL_META_U(unit, "\nStoring random packet sizes")));
    692 
    693     pktdma_p->random_packet_sizes =
    694         (uint32 **) sal_alloc(MAX_CHANNELS * sizeof(uint32 *),
    695                               "pktdma_p->random_packet_sizes_ptr");
    696     for (i = 0; i < MAX_CHANNELS; i++) {
    697         pktdma_p->random_packet_sizes[i] =
    698             (uint32 *) sal_alloc(MAX_DESC_CHAIN_LENGTH * sizeof(uint32),
    699                                  "pktdma_p->random_packet_sizes");
    700     }
    701 
    702     for (i = 0; i < MAX_CHANNELS; i++) {
    703         if (((pktdma_p->rx_bitmap_param >> i) % 2) != 0) {
    704             num_rx_channels_active++;
    705         }
    706     }
    707 
    708     for (i = 0; i < MAX_CHANNELS; i++) {
    709         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\nChannel %0d"), i));
    710         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n-----------")));
    711         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
    712         for (j = 0; j < MAX_DESC_CHAIN_LENGTH; j++) {
    713             /* coverity[dont_call : FALSE] */
    714             pktdma_p->random_packet_sizes[i][j] =
    715                 min_pkt_size +
    716                     (sal_rand() % (pktdma_p->max_pkt_size_param - min_pkt_size));
    717             LOG_INFO(BSL_LS_APPL_TESTS,
    718                      (BSL_META_U(unit, "%0d "),
    719                       pktdma_p->random_packet_sizes[i][j]));
    720         }
    721         LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n")));
    722     }
    723     LOG_INFO(BSL_LS_APPL_TESTS,
    724              (BSL_META_U(unit, "\nDone Storing random packet sizes")));
    725 
    726     if (pktdma_p->pkt_size_param == 0) {
    727         LOG_INFO(BSL_LS_APPL_TESTS,
    728                  (BSL_META_U(unit, "\nUsing Random Packet Sizes")));
    729         use_random_packet_sizes = 1;
    730     }
    731 
    732     pktdma_p->pkt_tx_array =
    733                     soc_cm_salloc(unit, MAX_CHANNELS * sizeof(uint8 **),
    734                                   "pktdma_p->pkt_tx_array***");
    735 
    736     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\nStoring TX packets")));
    737 
    738     for (i = 0; i < MAX_CHANNELS; i++) {
    739         if (((pktdma_p->tx_bitmap_param >> i) % 2) != 0) {
    740             pktdma_p->pkt_tx_array[i] =
    741                             soc_cm_salloc(unit, pktdma_p->num_pkts_param_tx *
    742                                          sizeof(uint8 *),
    743                                          "pktdma_p->pkt_tx_array**");
    744             for (j = 0; j < pktdma_p->num_pkts_param_tx; j++) {
    745                 if (SOC_IS_TRIDENT3X(unit)) {
    746                     prio_cfi = prio << 12;
    747                 } else {
    748                     prio_cfi = ((prio & 0x00000007) << 13) |
    749                                (((prio >> 3) & 0x00000001) << 12);
    750                 }
    751                 if (use_random_packet_sizes == 1) {
    752                     pktdma_p->pkt_tx_array[i][j] =
    753                                     soc_cm_salloc(unit, pktdma_p->
    754                                                 random_packet_sizes[i][j] *
    755                                                 sizeof(uint8),
    756                                                 "pktdma_p->pkt_tx_array*");
    757                     sal_srand(pktdma_p->pkt_seed + i + j);
    758                     pktdma_soc_gen_random_l2_pkt(pktdma_p->pkt_tx_array[i][j],
    759                                       pktdma_p->random_packet_sizes[i][j],
    760                                       mac_da, mac_sa, TPID,
    761                                       (VLAN | prio_cfi),
    762                                       j, i, pktdma_p->cmicx_loopback_param);
    763                 } else {
    764                     pktdma_p->pkt_tx_array[i][j] =
    765                                     soc_cm_salloc(unit, pktdma_p->pkt_size_param *
    766                                                 sizeof(uint8),
    767                                                 "pktdma_p->pkt_tx_array*");
    768                     sal_srand(pktdma_p->pkt_seed + i + j);
    769                     pktdma_soc_gen_random_l2_pkt(pktdma_p->pkt_tx_array[i][j],
    770                                       pktdma_p->pkt_size_param, mac_da, mac_sa,
    771                                       TPID,
    772                                       (VLAN | prio_cfi),
    773                                       j, i, pktdma_p->cmicx_loopback_param);
    774                 }
    775                 {
    776                     uint32 debug_vlan;
    777                     debug_vlan = (VLAN | prio_cfi);
    778                     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
    779                              "\n[TX_PKT_VALN_TAG] ch %2d, pkt_num %3d, "
    780                              "vlan_tag 0x%04x"),
    781                              i, j, debug_vlan));
    782                 }
    783                 if (pktdma_p->rx_bitmap_param != 0x000
    784                     && (pktdma_p->stream_param_tx == 1
    785                         || pktdma_p->stream_param_rx == 1
    786                         || pktdma_p->test_type_param_tx ==
    787                         DESC_TX_CHAIN_PKT_RELOAD
    788                         || pktdma_p->test_type_param_rx ==
    789                         DESC_RX_CHAIN_PKT_RELOAD)) {
    790                     prio++;
    791                     prio = prio % num_rx_channels_active;
    792                 }
    793             }
    794             if (pktdma_p->rx_bitmap_param == 0x000
    795                 ||
    796                 (!(pktdma_p->stream_param_tx == 1
    797                    || pktdma_p->stream_param_rx == 1
    798                    || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD
    799                    || pktdma_p->test_type_param_rx ==
    800                    DESC_RX_CHAIN_PKT_RELOAD))) {
    801                 prio++;
    802             }
    803         }
    804     }
    805     LOG_INFO(BSL_LS_APPL_TESTS,
    806              (BSL_META_U(unit, "\nDone Storing TX packets")));
    807 
    808     LOG_INFO(BSL_LS_APPL_TESTS,
    809              (BSL_META_U(unit, "\nAllocating memory for RX packets")));
    810 
    811     pktdma_p->pkt_rx_array =
    812                     soc_cm_salloc(unit, MAX_CHANNELS * sizeof(uint8 **),
    813                                   "pktdma_p->pkt_rx_array***");
    814 
    815     for (i = 0; i < MAX_CHANNELS; i++) {
    816         if (((pktdma_p->rx_bitmap_param >> i) % 2) != 0) {
    817             pktdma_p->pkt_rx_array[i] =
    818                             soc_cm_salloc(unit, pktdma_p->num_pkts_param_rx *
    819                                          sizeof(uint8 *),
    820                                          "pktdma_p->pkt_rx_array**");
    821             for (j = 0; j < pktdma_p->num_pkts_param_rx; j++) {
    822                 if (use_random_packet_sizes) {
    823                     pktdma_p->pkt_rx_array[i][j] =
    824                                     soc_cm_salloc(unit, (pktdma_p->
    825                                                 max_pkt_size_param
    826                                                     + pktdma_p->header_offset) *
    827                                                 sizeof(uint8),
    828                                                 "pktdma_p->pkt_rx_array*");
    829                 } else {
    830                     pktdma_p->pkt_rx_array[i][j] =
    831                                     soc_cm_salloc(unit, (pktdma_p->pkt_size_param
    832                                                     + pktdma_p->header_offset) *
    833                                                 sizeof(uint8),
    834                                                 "pktdma_p->pkt_rx_array*");
    835                 }
    836             }
    837         }
    838     }
    839     LOG_INFO(BSL_LS_APPL_TESTS,
    840              (BSL_META_U(unit, "\nDone Allocating memory for RX packets")));
    841     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\nDone storing packets")));
    842 }
    843 
    844 /*
    845  * Functions:
    846  *      desc_done_intr_tx_0..15
    847  * Purpose:
    848  *      Interrupt level routine called from soc_dma_done_desc for TX descriptors
    849  *      for virtual channels 0..15.
    850  * Parameters:
    851  *      unit - StrataSwitch Unit #.
    852  *      dv - Descriptor vector raising interrupt
    853  *      dcb - Descriptor raising interrupt
    854  *
    855  * Returns:
    856  *     Nothing
    857  */
    858 
    859 static void
    860 desc_done_intr_tx_0(int unit, dv_t *dv, dcb_t *dcb)
    861 {
    862     pktdma_t *pktdma_p = pktdma_parray[unit];
    863 
    864     pktdma_p->desc_done_count_tx[0]++;
    865 }
    866 
    867 static void
    868 desc_done_intr_tx_1(int unit, dv_t *dv, dcb_t *dcb)
    869 {
    870     pktdma_t *pktdma_p = pktdma_parray[unit];
    871 
    872     pktdma_p->desc_done_count_tx[1]++;
    873 }
    874 
    875 static void
    876 desc_done_intr_tx_2(int unit, dv_t *dv, dcb_t *dcb)
    877 {
    878     pktdma_t *pktdma_p = pktdma_parray[unit];
    879 
    880     pktdma_p->desc_done_count_tx[2]++;
    881 }
    882 
    883 static void
    884 desc_done_intr_tx_3(int unit, dv_t *dv, dcb_t *dcb)
    885 {
    886     pktdma_t *pktdma_p = pktdma_parray[unit];
    887 
    888     pktdma_p->desc_done_count_tx[3]++;
    889 }
    890 
    891 static void
    892 desc_done_intr_tx_4(int unit, dv_t *dv, dcb_t *dcb)
    893 {
    894     pktdma_t *pktdma_p = pktdma_parray[unit];
    895 
    896     pktdma_p->desc_done_count_tx[4]++;
    897 }
    898 
    899 static void
    900 desc_done_intr_tx_5(int unit, dv_t *dv, dcb_t *dcb)
    901 {
    902     pktdma_t *pktdma_p = pktdma_parray[unit];
    903 
    904     pktdma_p->desc_done_count_tx[5]++;
    905 }
    906 
    907 static void
    908 desc_done_intr_tx_6(int unit, dv_t *dv, dcb_t *dcb)
    909 {
    910     pktdma_t *pktdma_p = pktdma_parray[unit];
    911 
    912     pktdma_p->desc_done_count_tx[6]++;
    913 }
    914 
    915 static void
    916 desc_done_intr_tx_7(int unit, dv_t *dv, dcb_t *dcb)
    917 {
    918     pktdma_t *pktdma_p = pktdma_parray[unit];
    919 
    920     pktdma_p->desc_done_count_tx[7]++;
    921 }
    922 
    923 static void
    924 desc_done_intr_tx_8(int unit, dv_t *dv, dcb_t *dcb)
    925 {
    926     pktdma_t *pktdma_p = pktdma_parray[unit];
    927 
    928     pktdma_p->desc_done_count_tx[8]++;
    929 }
    930 
    931 static void
    932 desc_done_intr_tx_9(int unit, dv_t *dv, dcb_t *dcb)
    933 {
    934     pktdma_t *pktdma_p = pktdma_parray[unit];
    935 
    936     pktdma_p->desc_done_count_tx[9]++;
    937 }
    938 
    939 static void
    940 desc_done_intr_tx_10(int unit, dv_t *dv, dcb_t *dcb)
    941 {
    942     pktdma_t *pktdma_p = pktdma_parray[unit];
    943 
    944     pktdma_p->desc_done_count_tx[10]++;
    945 }
    946 
    947 static void
    948 desc_done_intr_tx_11(int unit, dv_t *dv, dcb_t *dcb)
    949 {
    950     pktdma_t *pktdma_p = pktdma_parray[unit];
    951 
    952     pktdma_p->desc_done_count_tx[11]++;
    953 }
    954 
    955 static void
    956 desc_done_intr_tx_12(int unit, dv_t *dv, dcb_t *dcb)
    957 {
    958     pktdma_t *pktdma_p = pktdma_parray[unit];
    959 
    960     pktdma_p->desc_done_count_tx[12]++;
    961 }
    962 
    963 static void
    964 desc_done_intr_tx_13(int unit, dv_t *dv, dcb_t *dcb)
    965 {
    966     pktdma_t *pktdma_p = pktdma_parray[unit];
    967 
    968     pktdma_p->desc_done_count_tx[13]++;
    969 }
    970 
    971 static void
    972 desc_done_intr_tx_14(int unit, dv_t *dv, dcb_t *dcb)
    973 {
    974     pktdma_t *pktdma_p = pktdma_parray[unit];
    975 
    976     pktdma_p->desc_done_count_tx[14]++;
    977 }
    978 
    979 static void
    980 desc_done_intr_tx_15(int unit, dv_t *dv, dcb_t *dcb)
    981 {
    982     pktdma_t *pktdma_p = pktdma_parray[unit];
    983 
    984     pktdma_p->desc_done_count_tx[15]++;
    985 }
    986 
    987 
    988 /*
    989  * Functions:
    990  *      desc_done_intr_rx_0..15
    991  * Purpose:
    992  *      Interrupt level routine called from soc_dma_done_desc for RX descriptors
    993  *      for virtual channels 0..15.
    994  * Parameters:
    995  *      unit - StrataSwitch Unit #.
    996  *      dv - Descriptor vector raising interrupt
    997  *      dcb - Descriptor raising interrupt
    998  *
    999  * Returns:
   1000  *     Nothing
   1001  */
   1002 
   1003 static void
   1004 desc_done_intr_rx_0(int unit, dv_t *dv, dcb_t *dcb)
   1005 {
   1006     pktdma_t *pktdma_p = pktdma_parray[unit];
   1007 
   1008     pktdma_p->desc_done_count_rx[0]++;
   1009 }
   1010 
   1011 static void
   1012 desc_done_intr_rx_1(int unit, dv_t *dv, dcb_t *dcb)
   1013 {
   1014     pktdma_t *pktdma_p = pktdma_parray[unit];
   1015 
   1016     pktdma_p->desc_done_count_rx[1]++;
   1017 }
   1018 
   1019 static void
   1020 desc_done_intr_rx_2(int unit, dv_t *dv, dcb_t *dcb)
   1021 {
   1022     pktdma_t *pktdma_p = pktdma_parray[unit];
   1023 
   1024     pktdma_p->desc_done_count_rx[2]++;
   1025 }
   1026 
   1027 static void
   1028 desc_done_intr_rx_3(int unit, dv_t *dv, dcb_t *dcb)
   1029 {
   1030     pktdma_t *pktdma_p = pktdma_parray[unit];
   1031 
   1032     pktdma_p->desc_done_count_rx[3]++;
   1033 }
   1034 
   1035 static void
   1036 desc_done_intr_rx_4(int unit, dv_t *dv, dcb_t *dcb)
   1037 {
   1038     pktdma_t *pktdma_p = pktdma_parray[unit];
   1039 
   1040     pktdma_p->desc_done_count_rx[4]++;
   1041 }
   1042 
   1043 static void
   1044 desc_done_intr_rx_5(int unit, dv_t *dv, dcb_t *dcb)
   1045 {
   1046     pktdma_t *pktdma_p = pktdma_parray[unit];
   1047 
   1048     pktdma_p->desc_done_count_rx[5]++;
   1049 }
   1050 
   1051 static void
   1052 desc_done_intr_rx_6(int unit, dv_t *dv, dcb_t *dcb)
   1053 {
   1054     pktdma_t *pktdma_p = pktdma_parray[unit];
   1055 
   1056     pktdma_p->desc_done_count_rx[6]++;
   1057 }
   1058 
   1059 static void
   1060 desc_done_intr_rx_7(int unit, dv_t *dv, dcb_t *dcb)
   1061 {
   1062     pktdma_t *pktdma_p = pktdma_parray[unit];
   1063 
   1064     pktdma_p->desc_done_count_rx[7]++;
   1065 }
   1066 
   1067 static void
   1068 desc_done_intr_rx_8(int unit, dv_t *dv, dcb_t *dcb)
   1069 {
   1070     pktdma_t *pktdma_p = pktdma_parray[unit];
   1071 
   1072     pktdma_p->desc_done_count_rx[8]++;
   1073 }
   1074 
   1075 static void
   1076 desc_done_intr_rx_9(int unit, dv_t *dv, dcb_t *dcb)
   1077 {
   1078     pktdma_t *pktdma_p = pktdma_parray[unit];
   1079 
   1080     pktdma_p->desc_done_count_rx[9]++;
   1081 }
   1082 
   1083 static void
   1084 desc_done_intr_rx_10(int unit, dv_t *dv, dcb_t *dcb)
   1085 {
   1086     pktdma_t *pktdma_p = pktdma_parray[unit];
   1087 
   1088     pktdma_p->desc_done_count_rx[10]++;
   1089 }
   1090 
   1091 static void
   1092 desc_done_intr_rx_11(int unit, dv_t *dv, dcb_t *dcb)
   1093 {
   1094     pktdma_t *pktdma_p = pktdma_parray[unit];
   1095 
   1096     pktdma_p->desc_done_count_rx[11]++;
   1097 }
   1098 
   1099 static void
   1100 desc_done_intr_rx_12(int unit, dv_t *dv, dcb_t *dcb)
   1101 {
   1102     pktdma_t *pktdma_p = pktdma_parray[unit];
   1103 
   1104     pktdma_p->desc_done_count_rx[12]++;
   1105 }
   1106 
   1107 static void
   1108 desc_done_intr_rx_13(int unit, dv_t *dv, dcb_t *dcb)
   1109 {
   1110     pktdma_t *pktdma_p = pktdma_parray[unit];
   1111 
   1112     pktdma_p->desc_done_count_rx[13]++;
   1113 }
   1114 
   1115 static void
   1116 desc_done_intr_rx_14(int unit, dv_t *dv, dcb_t *dcb)
   1117 {
   1118     pktdma_t *pktdma_p = pktdma_parray[unit];
   1119 
   1120     pktdma_p->desc_done_count_rx[14]++;
   1121 }
   1122 
   1123 static void
   1124 desc_done_intr_rx_15(int unit, dv_t *dv, dcb_t *dcb)
   1125 {
   1126     pktdma_t *pktdma_p = pktdma_parray[unit];
   1127 
   1128     pktdma_p->desc_done_count_rx[15]++;
   1129 }
   1130 
   1131 
   1132 /*
   1133  * Functions:
   1134  *      chain_done_intr_tx_0..15
   1135  * Purpose:
   1136  *      Interrupt level routine called from soc_dma_done_chain for TX descriptors
   1137  *      for virtual channels 0..15.
   1138  * Parameters:
   1139  *      unit - StrataSwitch Unit #.
   1140  *      dv - Descriptor vector raising interrupt
   1141  *
   1142  * Returns:
   1143  *     Nothing
   1144  */
   1145 
   1146 static void
   1147 chain_done_intr_tx_0(int unit, dv_t *dv)
   1148 {
   1149     pktdma_t *pktdma_p = pktdma_parray[unit];
   1150 
   1151     pktdma_p->chain_done_count_tx[0]++;
   1152     pktdma_p->chain_done_tx[0] = 1;
   1153 }
   1154 
   1155 static void
   1156 chain_done_intr_tx_1(int unit, dv_t *dv)
   1157 {
   1158     pktdma_t *pktdma_p = pktdma_parray[unit];
   1159 
   1160     pktdma_p->chain_done_count_tx[1]++;
   1161     pktdma_p->chain_done_tx[1] = 1;
   1162 }
   1163 
   1164 static void
   1165 chain_done_intr_tx_2(int unit, dv_t *dv)
   1166 {
   1167     pktdma_t *pktdma_p = pktdma_parray[unit];
   1168 
   1169     pktdma_p->chain_done_count_tx[2]++;
   1170     pktdma_p->chain_done_tx[2] = 1;
   1171 }
   1172 
   1173 static void
   1174 chain_done_intr_tx_3(int unit, dv_t *dv)
   1175 {
   1176     pktdma_t *pktdma_p = pktdma_parray[unit];
   1177 
   1178     pktdma_p->chain_done_count_tx[3]++;
   1179     pktdma_p->chain_done_tx[3] = 1;
   1180 }
   1181 
   1182 static void
   1183 chain_done_intr_tx_4(int unit, dv_t *dv)
   1184 {
   1185     pktdma_t *pktdma_p = pktdma_parray[unit];
   1186 
   1187     pktdma_p->chain_done_count_tx[4]++;
   1188     pktdma_p->chain_done_tx[4] = 1;
   1189 }
   1190 
   1191 static void
   1192 chain_done_intr_tx_5(int unit, dv_t *dv)
   1193 {
   1194     pktdma_t *pktdma_p = pktdma_parray[unit];
   1195 
   1196     pktdma_p->chain_done_count_tx[5]++;
   1197     pktdma_p->chain_done_tx[5] = 1;
   1198 }
   1199 
   1200 static void
   1201 chain_done_intr_tx_6(int unit, dv_t *dv)
   1202 {
   1203     pktdma_t *pktdma_p = pktdma_parray[unit];
   1204 
   1205     pktdma_p->chain_done_count_tx[6]++;
   1206     pktdma_p->chain_done_tx[6] = 1;
   1207 }
   1208 
   1209 static void
   1210 chain_done_intr_tx_7(int unit, dv_t *dv)
   1211 {
   1212     pktdma_t *pktdma_p = pktdma_parray[unit];
   1213 
   1214     pktdma_p->chain_done_count_tx[7]++;
   1215     pktdma_p->chain_done_tx[7] = 1;
   1216 }
   1217 
   1218 static void
   1219 chain_done_intr_tx_8(int unit, dv_t *dv)
   1220 {
   1221     pktdma_t *pktdma_p = pktdma_parray[unit];
   1222 
   1223     pktdma_p->chain_done_count_tx[8]++;
   1224     pktdma_p->chain_done_tx[8] = 1;
   1225 }
   1226 
   1227 static void
   1228 chain_done_intr_tx_9(int unit, dv_t *dv)
   1229 {
   1230     pktdma_t *pktdma_p = pktdma_parray[unit];
   1231 
   1232     pktdma_p->chain_done_count_tx[9]++;
   1233     pktdma_p->chain_done_tx[9] = 1;
   1234 }
   1235 
   1236 static void
   1237 chain_done_intr_tx_10(int unit, dv_t *dv)
   1238 {
   1239     pktdma_t *pktdma_p = pktdma_parray[unit];
   1240 
   1241     pktdma_p->chain_done_count_tx[10]++;
   1242     pktdma_p->chain_done_tx[10] = 1;
   1243 }
   1244 
   1245 static void
   1246 chain_done_intr_tx_11(int unit, dv_t *dv)
   1247 {
   1248     pktdma_t *pktdma_p = pktdma_parray[unit];
   1249 
   1250     pktdma_p->chain_done_count_tx[11]++;
   1251     pktdma_p->chain_done_tx[11] = 1;
   1252 }
   1253 
   1254 static void
   1255 chain_done_intr_tx_12(int unit, dv_t *dv)
   1256 {
   1257     pktdma_t *pktdma_p = pktdma_parray[unit];
   1258 
   1259     pktdma_p->chain_done_count_tx[12]++;
   1260     pktdma_p->chain_done_tx[12] = 1;
   1261 }
   1262 
   1263 static void
   1264 chain_done_intr_tx_13(int unit, dv_t *dv)
   1265 {
   1266     pktdma_t *pktdma_p = pktdma_parray[unit];
   1267 
   1268     pktdma_p->chain_done_count_tx[13]++;
   1269     pktdma_p->chain_done_tx[13] = 1;
   1270 }
   1271 
   1272 static void
   1273 chain_done_intr_tx_14(int unit, dv_t *dv)
   1274 {
   1275     pktdma_t *pktdma_p = pktdma_parray[unit];
   1276 
   1277     pktdma_p->chain_done_count_tx[14]++;
   1278     pktdma_p->chain_done_tx[14] = 1;
   1279 }
   1280 
   1281 static void
   1282 chain_done_intr_tx_15(int unit, dv_t *dv)
   1283 {
   1284     pktdma_t *pktdma_p = pktdma_parray[unit];
   1285 
   1286     pktdma_p->chain_done_count_tx[15]++;
   1287     pktdma_p->chain_done_tx[15] = 1;
   1288 }
   1289 
   1290 /*
   1291  * Functions:
   1292  *      chain_done_intr_rx_0..15
   1293  * Purpose:
   1294  *      Interrupt level routine called from soc_dma_done_chain for RX descriptors
   1295  *      for virtual channels 0..15.
   1296  * Parameters:
   1297  *      unit - StrataSwitch Unit #.
   1298  *      dv - Descriptor vector raising interrupt
   1299  *
   1300  * Returns:
   1301  *     Nothing
   1302  */
   1303 
   1304 static void
   1305 chain_done_intr_rx_0(int unit, dv_t *dv)
   1306 {
   1307     pktdma_t *pktdma_p = pktdma_parray[unit];
   1308 
   1309     pktdma_p->chain_done_count_rx[0]++;
   1310     pktdma_p->chain_done_rx[0] = 1;
   1311 }
   1312 
   1313 static void
   1314 chain_done_intr_rx_1(int unit, dv_t *dv)
   1315 {
   1316     pktdma_t *pktdma_p = pktdma_parray[unit];
   1317 
   1318     pktdma_p->chain_done_count_rx[1]++;
   1319     pktdma_p->chain_done_rx[1] = 1;
   1320 }
   1321 
   1322 static void
   1323 chain_done_intr_rx_2(int unit, dv_t *dv)
   1324 {
   1325     pktdma_t *pktdma_p = pktdma_parray[unit];
   1326 
   1327     pktdma_p->chain_done_count_rx[2]++;
   1328     pktdma_p->chain_done_rx[2] = 1;
   1329 }
   1330 
   1331 static void
   1332 chain_done_intr_rx_3(int unit, dv_t *dv)
   1333 {
   1334     pktdma_t *pktdma_p = pktdma_parray[unit];
   1335 
   1336     pktdma_p->chain_done_count_rx[3]++;
   1337     pktdma_p->chain_done_rx[3] = 1;
   1338 }
   1339 
   1340 static void
   1341 chain_done_intr_rx_4(int unit, dv_t *dv)
   1342 {
   1343     pktdma_t *pktdma_p = pktdma_parray[unit];
   1344 
   1345     pktdma_p->chain_done_count_rx[4]++;
   1346     pktdma_p->chain_done_rx[4] = 1;
   1347 }
   1348 
   1349 static void
   1350 chain_done_intr_rx_5(int unit, dv_t *dv)
   1351 {
   1352     pktdma_t *pktdma_p = pktdma_parray[unit];
   1353 
   1354     pktdma_p->chain_done_count_rx[5]++;
   1355     pktdma_p->chain_done_rx[5] = 1;
   1356 }
   1357 
   1358 static void
   1359 chain_done_intr_rx_6(int unit, dv_t *dv)
   1360 {
   1361     pktdma_t *pktdma_p = pktdma_parray[unit];
   1362 
   1363     pktdma_p->chain_done_count_rx[6]++;
   1364     pktdma_p->chain_done_rx[6] = 1;
   1365 }
   1366 
   1367 static void
   1368 chain_done_intr_rx_7(int unit, dv_t *dv)
   1369 {
   1370     pktdma_t *pktdma_p = pktdma_parray[unit];
   1371 
   1372     pktdma_p->chain_done_count_rx[7]++;
   1373     pktdma_p->chain_done_rx[7] = 1;
   1374 }
   1375 
   1376 static void
   1377 chain_done_intr_rx_8(int unit, dv_t *dv)
   1378 {
   1379     pktdma_t *pktdma_p = pktdma_parray[unit];
   1380 
   1381     pktdma_p->chain_done_count_rx[8]++;
   1382     pktdma_p->chain_done_rx[8] = 1;
   1383 }
   1384 
   1385 static void
   1386 chain_done_intr_rx_9(int unit, dv_t *dv)
   1387 {
   1388     pktdma_t *pktdma_p = pktdma_parray[unit];
   1389 
   1390     pktdma_p->chain_done_count_rx[9]++;
   1391     pktdma_p->chain_done_rx[9] = 1;
   1392 }
   1393 
   1394 static void
   1395 chain_done_intr_rx_10(int unit, dv_t *dv)
   1396 {
   1397     pktdma_t *pktdma_p = pktdma_parray[unit];
   1398 
   1399     pktdma_p->chain_done_count_rx[10]++;
   1400     pktdma_p->chain_done_rx[10] = 1;
   1401 }
   1402 
   1403 static void
   1404 chain_done_intr_rx_11(int unit, dv_t *dv)
   1405 {
   1406     pktdma_t *pktdma_p = pktdma_parray[unit];
   1407 
   1408     pktdma_p->chain_done_count_rx[11]++;
   1409     pktdma_p->chain_done_rx[11] = 1;
   1410 }
   1411 
   1412 static void
   1413 chain_done_intr_rx_12(int unit, dv_t *dv)
   1414 {
   1415     pktdma_t *pktdma_p = pktdma_parray[unit];
   1416 
   1417     pktdma_p->chain_done_count_rx[12]++;
   1418     pktdma_p->chain_done_rx[12] = 1;
   1419 }
   1420 
   1421 static void
   1422 chain_done_intr_rx_13(int unit, dv_t *dv)
   1423 {
   1424     pktdma_t *pktdma_p = pktdma_parray[unit];
   1425 
   1426     pktdma_p->chain_done_count_rx[13]++;
   1427     pktdma_p->chain_done_rx[13] = 1;
   1428 }
   1429 
   1430 static void
   1431 chain_done_intr_rx_14(int unit, dv_t *dv)
   1432 {
   1433     pktdma_t *pktdma_p = pktdma_parray[unit];
   1434 
   1435     pktdma_p->chain_done_count_rx[14]++;
   1436     pktdma_p->chain_done_rx[14] = 1;
   1437 }
   1438 
   1439 static void
   1440 chain_done_intr_rx_15(int unit, dv_t *dv)
   1441 {
   1442     pktdma_t *pktdma_p = pktdma_parray[unit];
   1443 
   1444     pktdma_p->chain_done_count_rx[15]++;
   1445     pktdma_p->chain_done_rx[15] = 1;
   1446 }
   1447 
   1448 /*
   1449  * Functions:
   1450  *      reload_done_intr_tx_0..15
   1451  * Purpose:
   1452  *      Used only for continuous DMA.
   1453  *      Interrupt level routine called from soc_dma_done_desc for TX descriptors
   1454  *      for virtual channels 0..15, when the reload desc at the end of a desc
   1455  *      chain is done.
   1456  * Parameters:
   1457  *      unit - StrataSwitch Unit #.
   1458  *      dv - Descriptor vector raising interrupt
   1459  *
   1460  * Returns:
   1461  *     Nothing
   1462  */
   1463 
   1464 static void
   1465 reload_done_intr_tx_0(int unit, dv_t *dv)
   1466 {
   1467     pktdma_t *pktdma_p = pktdma_parray[unit];
   1468 
   1469     pktdma_p->reload_done_count_tx[0]++;
   1470     pktdma_p->reload_done_tx[0] = 1;
   1471 }
   1472 
   1473 static void
   1474 reload_done_intr_tx_1(int unit, dv_t *dv)
   1475 {
   1476     pktdma_t *pktdma_p = pktdma_parray[unit];
   1477 
   1478     pktdma_p->reload_done_count_tx[1]++;
   1479     pktdma_p->reload_done_tx[1] = 1;
   1480 }
   1481 
   1482 static void
   1483 reload_done_intr_tx_2(int unit, dv_t *dv)
   1484 {
   1485     pktdma_t *pktdma_p = pktdma_parray[unit];
   1486 
   1487     pktdma_p->reload_done_count_tx[2]++;
   1488     pktdma_p->reload_done_tx[2] = 1;
   1489 }
   1490 
   1491 static void
   1492 reload_done_intr_tx_3(int unit, dv_t *dv)
   1493 {
   1494     pktdma_t *pktdma_p = pktdma_parray[unit];
   1495 
   1496     pktdma_p->reload_done_count_tx[3]++;
   1497     pktdma_p->reload_done_tx[3] = 1;
   1498 }
   1499 
   1500 static void
   1501 reload_done_intr_tx_4(int unit, dv_t *dv)
   1502 {
   1503     pktdma_t *pktdma_p = pktdma_parray[unit];
   1504 
   1505     pktdma_p->reload_done_count_tx[4]++;
   1506     pktdma_p->reload_done_tx[4] = 1;
   1507 }
   1508 
   1509 static void
   1510 reload_done_intr_tx_5(int unit, dv_t *dv)
   1511 {
   1512     pktdma_t *pktdma_p = pktdma_parray[unit];
   1513 
   1514     pktdma_p->reload_done_count_tx[5]++;
   1515     pktdma_p->reload_done_tx[5] = 1;
   1516 }
   1517 
   1518 static void
   1519 reload_done_intr_tx_6(int unit, dv_t *dv)
   1520 {
   1521     pktdma_t *pktdma_p = pktdma_parray[unit];
   1522 
   1523     pktdma_p->reload_done_count_tx[6]++;
   1524     pktdma_p->reload_done_tx[6] = 1;
   1525 }
   1526 
   1527 static void
   1528 reload_done_intr_tx_7(int unit, dv_t *dv)
   1529 {
   1530     pktdma_t *pktdma_p = pktdma_parray[unit];
   1531 
   1532     pktdma_p->reload_done_count_tx[7]++;
   1533     pktdma_p->reload_done_tx[7] = 1;
   1534 }
   1535 
   1536 static void
   1537 reload_done_intr_tx_8(int unit, dv_t *dv)
   1538 {
   1539     pktdma_t *pktdma_p = pktdma_parray[unit];
   1540 
   1541     pktdma_p->reload_done_count_tx[8]++;
   1542     pktdma_p->reload_done_tx[8] = 1;
   1543 }
   1544 
   1545 static void
   1546 reload_done_intr_tx_9(int unit, dv_t *dv)
   1547 {
   1548     pktdma_t *pktdma_p = pktdma_parray[unit];
   1549 
   1550     pktdma_p->reload_done_count_tx[9]++;
   1551     pktdma_p->reload_done_tx[9] = 1;
   1552 }
   1553 
   1554 static void
   1555 reload_done_intr_tx_10(int unit, dv_t *dv)
   1556 {
   1557     pktdma_t *pktdma_p = pktdma_parray[unit];
   1558 
   1559     pktdma_p->reload_done_count_tx[10]++;
   1560     pktdma_p->reload_done_tx[10] = 1;
   1561 }
   1562 
   1563 static void
   1564 reload_done_intr_tx_11(int unit, dv_t *dv)
   1565 {
   1566     pktdma_t *pktdma_p = pktdma_parray[unit];
   1567 
   1568     pktdma_p->reload_done_count_tx[11]++;
   1569     pktdma_p->reload_done_tx[11] = 1;
   1570 }
   1571 
   1572 static void
   1573 reload_done_intr_tx_12(int unit, dv_t *dv)
   1574 {
   1575     pktdma_t *pktdma_p = pktdma_parray[unit];
   1576 
   1577     pktdma_p->reload_done_count_tx[12]++;
   1578     pktdma_p->reload_done_tx[12] = 1;
   1579 }
   1580 
   1581 static void
   1582 reload_done_intr_tx_13(int unit, dv_t *dv)
   1583 {
   1584     pktdma_t *pktdma_p = pktdma_parray[unit];
   1585 
   1586     pktdma_p->reload_done_count_tx[13]++;
   1587     pktdma_p->reload_done_tx[13] = 1;
   1588 }
   1589 
   1590 static void
   1591 reload_done_intr_tx_14(int unit, dv_t *dv)
   1592 {
   1593     pktdma_t *pktdma_p = pktdma_parray[unit];
   1594 
   1595     pktdma_p->reload_done_count_tx[14]++;
   1596     pktdma_p->reload_done_tx[14] = 1;
   1597 }
   1598 
   1599 static void
   1600 reload_done_intr_tx_15(int unit, dv_t *dv)
   1601 {
   1602     pktdma_t *pktdma_p = pktdma_parray[unit];
   1603 
   1604     pktdma_p->reload_done_count_tx[15]++;
   1605     pktdma_p->reload_done_tx[15] = 1;
   1606 }
   1607 
   1608 
   1609 /*
   1610  * Functions:
   1611  *      reload_done_intr_rx_0..15
   1612  * Purpose:
   1613  *      Used only for continuous DMA.
   1614  *      Interrupt level routine called from soc_dma_done_desc for RX descriptors
   1615  *      for virtual channels 0..15, when the reload desc at the end of a desc
   1616  *      chain is done.
   1617  * Parameters:
   1618  *      unit - StrataSwitch Unit #.
   1619  *      dv - Descriptor vector raising interrupt
   1620  *
   1621  * Returns:
   1622  *     Nothing
   1623  */
   1624 
   1625 static void
   1626 reload_done_intr_rx_0(int unit, dv_t *dv)
   1627 {
   1628     pktdma_t *pktdma_p = pktdma_parray[unit];
   1629 
   1630     pktdma_p->reload_done_count_rx[0]++;
   1631     pktdma_p->reload_done_rx[0] = 1;
   1632 }
   1633 
   1634 static void
   1635 reload_done_intr_rx_1(int unit, dv_t *dv)
   1636 {
   1637     pktdma_t *pktdma_p = pktdma_parray[unit];
   1638 
   1639     pktdma_p->reload_done_count_rx[1]++;
   1640     pktdma_p->reload_done_rx[1] = 1;
   1641 }
   1642 
   1643 static void
   1644 reload_done_intr_rx_2(int unit, dv_t *dv)
   1645 {
   1646     pktdma_t *pktdma_p = pktdma_parray[unit];
   1647 
   1648     pktdma_p->reload_done_count_rx[2]++;
   1649     pktdma_p->reload_done_rx[2] = 1;
   1650 }
   1651 
   1652 static void
   1653 reload_done_intr_rx_3(int unit, dv_t *dv)
   1654 {
   1655     pktdma_t *pktdma_p = pktdma_parray[unit];
   1656 
   1657     pktdma_p->reload_done_count_rx[3]++;
   1658     pktdma_p->reload_done_rx[3] = 1;
   1659 }
   1660 
   1661 static void
   1662 reload_done_intr_rx_4(int unit, dv_t *dv)
   1663 {
   1664     pktdma_t *pktdma_p = pktdma_parray[unit];
   1665 
   1666     pktdma_p->reload_done_count_rx[4]++;
   1667     pktdma_p->reload_done_rx[4] = 1;
   1668 }
   1669 
   1670 static void
   1671 reload_done_intr_rx_5(int unit, dv_t *dv)
   1672 {
   1673     pktdma_t *pktdma_p = pktdma_parray[unit];
   1674 
   1675     pktdma_p->reload_done_count_rx[5]++;
   1676     pktdma_p->reload_done_rx[5] = 1;
   1677 }
   1678 
   1679 static void
   1680 reload_done_intr_rx_6(int unit, dv_t *dv)
   1681 {
   1682     pktdma_t *pktdma_p = pktdma_parray[unit];
   1683 
   1684     pktdma_p->reload_done_count_rx[6]++;
   1685     pktdma_p->reload_done_rx[6] = 1;
   1686 }
   1687 
   1688 static void
   1689 reload_done_intr_rx_7(int unit, dv_t *dv)
   1690 {
   1691     pktdma_t *pktdma_p = pktdma_parray[unit];
   1692 
   1693     pktdma_p->reload_done_count_rx[7]++;
   1694     pktdma_p->reload_done_rx[7] = 1;
   1695 }
   1696 
   1697 static void
   1698 reload_done_intr_rx_8(int unit, dv_t *dv)
   1699 {
   1700     pktdma_t *pktdma_p = pktdma_parray[unit];
   1701 
   1702     pktdma_p->reload_done_count_rx[8]++;
   1703     pktdma_p->reload_done_rx[8] = 1;
   1704 }
   1705 
   1706 static void
   1707 reload_done_intr_rx_9(int unit, dv_t *dv)
   1708 {
   1709     pktdma_t *pktdma_p = pktdma_parray[unit];
   1710 
   1711     pktdma_p->reload_done_count_rx[9]++;
   1712     pktdma_p->reload_done_rx[9] = 1;
   1713 }
   1714 
   1715 static void
   1716 reload_done_intr_rx_10(int unit, dv_t *dv)
   1717 {
   1718     pktdma_t *pktdma_p = pktdma_parray[unit];
   1719 
   1720     pktdma_p->reload_done_count_rx[10]++;
   1721     pktdma_p->reload_done_rx[10] = 1;
   1722 }
   1723 
   1724 static void
   1725 reload_done_intr_rx_11(int unit, dv_t *dv)
   1726 {
   1727     pktdma_t *pktdma_p = pktdma_parray[unit];
   1728 
   1729     pktdma_p->reload_done_count_rx[11]++;
   1730     pktdma_p->reload_done_rx[11] = 1;
   1731 }
   1732 
   1733 static void
   1734 reload_done_intr_rx_12(int unit, dv_t *dv)
   1735 {
   1736     pktdma_t *pktdma_p = pktdma_parray[unit];
   1737 
   1738     pktdma_p->reload_done_count_rx[12]++;
   1739     pktdma_p->reload_done_rx[12] = 1;
   1740 }
   1741 
   1742 static void
   1743 reload_done_intr_rx_13(int unit, dv_t *dv)
   1744 {
   1745     pktdma_t *pktdma_p = pktdma_parray[unit];
   1746 
   1747     pktdma_p->reload_done_count_rx[13]++;
   1748     pktdma_p->reload_done_rx[13] = 1;
   1749 }
   1750 
   1751 static void
   1752 reload_done_intr_rx_14(int unit, dv_t *dv)
   1753 {
   1754     pktdma_t *pktdma_p = pktdma_parray[unit];
   1755 
   1756     pktdma_p->reload_done_count_rx[14]++;
   1757     pktdma_p->reload_done_rx[14] = 1;
   1758 }
   1759 
   1760 static void
   1761 reload_done_intr_rx_15(int unit, dv_t *dv)
   1762 {
   1763     pktdma_t *pktdma_p = pktdma_parray[unit];
   1764 
   1765     pktdma_p->reload_done_count_rx[15]++;
   1766     pktdma_p->reload_done_rx[15] = 1;
   1767 }
   1768 
   1769 /*
   1770  * Function:
   1771  *      set_up_isr_table
   1772  * Purpose:
   1773  *      Sets up interrupt related function pointers in test struct.
   1774  * Parameters:
   1775  *      unit - StrataSwitch Unit #.
   1776  *
   1777  * Returns:
   1778  *     Nothing
   1779  */
   1780 
   1781 static void
   1782 set_up_isr_table(int unit)
   1783 {
   1784     pktdma_t *pktdma_p = pktdma_parray[unit];
   1785 
   1786     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\nSetting up ISR table")));
   1787     pktdma_p->desc_done_intr_tx_table[0] = &desc_done_intr_tx_0;
   1788     pktdma_p->desc_done_intr_tx_table[1] = &desc_done_intr_tx_1;
   1789     pktdma_p->desc_done_intr_tx_table[2] = &desc_done_intr_tx_2;
   1790     pktdma_p->desc_done_intr_tx_table[3] = &desc_done_intr_tx_3;
   1791     pktdma_p->desc_done_intr_tx_table[4] = &desc_done_intr_tx_4;
   1792     pktdma_p->desc_done_intr_tx_table[5] = &desc_done_intr_tx_5;
   1793     pktdma_p->desc_done_intr_tx_table[6] = &desc_done_intr_tx_6;
   1794     pktdma_p->desc_done_intr_tx_table[7] = &desc_done_intr_tx_7;
   1795     pktdma_p->desc_done_intr_tx_table[8] = &desc_done_intr_tx_8;
   1796     pktdma_p->desc_done_intr_tx_table[9] = &desc_done_intr_tx_9;
   1797     pktdma_p->desc_done_intr_tx_table[10] = &desc_done_intr_tx_10;
   1798     pktdma_p->desc_done_intr_tx_table[11] = &desc_done_intr_tx_11;
   1799     pktdma_p->desc_done_intr_tx_table[12] = &desc_done_intr_tx_12;
   1800     pktdma_p->desc_done_intr_tx_table[13] = &desc_done_intr_tx_13;
   1801     pktdma_p->desc_done_intr_tx_table[14] = &desc_done_intr_tx_14;
   1802     pktdma_p->desc_done_intr_tx_table[15] = &desc_done_intr_tx_15;
   1803 
   1804     pktdma_p->desc_done_intr_rx_table[0] = &desc_done_intr_rx_0;
   1805     pktdma_p->desc_done_intr_rx_table[1] = &desc_done_intr_rx_1;
   1806     pktdma_p->desc_done_intr_rx_table[2] = &desc_done_intr_rx_2;
   1807     pktdma_p->desc_done_intr_rx_table[3] = &desc_done_intr_rx_3;
   1808     pktdma_p->desc_done_intr_rx_table[4] = &desc_done_intr_rx_4;
   1809     pktdma_p->desc_done_intr_rx_table[5] = &desc_done_intr_rx_5;
   1810     pktdma_p->desc_done_intr_rx_table[6] = &desc_done_intr_rx_6;
   1811     pktdma_p->desc_done_intr_rx_table[7] = &desc_done_intr_rx_7;
   1812     pktdma_p->desc_done_intr_rx_table[8] = &desc_done_intr_rx_8;
   1813     pktdma_p->desc_done_intr_rx_table[9] = &desc_done_intr_rx_9;
   1814     pktdma_p->desc_done_intr_rx_table[10] = &desc_done_intr_rx_10;
   1815     pktdma_p->desc_done_intr_rx_table[11] = &desc_done_intr_rx_11;
   1816     pktdma_p->desc_done_intr_rx_table[12] = &desc_done_intr_rx_12;
   1817     pktdma_p->desc_done_intr_rx_table[13] = &desc_done_intr_rx_13;
   1818     pktdma_p->desc_done_intr_rx_table[14] = &desc_done_intr_rx_14;
   1819     pktdma_p->desc_done_intr_rx_table[15] = &desc_done_intr_rx_15;
   1820 
   1821     pktdma_p->chain_done_intr_tx_table[0] = &chain_done_intr_tx_0;
   1822     pktdma_p->chain_done_intr_tx_table[1] = &chain_done_intr_tx_1;
   1823     pktdma_p->chain_done_intr_tx_table[2] = &chain_done_intr_tx_2;
   1824     pktdma_p->chain_done_intr_tx_table[3] = &chain_done_intr_tx_3;
   1825     pktdma_p->chain_done_intr_tx_table[4] = &chain_done_intr_tx_4;
   1826     pktdma_p->chain_done_intr_tx_table[5] = &chain_done_intr_tx_5;
   1827     pktdma_p->chain_done_intr_tx_table[6] = &chain_done_intr_tx_6;
   1828     pktdma_p->chain_done_intr_tx_table[7] = &chain_done_intr_tx_7;
   1829     pktdma_p->chain_done_intr_tx_table[8] = &chain_done_intr_tx_8;
   1830     pktdma_p->chain_done_intr_tx_table[9] = &chain_done_intr_tx_9;
   1831     pktdma_p->chain_done_intr_tx_table[10] = &chain_done_intr_tx_10;
   1832     pktdma_p->chain_done_intr_tx_table[11] = &chain_done_intr_tx_11;
   1833     pktdma_p->chain_done_intr_tx_table[12] = &chain_done_intr_tx_12;
   1834     pktdma_p->chain_done_intr_tx_table[13] = &chain_done_intr_tx_13;
   1835     pktdma_p->chain_done_intr_tx_table[14] = &chain_done_intr_tx_14;
   1836     pktdma_p->chain_done_intr_tx_table[15] = &chain_done_intr_tx_15;
   1837 
   1838     pktdma_p->chain_done_intr_rx_table[0] = &chain_done_intr_rx_0;
   1839     pktdma_p->chain_done_intr_rx_table[1] = &chain_done_intr_rx_1;
   1840     pktdma_p->chain_done_intr_rx_table[2] = &chain_done_intr_rx_2;
   1841     pktdma_p->chain_done_intr_rx_table[3] = &chain_done_intr_rx_3;
   1842     pktdma_p->chain_done_intr_rx_table[4] = &chain_done_intr_rx_4;
   1843     pktdma_p->chain_done_intr_rx_table[5] = &chain_done_intr_rx_5;
   1844     pktdma_p->chain_done_intr_rx_table[6] = &chain_done_intr_rx_6;
   1845     pktdma_p->chain_done_intr_rx_table[7] = &chain_done_intr_rx_7;
   1846     pktdma_p->chain_done_intr_rx_table[8] = &chain_done_intr_rx_8;
   1847     pktdma_p->chain_done_intr_rx_table[9] = &chain_done_intr_rx_9;
   1848     pktdma_p->chain_done_intr_rx_table[10] = &chain_done_intr_rx_10;
   1849     pktdma_p->chain_done_intr_rx_table[11] = &chain_done_intr_rx_11;
   1850     pktdma_p->chain_done_intr_rx_table[12] = &chain_done_intr_rx_12;
   1851     pktdma_p->chain_done_intr_rx_table[13] = &chain_done_intr_rx_13;
   1852     pktdma_p->chain_done_intr_rx_table[14] = &chain_done_intr_rx_14;
   1853     pktdma_p->chain_done_intr_rx_table[15] = &chain_done_intr_rx_15;
   1854 
   1855     pktdma_p->reload_done_intr_tx_table[0] = &reload_done_intr_tx_0;
   1856     pktdma_p->reload_done_intr_tx_table[1] = &reload_done_intr_tx_1;
   1857     pktdma_p->reload_done_intr_tx_table[2] = &reload_done_intr_tx_2;
   1858     pktdma_p->reload_done_intr_tx_table[3] = &reload_done_intr_tx_3;
   1859     pktdma_p->reload_done_intr_tx_table[4] = &reload_done_intr_tx_4;
   1860     pktdma_p->reload_done_intr_tx_table[5] = &reload_done_intr_tx_5;
   1861     pktdma_p->reload_done_intr_tx_table[6] = &reload_done_intr_tx_6;
   1862     pktdma_p->reload_done_intr_tx_table[7] = &reload_done_intr_tx_7;
   1863     pktdma_p->reload_done_intr_tx_table[8] = &reload_done_intr_tx_8;
   1864     pktdma_p->reload_done_intr_tx_table[9] = &reload_done_intr_tx_9;
   1865     pktdma_p->reload_done_intr_tx_table[10] = &reload_done_intr_tx_10;
   1866     pktdma_p->reload_done_intr_tx_table[11] = &reload_done_intr_tx_11;
   1867     pktdma_p->reload_done_intr_tx_table[12] = &reload_done_intr_tx_12;
   1868     pktdma_p->reload_done_intr_tx_table[13] = &reload_done_intr_tx_13;
   1869     pktdma_p->reload_done_intr_tx_table[14] = &reload_done_intr_tx_14;
   1870     pktdma_p->reload_done_intr_tx_table[15] = &reload_done_intr_tx_15;
   1871 
   1872     pktdma_p->reload_done_intr_rx_table[0] = &reload_done_intr_rx_0;
   1873     pktdma_p->reload_done_intr_rx_table[1] = &reload_done_intr_rx_1;
   1874     pktdma_p->reload_done_intr_rx_table[2] = &reload_done_intr_rx_2;
   1875     pktdma_p->reload_done_intr_rx_table[3] = &reload_done_intr_rx_3;
   1876     pktdma_p->reload_done_intr_rx_table[4] = &reload_done_intr_rx_4;
   1877     pktdma_p->reload_done_intr_rx_table[5] = &reload_done_intr_rx_5;
   1878     pktdma_p->reload_done_intr_rx_table[6] = &reload_done_intr_rx_6;
   1879     pktdma_p->reload_done_intr_rx_table[7] = &reload_done_intr_rx_7;
   1880     pktdma_p->reload_done_intr_rx_table[8] = &reload_done_intr_rx_8;
   1881     pktdma_p->reload_done_intr_rx_table[9] = &reload_done_intr_rx_9;
   1882     pktdma_p->reload_done_intr_rx_table[10] = &reload_done_intr_rx_10;
   1883     pktdma_p->reload_done_intr_rx_table[11] = &reload_done_intr_rx_11;
   1884     pktdma_p->reload_done_intr_rx_table[12] = &reload_done_intr_rx_12;
   1885     pktdma_p->reload_done_intr_rx_table[13] = &reload_done_intr_rx_13;
   1886     pktdma_p->reload_done_intr_rx_table[14] = &reload_done_intr_rx_14;
   1887     pktdma_p->reload_done_intr_rx_table[15] = &reload_done_intr_rx_15;
   1888 
   1889 }
   1890 
   1891 /*
   1892  * Function:
   1893  *      set_global_desc_attr
   1894  * Purpose:
   1895  *      Sets variables in test struct for desc_attributes. Sets chain_tx,
   1896  *      chain_rx (For chaining), sg_tx, sg_rx (Scatter/Gather) and reload_tx,
   1897  *      reload_rx (Chain has reload desc at the end).
   1898  * Parameters:
   1899  *      unit - StrataSwitch Unit #.
   1900  *
   1901  * Returns:
   1902  *     Nothing
   1903  */
   1904 
   1905 static void
   1906 set_global_desc_attr(int unit)
   1907 {
   1908     pktdma_t *pktdma_p = pktdma_parray[unit];
   1909 
   1910     LOG_INFO(BSL_LS_APPL_TESTS,
   1911              (BSL_META_U(unit, "\nSetting global attributes")));
   1912 
   1913     pktdma_p->chain_tx = (pktdma_p->test_type_param_tx == DESC_TX_SINGLE_PKT
   1914                           || pktdma_p->test_type_param_tx ==
   1915                           DESC_TX_SINGLE_PKT_SPLIT) ? 0 : 1;
   1916     pktdma_p->sg_tx = (pktdma_p->test_type_param_tx == DESC_TX_SINGLE_PKT_SPLIT
   1917                        || pktdma_p->test_type_param_tx ==
   1918                        DESC_TX_CHAIN_PKT_SPLIT) ? 1 : 0;
   1919     pktdma_p->reload_tx =
   1920         (pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD) ? 1 : 0;
   1921 
   1922     pktdma_p->chain_rx = (pktdma_p->test_type_param_rx == DESC_RX_SINGLE_PKT
   1923                           || pktdma_p->test_type_param_rx ==
   1924                           DESC_RX_SINGLE_PKT_SPLIT) ? 0 : 1;
   1925     pktdma_p->sg_rx = (pktdma_p->test_type_param_rx == DESC_RX_SINGLE_PKT_SPLIT
   1926                        || pktdma_p->test_type_param_rx ==
   1927                        DESC_RX_CHAIN_PKT_SPLIT) ? 1 : 0;
   1928     pktdma_p->reload_rx =
   1929         (pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) ? 1 : 0;
   1930 }
   1931 
   1932 /*
   1933  * Function:
   1934  *      set_up_dv
   1935  * Purpose:
   1936  *      Sets up DV arrays based on input params.
   1937  * Parameters:
   1938  *      unit - StrataSwitch Unit #.
   1939  *      dv_array - Array of DV pointers (dv_t*).
   1940  *      dv_type - DV type (TX or RX).
   1941  *      chain - Chaining enabled if chain is 1
   1942  *      sg - Scatter/Gather, split each pkt into 2 descriptors if sg is 1
   1943  *      reload - Last desc in chain is a reload desc if set to 1
   1944  *      poll_intr - Set to 0 for polling, 1 for chain_done interrupts, 0 for
   1945  *                  desc_done interrupts.
   1946  *      channel - Virtual channel number (0..11)
   1947  *      pkt_array - 2D array of packet pointers generated by store_l2_packets
   1948  *      pkt_size - Packet size in bytes
   1949  *      num_pkts - Number of packets in DV array
   1950  *      random_packet_sizes - Random packet size array created by store_l2_packets
   1951  *      source_ch - source_ch_array
   1952  *      cont_dma - 1 of cont_dma is enabled
   1953  * Returns:
   1954  *     Nothing
   1955  */
   1956 
   1957 static void
   1958 set_up_dv(int unit, dv_t **dv_array, dvt_t dv_type, uint32 chain,
   1959           uint32 sg, uint32 reload, uint32 poll_intr, uint32 channel,
   1960           uint8 ***pkt_array, uint32 pkt_size, uint32 num_pkts,
   1961           uint32 **random_packet_sizes, uint32 *source_ch, uint32 cont_dma)
   1962 {
   1963     pktdma_t *pktdma_p = pktdma_parray[unit];
   1964     pbmp_t lp_pbm, empty_pbm0, empty_pbm1;
   1965     int32 i;
   1966     uint32 dma_bytes;
   1967     uint32 pkt_size_test = 0;
   1968     int32 flags = 0;
   1969     dv_t *dv = 0;
   1970     int32 dv_num = 0;
   1971     int32 prefetch = 0;
   1972 
   1973     BCM_PBMP_CLEAR(lp_pbm);
   1974     BCM_PBMP_CLEAR(empty_pbm0);
   1975     BCM_PBMP_CLEAR(empty_pbm1);
   1976     BCM_PBMP_PORT_ADD(lp_pbm, 1);
   1977 
   1978     for (i = 0; i < num_pkts; i++) {
   1979         dv = dv_array[dv_num];
   1980 
   1981         if (pkt_size == 0) {
   1982             if (dv_type == DV_TX) {
   1983                 pkt_size_test = random_packet_sizes[channel][i];
   1984             } else if (dv_type == DV_RX) {
   1985                 pkt_size_test = pktdma_p->max_pkt_size_param;
   1986             }
   1987         } else {
   1988             pkt_size_test = pkt_size;
   1989         }
   1990 
   1991         if (dv_type == DV_RX) {
   1992             pkt_size_test += pktdma_p->header_offset;
   1993         }
   1994 
   1995         if (sg == 0) {
   1996             dma_bytes = pkt_size_test;
   1997         } else {
   1998             /* coverity[dont_call : FALSE] */
   1999             dma_bytes = ((sal_rand() % ((pkt_size_test / 4) - 4)) * 4) + 4;
   2000         }
   2001 
   2002         soc_dma_desc_add(dv, (sal_vaddr_t) (pkt_array[channel][i]), dma_bytes,
   2003                          lp_pbm, empty_pbm0, empty_pbm1, flags, NULL);
   2004         if (sg == 1) {
   2005             soc_dma_desc_add(dv,
   2006                              (sal_vaddr_t) (pkt_array[channel][i] + dma_bytes),
   2007                              pkt_size_test - dma_bytes, lp_pbm, empty_pbm0,
   2008                              empty_pbm1, flags, NULL);
   2009         }
   2010         soc_dma_desc_end_packet(dv);
   2011         if (poll_intr == POLL) {
   2012             flags = 0;
   2013         } else if (poll_intr == CHAIN_DONE_INTR_ONLY) {
   2014             flags |= DV_F_NOTIFY_CHN;
   2015         } else {
   2016             flags |= DV_F_NOTIFY_DSC;
   2017             flags |= DV_F_NOTIFY_CHN;
   2018         }
   2019         dv->dv_flags = flags;
   2020 
   2021         if (dv_type == DV_TX) {
   2022             dv->dv_done_desc = pktdma_p->desc_done_intr_tx_table[channel];
   2023             dv->dv_done_chain = pktdma_p->chain_done_intr_tx_table[channel];
   2024             dv->dv_done_reload = pktdma_p->reload_done_intr_tx_table[channel];
   2025         } else {
   2026             dv->dv_done_desc = pktdma_p->desc_done_intr_rx_table[channel];
   2027             dv->dv_done_chain = pktdma_p->chain_done_intr_rx_table[channel];
   2028             dv->dv_done_reload = pktdma_p->reload_done_intr_rx_table[channel];
   2029         }
   2030         if (chain == 0) {
   2031             dv_num++;
   2032         }
   2033     }
   2034     if (cont_dma == 1) {
   2035         soc_dma_rld_desc_add(dv, 0);
   2036         SOC_DCB_CHAIN_SET(unit,
   2037                           SOC_DCB_IDX2PTR(unit, dv->dv_dcb, dv->dv_vcnt - 1),
   2038                           1);
   2039         prefetch = 1;
   2040     } else if (reload == 1) {
   2041         soc_dma_rld_desc_add(dv, (sal_vaddr_t) dv->dv_dcb);
   2042         SOC_DCB_CHAIN_SET(unit,
   2043                           SOC_DCB_IDX2PTR(unit, dv->dv_dcb, dv->dv_vcnt - 1),
   2044                           1);
   2045         prefetch = 1;
   2046     }
   2047 
   2048     if (!prefetch) {
   2049         soc_dma_contiguous_desc_add(dv);
   2050     }
   2051 }
   2052 
   2053 /*
   2054  * Function:
   2055  *      config_dma_chan
   2056  * Purpose:
   2057  *      Calls soc_dma_chan_config to configure DMA channels
   2058  * Parameters:
   2059  *      unit - StrataSwitch Unit #.
   2060  *      tx_bitmap - 12-bit bitmap of virtual channels enabled for TX
   2061  *      rx_bitmap - 12-bit bitmap of virtual channels enabled for RX
   2062  *      poll_intr - Set to 0 for polling, 1 for chain done interrupts only and
   2063                     2 for both desc and chain done interrupts
   2064  * Returns:
   2065  *     Nothing
   2066  */
   2067 
   2068 static void
   2069 config_dma_chan(int unit, uint32 tx_bitmap, uint32 rx_bitmap, uint32 poll_intr)
   2070 {
   2071     int32 channel;
   2072 
   2073     LOG_INFO(BSL_LS_APPL_TESTS,
   2074              (BSL_META_U(unit, "\nCalling config_dma_chan")));
   2075     for (channel = 0; channel < MAX_CHANNELS; channel++) {
   2076         if (((tx_bitmap >> channel) % 2) != 0) {
   2077             if (poll_intr != POLL) {
   2078                 cli_out("\nConfiguring TX DMA channel %0d for interrupts",
   2079                         channel);
   2080                 (void) soc_dma_chan_config(unit, channel, DV_TX, SOC_DMA_F_INTR);
   2081             } else {
   2082                 cli_out("\nConfiguring TX DMA channel %0d for polling",
   2083                         channel);
   2084                 (void) soc_dma_chan_config(unit, channel, DV_TX, SOC_DMA_F_POLL);
   2085             }
   2086         } else if (((rx_bitmap >> channel) % 2) != 0) {
   2087             if (poll_intr != POLL) {
   2088                 cli_out("\nConfiguring RX DMA channel %0d for interrupts",
   2089                         channel);
   2090                 (void) soc_dma_chan_config(unit, channel, DV_RX, SOC_DMA_F_INTR);
   2091             } else {
   2092                 cli_out("\nConfiguring RX DMA channel %0d for polling",
   2093                         channel);
   2094                 (void) soc_dma_chan_config(unit, channel, DV_RX, SOC_DMA_F_POLL);
   2095             }
   2096         }
   2097     }
   2098 }
   2099 
   2100 /*
   2101  * Function:
   2102  *      soc_check_cont_dma_in_halt
   2103  * Purpose:
   2104  *      Check DMA_STAT_HI register to see if channel is halted - used for
   2105  *      continuous DMA
   2106  * Parameters:
   2107  *      unit - StrataSwitch Unit #.
   2108  *      vchan - Virtual channel number
   2109  *      detected - whether desc done or chain done was detected
   2110  *
   2111  * Returns:
   2112  *    Nothing
   2113  */
   2114 
   2115 static void
   2116 soc_check_cont_dma_in_halt(int unit, int32 vchan, int32 *detected)
   2117 {
   2118     int32 halt;
   2119 
   2120     soc_dma_chan_halt_get(unit, vchan, 0x1, &halt);
   2121 
   2122     *detected = 0;
   2123 
   2124     if (halt != 0) {
   2125         *detected = 1;
   2126     }
   2127 }
   2128 
   2129 /*
   2130  * Function:
   2131  *      txdma_thread
   2132  * Purpose:
   2133  *      TX DMA thread - one thread takes care of all active channels
   2134  * Parameters:
   2135  *      up - Pointer to StrataSwitch Unit #.
   2136  *
   2137  * Returns:
   2138  *     Nothing
   2139  */
   2140 
   2141 static void
   2142 txdma_thread(void *up)
   2143 {
   2144     int unit = PTR_TO_INT(up);
   2145     uint32 performance_test = 0;
   2146     int32 first_time[MAX_CHANNELS];
   2147     int32 channel;
   2148     int32 dv_num[MAX_CHANNELS];
   2149     int32 channel_all_dv_done[MAX_CHANNELS];
   2150     int32 poll_chain_done_detected = 0;
   2151     int32 all_channels_done = 0;
   2152     int32 dv_cont[MAX_CHANNELS];
   2153     sal_usecs_t time_curr = 0, time_prev = 0, time_cost = 0;
   2154     uint32 reset_dv = 1;
   2155 
   2156     pktdma_t *pktdma_p = pktdma_parray[unit];
   2157 
   2158     if ((pktdma_p->stream_param_tx == 1)
   2159         || (pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD)) {
   2160         performance_test = 1;
   2161     } else {
   2162         performance_test = 0;
   2163     }
   2164     if (pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD ||
   2165         pktdma_p->stream_param_tx == 0) {
   2166         reset_dv = 0;
   2167     }
   2168 
   2169     for (channel = 0; channel < MAX_CHANNELS; channel++) {
   2170         first_time[channel] = 1;
   2171         dv_cont[channel] = 0;
   2172         dv_num[channel] = 0;
   2173         channel_all_dv_done[channel] = 0;
   2174     }
   2175 
   2176     if (pktdma_p->cpu_time_cost_param != 0) {
   2177         time_curr = sal_time_usecs();
   2178     }
   2179 
   2180     do {
   2181         for (channel = 0; channel < MAX_CHANNELS; channel++) {
   2182             if (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0) {
   2183                 if (channel_all_dv_done[channel] == 0 || performance_test) {
   2184                     if (performance_test && channel_all_dv_done[channel] == 1) {
   2185                         channel_all_dv_done[channel] = 0;
   2186                         dv_num[channel] = 0;
   2187                         if (pktdma_p->cont_dma == 1) {
   2188                             dv_cont[channel]++;
   2189                             dv_cont[channel] =
   2190                                 dv_cont[channel] % NUM_CONT_DMA_DV;
   2191                         }
   2192                     }
   2193                     if ((pktdma_p->poll_intr_param == POLL || pktdma_p->cont_dma)
   2194                         && (first_time[channel] == 0)
   2195                         && (pktdma_p->test_type_param_tx != DESC_TX_CHAIN_PKT_RELOAD)) {
   2196                         if (pktdma_p->cont_dma) {
   2197                             soc_check_cont_dma_in_halt(unit, channel,
   2198                                                        &poll_chain_done_detected);
   2199                         } else {
   2200                             soc_dma_chan_poll_done(unit, channel,
   2201                                                     SOC_DMA_POLL_CHAIN_DONE,
   2202                                                     &poll_chain_done_detected);
   2203                         }
   2204                     }
   2205                     if (first_time[channel] || poll_chain_done_detected
   2206                         || pktdma_p->chain_done_tx[channel]) {
   2207                         pktdma_p->chain_done_tx[channel] = 0;
   2208                         if (pktdma_p->poll_intr_param == POLL
   2209                             && poll_chain_done_detected
   2210                             && (pktdma_p->cont_dma == 0)) {
   2211                             if (dv_num[channel] == 0) {
   2212                                 if (pktdma_p->chain_tx == 1) {
   2213                                     soc_dma_abort_dv(unit,
   2214                                                      pktdma_p->
   2215                                                      dv_tx_array[dv_cont
   2216                                                                  [channel]]
   2217                                                      [channel][0]);
   2218                                 } else {
   2219                                     soc_dma_abort_dv(unit,
   2220                                                      pktdma_p->
   2221                                                      dv_tx_array[dv_cont
   2222                                                                  [channel]]
   2223                                                      [channel][pktdma_p->
   2224                                                                num_pkts_param_tx
   2225                                                                - 1]);
   2226                                 }
   2227                             } else {
   2228                                 soc_dma_abort_dv(unit,
   2229                                                  pktdma_p->
   2230                                                  dv_tx_array[dv_cont[channel]]
   2231                                                  [channel][dv_num[channel] -
   2232                                                            1]);
   2233                             }
   2234                         }
   2235                         if (performance_test && reset_dv) {
   2236                         soc_dma_dv_reset(DV_TX,
   2237                                          pktdma_p->
   2238                                          dv_tx_array[dv_cont[channel]][channel]
   2239                                          [dv_num[channel]]);
   2240                         set_up_dv(unit,
   2241                                   pktdma_p->
   2242                                   dv_tx_array[dv_cont[channel]][channel], DV_TX,
   2243                                   pktdma_p->chain_tx, pktdma_p->sg_tx,
   2244                                   pktdma_p->reload_tx,
   2245                                   pktdma_p->poll_intr_param, channel,
   2246                                   pktdma_p->pkt_tx_array,
   2247                                   pktdma_p->pkt_size_param,
   2248                                   pktdma_p->num_pkts_param_tx,
   2249                                   pktdma_p->random_packet_sizes,
   2250                                   pktdma_p->source_ch, pktdma_p->cont_dma);
   2251                         }
   2252                         soc_dma_start(unit, channel,
   2253                                       pktdma_p->
   2254                                       dv_tx_array[dv_cont[channel]][channel]
   2255                                       [dv_num[channel]]);
   2256                         dv_num[channel]++;
   2257                         if ((pktdma_p->chain_tx && dv_num[channel] == 1)
   2258                             || (dv_num[channel] == pktdma_p->num_pkts_param_tx)) {
   2259                             channel_all_dv_done[channel] = 1;
   2260                         }
   2261                         /* CPU time cost of each channel */
   2262                         if (pktdma_p->cpu_time_cost_param != 0) {
   2263                             time_prev = time_curr;
   2264                             time_curr = sal_time_usecs();
   2265                             time_cost = SAL_USECS_SUB(time_curr, time_prev);
   2266                             cli_out("\n[time_cost] TX channel %0d, "
   2267                                     "time_cost(us) = %0d",
   2268                                     channel, (int) time_cost);
   2269                         }
   2270                         first_time[channel] = 0;
   2271                     }
   2272                 }
   2273             }
   2274             poll_chain_done_detected = 0;
   2275         }
   2276         if (performance_test == 0) {
   2277             all_channels_done = 1;
   2278             for (channel = 0; channel < MAX_CHANNELS; channel++) {
   2279                 if (channel_all_dv_done[channel] == 0
   2280                     && (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0)) {
   2281                     all_channels_done = 0;
   2282                 }
   2283             }
   2284         }
   2285     } while (all_channels_done != 1 && pktdma_p->kill_dma == 0);
   2286 
   2287     pktdma_p->tx_thread_done = 1;
   2288 
   2289     sal_thread_exit(0);
   2290 }
   2291 
   2292 /*
   2293  * Function:
   2294  *      pktdma_soc_check_packet_content
   2295  * Purpose:
   2296  *      Check received packets for content
   2297  * Parameters:
   2298  *      unit: StrataSwitch Unit #.
   2299  *      channel : RX channel
   2300  *
   2301  * Returns:
   2302  *     Nothing
   2303  */
   2304 
   2305 static void
   2306 pktdma_soc_check_packet_content(int unit, uint32 channel)
   2307 {
   2308     int32 j, k;
   2309     int32 match = 1;
   2310     uint8 *packet;
   2311     uint8 *exp_packet;
   2312     uint32 seq_id;
   2313     uint32 pkt_size;
   2314     uint32 tx_channel;
   2315     uint16 vlan_prio;
   2316     uint8 mac_sa[] = MAC_SA;
   2317     uint8 mac_da[] = MAC_DA;
   2318     pktdma_t *pktdma_p = pktdma_parray[unit];
   2319 
   2320     if (pktdma_p->pkt_size_param != 0) {
   2321         packet = sal_alloc(pktdma_p->pkt_size_param * sizeof(uint8), "Packet");
   2322         exp_packet = sal_alloc(pktdma_p->pkt_size_param * sizeof(uint8),
   2323                                                                 "Exp Packet");
   2324     } else {
   2325         packet = sal_alloc(pktdma_p->max_pkt_size_param * sizeof(uint8),
   2326                                                                 "Packet");
   2327         exp_packet = sal_alloc(pktdma_p->max_pkt_size_param * sizeof(uint8),
   2328                                                                "Exp Packet");
   2329     }
   2330 
   2331     if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   2332         for (j = 0; j < pktdma_p->num_pkts_param_rx; j++) {
   2333 
   2334             if (pktdma_p->pkt_size_param != 0) {
   2335                 for (k = 0; k < pktdma_p->pkt_size_param; k++) {
   2336                     packet[k] = pktdma_p->pkt_rx_array[channel][j]
   2337                                                 [k + pktdma_p->header_offset];
   2338                 }
   2339             } else {
   2340                 for (k = 0; k < pktdma_p->max_pkt_size_param; k++) {
   2341                     packet[k] = pktdma_p->pkt_rx_array[channel][j]
   2342                                                 [k + pktdma_p->header_offset];
   2343                 }
   2344             }
   2345             packet[(2 * NUM_BYTES_MAC_ADDR) + 2] &= 0xf0;
   2346             packet[(2 * NUM_BYTES_MAC_ADDR) + 2] |= (VLAN >> 8) & 0x000f;
   2347             packet[(2 * NUM_BYTES_MAC_ADDR) + 3] = VLAN & 0x00ff;
   2348             seq_id = 0x00000000;
   2349             pkt_size = 0x00000000;
   2350             tx_channel = 0x00000000;
   2351             vlan_prio = 0x0000;
   2352 
   2353             vlan_prio |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 2] << 8);
   2354             vlan_prio |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 3]);
   2355             seq_id |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 6] << 24);
   2356             seq_id |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 7] << 16);
   2357             seq_id |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 8] << 8);
   2358             seq_id |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 9]);
   2359             pkt_size |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 10] << 8);
   2360             pkt_size |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 11]);
   2361             tx_channel |= (packet[(2 * NUM_BYTES_MAC_ADDR) + 12]);
   2362 
   2363             sal_srand(pktdma_p->pkt_seed + tx_channel + seq_id);
   2364             pktdma_soc_gen_random_l2_pkt(exp_packet, pkt_size, mac_da, mac_sa,
   2365                                          TPID, vlan_prio, seq_id, tx_channel,
   2366                                          pktdma_p->cmicx_loopback_param);
   2367 
   2368             for (k = 0; k < pkt_size; k++) {
   2369                 if (packet[k] != exp_packet[k]) {
   2370                     test_error(unit, "\nCorrupt packet received on "
   2371                                         "channel %0d at location %p", channel,
   2372                                         pktdma_p->pkt_rx_array[channel][j]);
   2373                     pktdma_p->test_fail = 1;
   2374                     match = 0;
   2375                     break;
   2376                 }
   2377             }
   2378         }
   2379     }
   2380 
   2381     if (match == 0) {
   2382         test_error(unit, "\n*ERROR: Packet content check failed for channel %0d",
   2383                             channel);
   2384         pktdma_p->test_fail = 1;
   2385     }
   2386     sal_free(packet);
   2387     sal_free(exp_packet);
   2388 }
   2389 
   2390 /*
   2391  * Function:
   2392  *      rxdma_thread
   2393  * Purpose:
   2394  *      RX DMA thread - one thread takes care of all active channels
   2395  * Parameters:
   2396  *      up - Pointer to StrataSwitch Unit #.
   2397  *
   2398  * Returns:
   2399  *     Nothing
   2400  */
   2401 
   2402 static void
   2403 rxdma_thread(void *up)
   2404 {
   2405     int unit = PTR_TO_INT(up);
   2406     uint32 performance_test = 0;
   2407     int32 first_time[MAX_CHANNELS];
   2408     int32 channel;
   2409     int32 dv_num[MAX_CHANNELS];
   2410     int32 channel_all_dv_done[MAX_CHANNELS];
   2411     int32 poll_chain_done_detected = 0;
   2412     int32 all_channels_done = 0;
   2413     int32 dv_cont[MAX_CHANNELS];
   2414     int32 skip_chain_cnt[MAX_CHANNELS];
   2415     int32 first_chain_done[MAX_CHANNELS];
   2416     sal_usecs_t time_curr = 0, time_prev = 0, time_cost = 0;
   2417     uint32 reset_dv = 1;
   2418 
   2419     pktdma_t *pktdma_p = pktdma_parray[unit];
   2420 
   2421     if ((pktdma_p->stream_param_rx == 1)
   2422         || (pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD)) {
   2423         performance_test = 1;
   2424     } else {
   2425         performance_test = 0;
   2426     }
   2427     if (pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD ||
   2428         pktdma_p->stream_param_rx == 0) {
   2429         reset_dv = 0;
   2430     }
   2431 
   2432     for (channel = 0; channel < MAX_CHANNELS; channel++) {
   2433         first_time[channel] = 1;
   2434         dv_cont[channel] = 0;
   2435         dv_num[channel] = 0;
   2436         channel_all_dv_done[channel] = 0;
   2437         skip_chain_cnt[channel] = 0;
   2438         first_chain_done[channel] = 0;
   2439     }
   2440 
   2441     if (pktdma_p->cpu_time_cost_param != 0) {
   2442         time_curr = sal_time_usecs();
   2443     }
   2444 
   2445     do {
   2446         for (channel = 0; channel < MAX_CHANNELS; channel++) {
   2447             if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   2448                 if (channel_all_dv_done[channel] == 0 || performance_test) {
   2449                     if (performance_test && channel_all_dv_done[channel] == 1) {
   2450                         channel_all_dv_done[channel] = 0;
   2451                         dv_num[channel] = 0;
   2452                         if (pktdma_p->cont_dma == 1) {
   2453                             dv_cont[channel]++;
   2454                             dv_cont[channel] =
   2455                                 dv_cont[channel] % NUM_CONT_DMA_DV;
   2456                         }
   2457                     }
   2458                     if ((pktdma_p->poll_intr_param == POLL || pktdma_p->cont_dma)
   2459                         && (first_time[channel] == 0)
   2460                         && (pktdma_p->test_type_param_rx != DESC_RX_CHAIN_PKT_RELOAD)) {
   2461                         if (pktdma_p->cont_dma) {
   2462                             soc_check_cont_dma_in_halt(unit, channel,
   2463                                                        &poll_chain_done_detected);
   2464                         } else {
   2465                             soc_dma_chan_poll_done(unit, channel,
   2466                                                     SOC_DMA_POLL_CHAIN_DONE,
   2467                                                     &poll_chain_done_detected);
   2468                         }
   2469                     }
   2470                     if (first_time[channel] || poll_chain_done_detected
   2471                         || pktdma_p->chain_done_rx[channel]) {
   2472                         pktdma_p->chain_done_rx[channel] = 0;
   2473                         if (pktdma_p->poll_intr_param == POLL
   2474                             && poll_chain_done_detected
   2475                             && (pktdma_p->cont_dma == 0)) {
   2476                             if (dv_num[channel] == 0) {
   2477                                 if (pktdma_p->chain_rx == 1) {
   2478                                     soc_dma_abort_dv(unit,
   2479                                                      pktdma_p->
   2480                                                      dv_rx_array[dv_cont
   2481                                                                  [channel]]
   2482                                                      [channel][0]);
   2483                                 } else {
   2484                                     soc_dma_abort_dv(unit,
   2485                                                      pktdma_p->
   2486                                                      dv_rx_array[dv_cont
   2487                                                                  [channel]]
   2488                                                      [channel][pktdma_p->
   2489                                                                num_pkts_param_rx
   2490                                                                - 1]);
   2491                                 }
   2492                             } else {
   2493                                 soc_dma_abort_dv(unit,
   2494                                                  pktdma_p->
   2495                                                  dv_rx_array[dv_cont[channel]]
   2496                                                  [channel][dv_num[channel] -
   2497                                                            1]);
   2498                             }
   2499                         }
   2500                         if (performance_test && reset_dv) {
   2501                         soc_dma_dv_reset(DV_RX,
   2502                                          pktdma_p->
   2503                                          dv_rx_array[dv_cont[channel]][channel]
   2504                                          [dv_num[channel]]);
   2505                         set_up_dv(unit,
   2506                                   pktdma_p->
   2507                                   dv_rx_array[dv_cont[channel]][channel], DV_RX,
   2508                                   pktdma_p->chain_rx, pktdma_p->sg_rx,
   2509                                   pktdma_p->reload_rx,
   2510                                   pktdma_p->poll_intr_param, channel,
   2511                                   pktdma_p->pkt_rx_array,
   2512                                   pktdma_p->pkt_size_param,
   2513                                   pktdma_p->num_pkts_param_rx,
   2514                                   pktdma_p->random_packet_sizes,
   2515                                   pktdma_p->source_ch, pktdma_p->cont_dma);
   2516                         }
   2517                         dv_num[channel]++;
   2518 
   2519                         if ((pktdma_p->chain_rx && dv_num[channel] == 1)
   2520                             || (dv_num[channel] == pktdma_p->num_pkts_param_rx)) {
   2521                             channel_all_dv_done[channel] = 1;
   2522                             if ((pktdma_p->check_packet_integrity_param == 1)
   2523                                 && (skip_chain_cnt[channel] == 0)
   2524                                 && (first_time[channel] == 0)
   2525                                 && (first_chain_done[channel] == 1)) {
   2526                                 pktdma_soc_check_packet_content(unit, channel);
   2527                             }
   2528                             skip_chain_cnt[channel]
   2529                                         = (skip_chain_cnt[channel] + 1)
   2530                                                 % pktdma_p->pkt_chk_int_param;
   2531                             first_chain_done[channel] = 1;
   2532                         }
   2533                         soc_dma_start(unit, channel,
   2534                                       pktdma_p->
   2535                                       dv_rx_array[dv_cont[channel]][channel]
   2536                                       [dv_num[channel] - 1]);
   2537                         /* CPU time cost of each channel */
   2538                         if (pktdma_p->cpu_time_cost_param != 0) {
   2539                             time_prev = time_curr;
   2540                             time_curr = sal_time_usecs();
   2541                             time_cost = SAL_USECS_SUB(time_curr, time_prev);
   2542                             cli_out("\n[time_cost] RX channel %0d, "
   2543                                     "time_cost(us) = %0d",
   2544                                     channel, (int) time_cost);
   2545                         }
   2546                         first_time[channel] = 0;
   2547                     }
   2548                 }
   2549             }
   2550             poll_chain_done_detected = 0;
   2551         }
   2552         if (performance_test == 0) {
   2553             all_channels_done = 1;
   2554             for (channel = 0; channel < MAX_CHANNELS; channel++) {
   2555                 if (channel_all_dv_done[channel] == 0
   2556                     && (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0)) {
   2557                     all_channels_done = 0;
   2558                 }
   2559             }
   2560         }
   2561 
   2562     } while ((all_channels_done != 1) && pktdma_p->kill_dma == 0);
   2563 
   2564     pktdma_p->rx_thread_done = 1;
   2565 
   2566     sal_thread_exit(0);
   2567 }
   2568 
   2569 /*
   2570  * Function:
   2571  *      program_hostmem_addr_remap
   2572  * Purpose:
   2573  *      Program CMIC_CMCx_HOSTMEM_ADDR_REMAP regs for all CMCs
   2574  * Parameters:
   2575  *      unit: StrataSwitch Unit #.
   2576  *
   2577  * Returns:
   2578  *     Nothing
   2579  */
   2580 
   2581 static void
   2582 program_hostmem_addr_remap(int unit)
   2583 {
   2584     uint32 cmc;
   2585     pktdma_t *pktdma_p = pktdma_parray[unit];
   2586     uint32 header_size = 0;
   2587 
   2588     soc_dma_header_size_get(unit, &header_size);
   2589 
   2590     if (!soc_feature(unit, soc_feature_cmicx)) {
   2591         if (SOC_IS_TOMAHAWKX(unit)) {
   2592             for (cmc = 0; cmc < SOC_PCI_CMCS_NUM(unit); cmc++) {
   2593                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(cmc),
   2594                             0x144d2450);
   2595                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(cmc),
   2596                             0x19617595);
   2597                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc),
   2598                             0x1e75c6da);
   2599                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_3_OFFSET(cmc),
   2600                             0x1f);
   2601             }
   2602         } else if (SOC_IS_TRIDENT2PLUS(unit)) {
   2603             for (cmc = 0; cmc < SOC_PCI_CMCS_NUM(unit); cmc++) {
   2604                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_0_OFFSET(cmc),
   2605                             0x2b49ca30);
   2606                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_1_OFFSET(cmc),
   2607                             0x37ace2f6);
   2608                 soc_pci_write(unit, CMIC_CMCx_HOSTMEM_ADDR_REMAP_2_OFFSET(cmc),
   2609                             0xffbbc);
   2610             }
   2611         }
   2612     }
   2613 
   2614     pktdma_p->header_offset = header_size;
   2615 }
   2616 
   2617 /*
   2618  * Function:
   2619  *      turn_off_cmic_mmu_bkp
   2620  * Purpose:
   2621  *      Turn off CMIC to MMU backpressure
   2622  * Parameters:
   2623  *      unit: StrataSwitch Unit #.
   2624  *
   2625  * Returns:
   2626  *     Nothing
   2627  */
   2628 
   2629 static void
   2630 turn_off_cmic_mmu_bkp(int unit)
   2631 {
   2632     int cmc, ch;
   2633     int vchan;
   2634     uint32 threshold = CMICM_MMU_BKP_OFF_THRESHOLD;
   2635 
   2636     if (soc_feature(unit, soc_feature_cmicm)
   2637             || soc_feature(unit, soc_feature_cmicd_v2)
   2638             || soc_feature(unit, soc_feature_cmicd_v3)) {
   2639         threshold = CMICM_MMU_BKP_OFF_THRESHOLD;
   2640     } else if (soc_feature(unit, soc_feature_cmicx)) {
   2641         threshold = CMICX_MMU_BKP_OFF_THRESHOLD;
   2642     }
   2643 
   2644     for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   2645         for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) {
   2646             vchan = cmc * DMA_CHAN_PER_CMC(unit) + ch;
   2647             soc_dma_chan_rxbuf_threshold_cfg(unit, vchan, threshold);
   2648         }
   2649     }
   2650 
   2651     if (soc_feature(unit, soc_feature_cmicx)) {
   2652         for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   2653             soc_dma_cmc_rxbuf_threshold_cfg(unit, cmc, threshold);
   2654         }
   2655     }
   2656 }
   2657 
   2658 /*
   2659  * Function:
   2660  *      set_up_cos_ctrl
   2661  * Purpose:
   2662  *      Program COS_CTRL bitmaps.
   2663  * Parameters:
   2664  *      unit: StrataSwitch Unit #.
   2665  *      rx_bitmap: 12-bit bitmap of virtual channels active for RX
   2666  *
   2667  * Returns:
   2668  *     Nothing
   2669  */
   2670 
   2671 static void
   2672 set_up_cos_ctrl(int unit, uint32 rx_bitmap)
   2673 {
   2674     int32 cmc, ch;
   2675     int32 vchan = 0;
   2676     int32 max_vchan = 0;
   2677     uint32 max_cos_num = 0;
   2678     uint32 cos_bmp0, cos_bmp1;
   2679     uint32 i;
   2680     uint32 cmc_max = SOC_CMCS_NUM(unit);
   2681     uint32 ch_per_cmc_max = DMA_CHAN_PER_CMC(unit);
   2682 
   2683     if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
   2684         {
   2685             int numels;
   2686             soc_reg_t reg = 0;
   2687             uint32 rval = 0, fval = 0, fval_old;
   2688             uint32 rxchan_cnt = 0;
   2689             uint32 cos_map_full = 0, is_last_ch = 0;
   2690             /* set Q_SCHED_CPU_L1_MC_QUEUE_L0_MAPPING */
   2691             if (SOC_REG_IS_VALID(unit, Q_SCHED_CPU_L1_MC_QUEUE_L0_MAPPINGr)) {
   2692                 reg = Q_SCHED_CPU_L1_MC_QUEUE_L0_MAPPINGr;
   2693             } else if (SOC_REG_IS_VALID(unit, MMU_QSCH_CPU_L1_TO_L0_MAPPINGr)) {
   2694                 reg = MMU_QSCH_CPU_L1_TO_L0_MAPPINGr;
   2695             } else if (SOC_REG_IS_VALID(unit, Q_SCHED_CPU_L3_MC_QUEUE_L2_MAPPINGr)) {
   2696                 reg = Q_SCHED_CPU_L3_MC_QUEUE_L2_MAPPINGr;
   2697             }
   2698 
   2699             numels = SOC_REG_NUMELS(unit, reg);
   2700             for (i = 0; i < numels; i++) {
   2701                 fval = (i<8) ? (i) :
   2702                        ((i<16) ? 8 : 9);
   2703                 (void) soc_reg32_get(unit, reg, REG_PORT_ANY, i, &rval);
   2704                 fval_old = soc_reg_field_get(unit, reg, rval, SELECTf);
   2705                 if (fval != fval_old) {
   2706                     soc_reg_field_set(unit, reg, &rval, SELECTf, fval);
   2707                     soc_reg32_set(unit, reg, REG_PORT_ANY, i, rval);
   2708                 }
   2709             }
   2710             /* map CMIC RX channel to 48bit cos_q */
   2711             rxchan_cnt = 0;
   2712             cos_map_full = 0xffff;
   2713             for (cmc = 0; cmc < cmc_max; cmc++) {
   2714                 for (ch = 0; ch < ch_per_cmc_max; ch++) {
   2715                     vchan = (cmc * ch_per_cmc_max) + ch;
   2716                     soc_dma_chan_cos_ctrl_set(unit, vchan, 1, 0x0);
   2717                     soc_dma_chan_cos_ctrl_set(unit, vchan, 2, 0x0);
   2718                     if (((rx_bitmap >> vchan) % 2) != 0) {
   2719                         is_last_ch = ((rx_bitmap >> (vchan+1)) == 0);
   2720                         cos_bmp0 = (is_last_ch == 1 && rxchan_cnt >= 8) ?
   2721                                    (cos_map_full) : (0x1 << rxchan_cnt);
   2722                         cos_bmp1 = 0x0;
   2723                         soc_dma_chan_cos_ctrl_set(unit, vchan, 1, cos_bmp0);
   2724                         soc_dma_chan_cos_ctrl_set(unit, vchan, 2, cos_bmp1);
   2725                         rxchan_cnt++;
   2726                         cos_map_full &= ~cos_bmp0;
   2727                     }
   2728                 }
   2729             }
   2730         }
   2731     } else {
   2732         for (cmc = 0; cmc < cmc_max; cmc++) {
   2733             for (ch = 0; ch < ch_per_cmc_max; ch++) {
   2734                 vchan = (cmc * ch_per_cmc_max) + ch;
   2735                 soc_dma_chan_cos_ctrl_set(unit, vchan, 1, 0x0);
   2736                 soc_dma_chan_cos_ctrl_set(unit, vchan, 2, 0x0);
   2737 
   2738                 if (((rx_bitmap >> vchan) % 2) != 0) {
   2739                     if (max_cos_num < 32) {
   2740                         soc_dma_chan_cos_ctrl_set(unit, vchan, 1,
   2741                                                             (0x1 << max_cos_num));
   2742                     } else {
   2743                         soc_dma_chan_cos_ctrl_set(unit, vchan, 2,
   2744                                                     (0x1 << (max_cos_num - 32)));
   2745                     }
   2746                     max_cos_num++;
   2747                 }
   2748             }
   2749         }
   2750 
   2751         max_vchan = (cmc_max * ch_per_cmc_max) - 1;
   2752 
   2753         if (!soc_feature(unit, soc_feature_cmicx)) {
   2754             soc_dma_chan_cos_ctrl_get(unit, max_vchan, 1, &cos_bmp0);
   2755             soc_dma_chan_cos_ctrl_get(unit, max_vchan, 2, &cos_bmp1);
   2756 
   2757             if (max_cos_num < 32) {
   2758                 for (i = max_cos_num; i < 32; i++) {
   2759                     cos_bmp0 |= (0x1 << i);
   2760                 }
   2761                 max_cos_num = 32;
   2762             }
   2763 
   2764             for (i = max_cos_num; i < 64; i++) {
   2765                 cos_bmp1 |= (0x1 << (i - 32));
   2766             }
   2767 
   2768             soc_dma_chan_cos_ctrl_set(unit, max_vchan, 1, cos_bmp0);
   2769             soc_dma_chan_cos_ctrl_set(unit, max_vchan, 2, cos_bmp1);
   2770         }
   2771     }
   2772     {
   2773         uint32 rval = 0, fval;
   2774         soc_reg_t reg;
   2775         int numels = 0;
   2776         for (cmc = 0; cmc < cmc_max; cmc++) {
   2777             for (ch = 0; ch < ch_per_cmc_max; ch++) {
   2778                 vchan = (cmc * ch_per_cmc_max) + ch;
   2779                 soc_dma_chan_cos_ctrl_get(unit, vchan, 1, &cos_bmp0);
   2780                 soc_dma_chan_cos_ctrl_get(unit, vchan, 2, &cos_bmp1);
   2781                 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   2782                          "\n[CMIC_COS_CTRL_BMP] vchan %d, "
   2783                          "cos_bmp 0x%04x_0x%04x"),
   2784                          vchan, cos_bmp1, cos_bmp0));
   2785             }
   2786         }
   2787         if (SOC_REG_IS_VALID(unit, Q_SCHED_CPU_L1_MC_QUEUE_L0_MAPPINGr)) {
   2788             reg = Q_SCHED_CPU_L1_MC_QUEUE_L0_MAPPINGr;
   2789             numels = SOC_REG_NUMELS(unit, reg);
   2790             for (i=0; i<numels; i++) {
   2791                 (void) soc_reg32_get(unit, reg, REG_PORT_ANY, i, &rval);
   2792                 fval = soc_reg_field_get(unit, reg, rval, SELECTf);
   2793                 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   2794                          "\n[MMU_L1_TO_L0_MAPPING] "
   2795                          "MMU_L1_COS %2d --> MMU_L0_Q %0d"),
   2796                          i, fval));
   2797             }
   2798         } else if (SOC_REG_IS_VALID(unit, Q_SCHED_CPU_L3_MC_QUEUE_L2_MAPPINGr)) {
   2799                 reg = Q_SCHED_CPU_L3_MC_QUEUE_L2_MAPPINGr;
   2800                 numels = SOC_REG_NUMELS(unit, reg);
   2801                 for (i=0; i<numels; i++) {
   2802                     (void) soc_reg32_get(unit, reg, REG_PORT_ANY, i, &rval);
   2803                     fval = soc_reg_field_get(unit, reg, rval, SELECTf);
   2804                     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit,
   2805                              "\n[MMU_L3_TO_L2_MAPPING] "
   2806                              "MMU_L3_COS %2d --> MMU_L2_Q %0d"),
   2807                              i, fval));
   2808                 }
   2809             }
   2810     }
   2811 }
   2812 
   2813 /*
   2814  * Function:
   2815  *      pktdma_init
   2816  * Purpose:
   2817  *      Basic initialization for packet DMA
   2818  * Parameters:
   2819  *      unit: StrataSwitch Unit #
   2820  *      disable_rx_fc: Set to 1 to disable CMIC to MMU backpressure
   2821  *      rx_bitmap - 12-bit bitmap of active RX virtual channels
   2822  *
   2823  * Returns:
   2824  *     Nothing
   2825  */
   2826 
   2827 static void
   2828 pktdma_init(int unit, uint32 disable_rx_fc, uint32 rx_bitmap,
   2829             uint32 skip_cos_prog)
   2830 {
   2831     program_hostmem_addr_remap(unit);
   2832     if (disable_rx_fc == 1) {
   2833         turn_off_cmic_mmu_bkp(unit);
   2834     }
   2835 
   2836     if (skip_cos_prog != 1) {
   2837         set_up_cos_ctrl(unit, rx_bitmap);
   2838     }
   2839 }
   2840 
   2841 /*
   2842  * Function:
   2843  *      clear_all_dma_ctrl_regs
   2844  * Purpose:
   2845  *      Clear all CMIC_CMCx_CHy_DMA_CTRL regs
   2846  * Parameters:
   2847  *      unit: StrataSwitch Unit #.
   2848  *
   2849  * Returns:
   2850  *     Nothing
   2851  */
   2852 
   2853 static void
   2854 clear_all_dma_ctrl_regs(int unit)
   2855 {
   2856     int32 cmc, ch;
   2857     int32 vchan;
   2858     uint32 rdata, ctrl_reg;
   2859     uint32 pkt_endian = 0;
   2860     uint32 desc_endian = 0;
   2861     uint32 header_endian = 0;
   2862 
   2863     soc_dma_chan_ctrl_reg_get(unit, 0, &rdata);
   2864     soc_dma_masks_get(unit, &pkt_endian, &desc_endian, &header_endian);
   2865     rdata &= (pkt_endian | desc_endian | header_endian);
   2866     LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\nrdata = 0x%08x"), rdata));
   2867 
   2868     for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   2869         for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) {
   2870             vchan = (cmc * DMA_CHAN_PER_CMC(unit)) + ch;
   2871             soc_dma_chan_ctrl_reg_set(unit, vchan, rdata);
   2872             soc_dma_chan_ctrl_reg_get(unit, vchan, &ctrl_reg);
   2873             LOG_INFO(BSL_LS_APPL_TESTS,
   2874                      (BSL_META_U(unit, "\nCMIC_CMC%0d_CH%0d_DMA_CTRL = 0x%08x"),
   2875                       cmc, ch, ctrl_reg));
   2876         }
   2877     }
   2878 }
   2879 
   2880 /*
   2881  * Function:
   2882  *      clear_dma_status_regs
   2883  * Purpose:
   2884  *      Clear all CMIC_CMCx_DMA_STAT regs
   2885  * Parameters:
   2886  *      unit: StrataSwitch Unit #.
   2887  *
   2888  * Returns:
   2889  *     Nothing
   2890  */
   2891 
   2892 static void
   2893 clear_dma_status_regs(int unit)
   2894 {
   2895     int32 cmc;
   2896 
   2897     if (!soc_feature(unit, soc_feature_cmicx)) {
   2898         for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   2899             soc_dma_chan_status_clear(unit, (cmc * DMA_CHAN_PER_CMC(unit)));
   2900         }
   2901     }
   2902 }
   2903 
   2904 /*
   2905  * Function:
   2906  *      clear_cmic_pkt_counters
   2907  * Purpose:
   2908  *      Clear CMIC packet counters
   2909  * Parameters:
   2910  *      unit: StrataSwitch Unit #.
   2911  *
   2912  * Returns:
   2913  *     Nothing
   2914  */
   2915 
   2916 static void
   2917 clear_cmic_pkt_counters(int unit)
   2918 {
   2919     int32 cmc, ch;
   2920     int32 vchan;
   2921 
   2922 
   2923     for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   2924         soc_dma_cmc_counter_clear(unit, cmc, SOC_DMA_TXPKT);
   2925         soc_dma_cmc_counter_clear(unit, cmc, SOC_DMA_RXPKT);
   2926 
   2927         for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) {
   2928             vchan = (cmc * DMA_CHAN_PER_CMC(unit)) + ch;
   2929             soc_dma_chan_counter_clear(unit, vchan, SOC_DMA_TXPKT);
   2930             soc_dma_chan_counter_clear(unit, vchan, SOC_DMA_RXPKT);
   2931         }
   2932     }
   2933 }
   2934 
   2935 /*
   2936  * Function:
   2937  *      pktdma_soc_test_clean
   2938  * Purpose:
   2939  *      Cleanup routine. Aborts all packet DMAs and clears ctrl and status regs
   2940  * Parameters:
   2941  *      unit: StrataSwitch Unit #.
   2942  *      abort_dma: Set to 1 to abort all packet DMA operations
   2943  *
   2944  * Returns:
   2945  *     Nothing
   2946  */
   2947 
   2948 static void
   2949 pktdma_soc_test_clean(int unit, int abort_dma)
   2950 {
   2951     cli_out("\nCalling pktdma_soc_test_clean");
   2952     cli_out("\nClearing DMA status regs");
   2953     clear_dma_status_regs(unit);
   2954     if (abort_dma != 0) {
   2955         cli_out("\nAborting all DMA ops");
   2956         soc_dma_abort(unit);
   2957     }
   2958     sal_usleep(100000);
   2959     cli_out("\nClearing DMA ctrl regs");
   2960     clear_all_dma_ctrl_regs(unit);
   2961     cli_out("\nClearing CMIC packet ctrs");
   2962     clear_cmic_pkt_counters(unit);
   2963     cli_out("\nClearing DMA status regs");
   2964     clear_dma_status_regs(unit);
   2965 }
   2966 
   2967 /*
   2968  * Function:
   2969  *      pktdma_soc_program_cpu_cos_map
   2970  * Purpose:
   2971  *      Program CPU_COS_MAP table for 16 priorities. Maps each internal priority
   2972  *      to an unique COS queue.
   2973  * Parameters:
   2974  *      unit: StrataSwitch Unit #.
   2975  *
   2976  * Returns:
   2977  *     Nothing
   2978  */
   2979 
   2980 static void
   2981 pktdma_soc_program_cpu_cos_map(int unit)
   2982 {
   2983     cpu_cos_map_entry_t cpu_cos_map_entry;
   2984     uint32 cpu_cos_map_mask_entry[SOC_MAX_MEM_WORDS];
   2985     uint32 cpu_cos_map_key_entry[SOC_MAX_MEM_WORDS];
   2986     uint32 entry;
   2987 
   2988     sal_memset (&cpu_cos_map_mask_entry, 0, sizeof(cpu_cos_map_mask_entry));
   2989     sal_memset (&cpu_cos_map_key_entry, 0, sizeof(cpu_cos_map_key_entry));
   2990 
   2991 #if defined(BCM_TOMAHAWK3_SUPPORT)
   2992     if (SOC_IS_TOMAHAWK3(unit)) {
   2993         uint32 final_int_prio, final_int_prio_mask;
   2994         for (entry = 0; entry < MAX_COS; entry++) {
   2995             final_int_prio = entry;
   2996             final_int_prio_mask = 0xf;
   2997             (void) soc_mem_read(unit, CPU_COS_MAPm, COPYNO_ALL, entry,
   2998                          cpu_cos_map_entry.entry_data);
   2999             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3000                                 VALIDf, 0x1);
   3001             soc_format_field32_set(unit, CPU_COS_MAP_KEYfmt, cpu_cos_map_key_entry,
   3002                                 INT_PRIf, final_int_prio);
   3003             soc_format_field32_set(unit, CPU_COS_MAP_KEYfmt, cpu_cos_map_mask_entry,
   3004                                 INT_PRIf, final_int_prio_mask);
   3005             soc_mem_field_set(unit, CPU_COS_MAPm, (uint32 *)&cpu_cos_map_entry.entry_data,
   3006                                 KEYf, &cpu_cos_map_key_entry[0]);
   3007             soc_mem_field_set(unit, CPU_COS_MAPm, (uint32 *)&cpu_cos_map_entry.entry_data,
   3008                                 MASKf, &cpu_cos_map_mask_entry[0]);
   3009             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3010                                 COSf, entry);
   3011             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3012                                 RQE_CPU_COSf, (entry % 2));
   3013             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3014                                 STRENGTHf, 0x1);
   3015             (void) soc_mem_write(unit, CPU_COS_MAPm, COPYNO_ALL, entry,
   3016                           cpu_cos_map_entry.entry_data);
   3017         }
   3018     } else
   3019 #endif
   3020     if (SOC_IS_TRIDENT3X(unit)) {
   3021         for (entry = 0; entry < MAX_COS; entry++) {
   3022             (void) soc_mem_read(unit, CPU_COS_MAPm, COPYNO_ALL, entry,
   3023                          cpu_cos_map_entry.entry_data);
   3024             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3025                                 VALIDf, 0x3);
   3026             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3027                                 INT_PRI_MASKf, 0xf);
   3028             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3029                                 INT_PRI_KEYf, entry);
   3030             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3031                                 COSf, entry);
   3032             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3033                                 RQE_CPU_COSf, (entry % 2));
   3034             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3035                                 STRENGTHf, 0x1);
   3036             (void) soc_mem_write(unit, CPU_COS_MAPm, COPYNO_ALL, entry,
   3037                           cpu_cos_map_entry.entry_data);
   3038         }
   3039     } else {
   3040         for (entry = 0; entry < MAX_COS; entry++) {
   3041             (void) soc_mem_read(unit, CPU_COS_MAPm, COPYNO_ALL, entry,
   3042                          cpu_cos_map_entry.entry_data);
   3043             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3044                                 VALIDf, (SOC_IS_TOMAHAWK2(unit) ? 0x3 : 0x1));
   3045             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3046                                 INT_PRI_MASKf, 0xf);
   3047             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3048                                 INT_PRI_KEYf, entry);
   3049             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3050                                 COSf, entry);
   3051             soc_mem_field32_set(unit, CPU_COS_MAPm, cpu_cos_map_entry.entry_data,
   3052                                 RQE_CPU_COSf, (entry % 2));
   3053             (void) soc_mem_write(unit, CPU_COS_MAPm, COPYNO_ALL, entry,
   3054                           cpu_cos_map_entry.entry_data);
   3055         }
   3056     }
   3057 }
   3058 
   3059 /*
   3060  * Function:
   3061  *      pktdma_soc_program_cos_map_pri16
   3062  * Purpose:
   3063  *      Misc table programming to map 16 internal priorities to corresponding COS
   3064  *      queues. For example prio 0 is mapped to queue 0, priority 1 to queue 1
   3065  *      and so on.
   3066  * Parameters:
   3067  *      unit: StrataSwitch Unit #.
   3068  *
   3069  * Returns:
   3070  *     Nothing
   3071  */
   3072 
   3073 static void
   3074 pktdma_soc_program_cos_map_pri16(int unit)
   3075 {
   3076     uint32 i, j;
   3077     uint32 entry_data_size = 0;
   3078     uint32 mem_index_size = 0;
   3079     uint64 cpu_lo_rqe_q_num;
   3080     uint64 cpu_hi_rqe_q_num;
   3081     uint64 mirror_rqe_q_num;
   3082 #ifdef BCM_TRIDENT3_SUPPORT
   3083     egr_vlan_control_1_entry_t egr_vlan_control_1_entry;
   3084     /* ing_outer_dot1p_mapping_table_entry_t ing_outer_dot1p_mapping_table_entry; */
   3085     phb_mapping_tbl_1_entry_t phb_mapping_tbl_1_entry;
   3086     /* port_cos_map_entry_t port_cos_map_entry; */
   3087     egr_zone_3_dot1p_mapping_table_3_entry_t egr_zone_3_dot1p_mapping_table_3_entry;
   3088     egr_map_mh_entry_t egr_map_mh_entry;
   3089 #endif
   3090     uint32 p;
   3091     ing_pri_cng_map_entry_t ing_pri_cng_map_entry;
   3092     ing_outer_dot1p_mapping_table_entry_t ing_outer_dot1p_mapping_table_entry;
   3093     egr_pri_cng_map_entry_t egr_pri_cng_map_entry;
   3094     port_cos_map_entry_t port_cos_map_entry;
   3095     soc_field_t egr_vlan_control_1_fields[] =
   3096         { CFI_AS_CNGf, VT_MISS_DROPf, VT_ENABLEf };
   3097     uint32 egr_vlan_control_1_values[] = { 0x1, 0x0, 0x0 };
   3098 
   3099     COMPILER_64_SET(cpu_lo_rqe_q_num, 0x0, 0x8);
   3100     COMPILER_64_SET(cpu_hi_rqe_q_num, 0x0, 0x9);
   3101     COMPILER_64_SET(mirror_rqe_q_num, 0x0, 0xa);
   3102 
   3103 #ifdef BCM_TRIDENT3_SUPPORT
   3104     if (SOC_IS_TRIDENT3X(unit)) {
   3105         /* epipe: EGR_VLAN_CONTROL_1m */
   3106         if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) {
   3107             entry_data_size = sizeof(egr_vlan_control_1_entry.entry_data) / sizeof(uint32);
   3108             for (j = 0; j < entry_data_size; j++) {
   3109                 egr_vlan_control_1_entry.entry_data[j] = 0x00000000;
   3110             }
   3111             soc_mem_field32_set(unit, EGR_VLAN_CONTROL_1m,
   3112                                 egr_vlan_control_1_entry.entry_data,
   3113                                 REMARK_OUTER_DOT1Pf, 1);
   3114             soc_mem_field32_set(unit, EGR_VLAN_CONTROL_1m,
   3115                                 egr_vlan_control_1_entry.entry_data,
   3116                                 CFI_AS_CNGf, 15);
   3117             (void) soc_mem_write(unit, EGR_VLAN_CONTROL_1m, COPYNO_ALL, 0,
   3118                                  egr_vlan_control_1_entry.entry_data);
   3119         }
   3120         /* ipipe: ING_OUTER_DOT1P_MAPPING_TABLEm */
   3121         if (SOC_MEM_IS_VALID(unit, ING_OUTER_DOT1P_MAPPING_TABLEm)) {
   3122             mem_index_size = soc_mem_index_max(unit, ING_OUTER_DOT1P_MAPPING_TABLEm);
   3123             entry_data_size = sizeof(ing_outer_dot1p_mapping_table_entry.entry_data) / sizeof(uint32);
   3124             cli_out("\n[ING_OUTER_DOT1P_MAPPING_TABLEm] idx_size %d, data_size %d",
   3125                     mem_index_size, entry_data_size);
   3126             for (i = 0; i < mem_index_size; i++) {
   3127                 for (j = 0; j < entry_data_size; j++) {
   3128                     ing_outer_dot1p_mapping_table_entry.entry_data[j] = 0x00000000;
   3129                 }
   3130                 soc_mem_field32_set(unit, ING_OUTER_DOT1P_MAPPING_TABLEm,
   3131                                     ing_outer_dot1p_mapping_table_entry.entry_data,
   3132                                     NEW_CFIf, (i % 2));
   3133                 soc_mem_field32_set(unit, ING_OUTER_DOT1P_MAPPING_TABLEm,
   3134                                     ing_outer_dot1p_mapping_table_entry.entry_data,
   3135                                     NEW_DOT1Pf, ((i % 16) / 2));
   3136                 (void) soc_mem_write(unit, ING_OUTER_DOT1P_MAPPING_TABLEm, COPYNO_ALL, i,
   3137                                      ing_outer_dot1p_mapping_table_entry.entry_data);
   3138             }
   3139         }
   3140         /* ipipe: PHB_MAPPING_TBL_1m */
   3141         if (SOC_MEM_IS_VALID(unit, PHB_MAPPING_TBL_1m)) {
   3142             mem_index_size = soc_mem_index_max(unit, PHB_MAPPING_TBL_1m);
   3143             entry_data_size = sizeof(phb_mapping_tbl_1_entry.entry_data) / sizeof(uint32);
   3144             cli_out("\n[PHB_MAPPING_TBL_1m] idx_size %d, data_size %d",
   3145                     mem_index_size, entry_data_size);
   3146             for (i = 0; i < mem_index_size; i++) {
   3147                 for (j = 0; j < entry_data_size; j++) {
   3148                     phb_mapping_tbl_1_entry.entry_data[j] = 0x00000000;
   3149                 }
   3150                 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m,
   3151                                     phb_mapping_tbl_1_entry.entry_data,
   3152                                     INT_PRIf, (i % 16));
   3153                 (void) soc_mem_write(unit, PHB_MAPPING_TBL_1m, COPYNO_ALL, i,
   3154                                      phb_mapping_tbl_1_entry.entry_data);
   3155             }
   3156         }
   3157         /* ipipe: PORT_COS_MAPm */
   3158         if (SOC_MEM_IS_VALID(unit, PORT_COS_MAPm)) {
   3159             mem_index_size = soc_mem_index_max(unit, PORT_COS_MAPm);
   3160             entry_data_size = sizeof(port_cos_map_entry.entry_data) / sizeof(uint32);
   3161             cli_out("\n[PORT_COS_MAPm] idx_size %d, data_size %d",
   3162                     mem_index_size, entry_data_size);
   3163             for (i = 0; i < mem_index_size; i++) {
   3164                 for (j = 0; j < entry_data_size; j++) {
   3165                     port_cos_map_entry.entry_data[j] = 0x00000000;
   3166                 }
   3167                 soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3168                                     UC_COS1f, ((i % 16) % 10));
   3169                 soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3170                                     MC_COS1f, ((i % 16) % 10));
   3171 /*                 soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3172                                     RQE_Q_NUMf, ((i % 16) % 11)); */
   3173                 (void) soc_mem_write(unit, PORT_COS_MAPm, COPYNO_ALL, i,
   3174                                      port_cos_map_entry.entry_data);
   3175             }
   3176         }
   3177         /* epipe: EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m */
   3178         if (SOC_MEM_IS_VALID(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m)) {
   3179             mem_index_size = soc_mem_index_max(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m);
   3180             entry_data_size = sizeof(egr_zone_3_dot1p_mapping_table_3_entry.entry_data) / sizeof(uint32);
   3181             cli_out("\n[EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m] idx_size %d, data_size %d",
   3182                     mem_index_size, entry_data_size);
   3183             for (i = 0; i < mem_index_size; i++) {
   3184                 for (j = 0; j < entry_data_size; j++) {
   3185                     egr_zone_3_dot1p_mapping_table_3_entry.entry_data[j] = 0x00000000;
   3186                 }
   3187                 /* i[5:2] */
   3188                 soc_mem_field32_set(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m, egr_zone_3_dot1p_mapping_table_3_entry.entry_data,
   3189                                     CFIf, (((i >> 2) & 0xf) % 2));
   3190                 soc_mem_field32_set(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m, egr_zone_3_dot1p_mapping_table_3_entry.entry_data,
   3191                                     PRIf, (((i >> 2) & 0xf) / 2));
   3192                 (void) soc_mem_write(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m, COPYNO_ALL, i,
   3193                                      egr_zone_3_dot1p_mapping_table_3_entry.entry_data);
   3194             }
   3195         }
   3196         /* epipe: EGR_MAP_MHm */
   3197         if (SOC_MEM_IS_VALID(unit, EGR_MAP_MHm)) {
   3198             mem_index_size = soc_mem_index_max(unit, EGR_MAP_MHm);
   3199             entry_data_size = sizeof(egr_map_mh_entry.entry_data) / sizeof(uint32);
   3200             cli_out("\n[EGR_MAP_MHm] idx_size %d, data_size %d",
   3201                     mem_index_size, entry_data_size);
   3202             for (i = 0; i < mem_index_size; i++) {
   3203                 for (j = 0; j < entry_data_size; j++) {
   3204                     egr_map_mh_entry.entry_data[j] = 0x00000000;
   3205                 }
   3206                 soc_mem_field32_set(unit, EGR_MAP_MHm, egr_map_mh_entry.entry_data,
   3207                                     HG_TCf, (i % 16));
   3208                 (void) soc_mem_write(unit, EGR_MAP_MHm, COPYNO_ALL, i,
   3209                                      egr_map_mh_entry.entry_data);
   3210             }
   3211         }
   3212 
   3213         /* regs */
   3214         (void) soc_reg_set(unit, CPU_LO_RQE_Q_NUMr, 0, 0, cpu_lo_rqe_q_num);
   3215         (void) soc_reg_set(unit, CPU_HI_RQE_Q_NUMr, 0, 0, cpu_hi_rqe_q_num);
   3216         (void) soc_reg_set(unit, MIRROR_RQE_Q_NUMr, 0, 0, mirror_rqe_q_num);
   3217     }
   3218 #endif
   3219     if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2PLUS(unit)) {
   3220         /* ING_PRI_CNG_MAPm */
   3221         if (SOC_MEM_IS_VALID(unit, ING_PRI_CNG_MAPm)) {
   3222             mem_index_size = soc_mem_index_max(unit, ING_PRI_CNG_MAPm);
   3223             entry_data_size = sizeof(ing_pri_cng_map_entry.entry_data) / sizeof(uint32);
   3224             for (i = 0; i < mem_index_size; i++) {
   3225                 for (j = 0; j < entry_data_size; j++) {
   3226                     ing_pri_cng_map_entry.entry_data[j] = 0x00000000;
   3227                 }
   3228 
   3229                 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm,
   3230                                     ing_pri_cng_map_entry.entry_data, PRIf,
   3231                                     ((8 * (i % 2)) + ((i % 16) / 2)));
   3232                 (void) soc_mem_write(unit, ING_PRI_CNG_MAPm, COPYNO_ALL, i,
   3233                                      ing_pri_cng_map_entry.entry_data);
   3234             }
   3235         }
   3236         /* ING_OUTER_DOT1P_MAPPING_TABLEm */
   3237         if (SOC_MEM_IS_VALID(unit, ING_OUTER_DOT1P_MAPPING_TABLEm)) {
   3238             mem_index_size = soc_mem_index_max(unit, ING_OUTER_DOT1P_MAPPING_TABLEm);
   3239             entry_data_size = sizeof(ing_outer_dot1p_mapping_table_entry.entry_data) / sizeof(uint32);
   3240             for (i = 0; i < mem_index_size; i++) {
   3241                 for (j = 0; j < entry_data_size; j++) {
   3242                     ing_outer_dot1p_mapping_table_entry.entry_data[j] = 0x00000000;
   3243                 }
   3244 
   3245                 soc_mem_field32_set(unit, ING_OUTER_DOT1P_MAPPING_TABLEm,
   3246                                     ing_outer_dot1p_mapping_table_entry.entry_data,
   3247                                     NEW_CFIf, (i % 2));
   3248                 soc_mem_field32_set(unit, ING_OUTER_DOT1P_MAPPING_TABLEm,
   3249                                     ing_outer_dot1p_mapping_table_entry.entry_data,
   3250                                     NEW_DOT1Pf, ((i % 16) / 2));
   3251                 (void) soc_mem_write(unit, ING_OUTER_DOT1P_MAPPING_TABLEm, COPYNO_ALL, i,
   3252                                      ing_outer_dot1p_mapping_table_entry.entry_data);
   3253             }
   3254         }
   3255         /* EGR_PRI_CNG_MAPm */
   3256         if (SOC_MEM_IS_VALID(unit, EGR_PRI_CNG_MAPm)) {
   3257             mem_index_size = soc_mem_index_max(unit, EGR_PRI_CNG_MAPm);
   3258             entry_data_size = sizeof(egr_pri_cng_map_entry.entry_data) / sizeof(uint32);
   3259             for (i = 0; i < mem_index_size; i++) {
   3260                 for (j = 0; j < entry_data_size; j++) {
   3261                     egr_pri_cng_map_entry.entry_data[j] = 0x00000000;
   3262                 }
   3263 
   3264                 soc_mem_field32_set(unit, EGR_PRI_CNG_MAPm,
   3265                                     egr_pri_cng_map_entry.entry_data, CFIf,
   3266                                     ((i / 32) % 2));
   3267                 soc_mem_field32_set(unit, EGR_PRI_CNG_MAPm,
   3268                                     egr_pri_cng_map_entry.entry_data, PRIf,
   3269                                     ((i % 32) / 4));
   3270                 (void) soc_mem_write(unit, EGR_PRI_CNG_MAPm, COPYNO_ALL, i,
   3271                                      egr_pri_cng_map_entry.entry_data);
   3272             }
   3273         }
   3274         /* PORT_COS_MAPm */
   3275         if (SOC_MEM_IS_VALID(unit, PORT_COS_MAPm)) {
   3276             mem_index_size = soc_mem_index_max(unit, PORT_COS_MAPm);
   3277             entry_data_size = sizeof(port_cos_map_entry.entry_data) / sizeof(uint32);
   3278             for (i = 0; i < mem_index_size; i++) {
   3279                 for (j = 0; j < entry_data_size; j++) {
   3280                     port_cos_map_entry.entry_data[j] = 0x00000000;
   3281                 }
   3282                 if (SOC_IS_TOMAHAWK3(unit)) {
   3283                     soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3284                                         UC_COS1f, ((i % 16) % 12));
   3285                     soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3286                                         MC_COS1f, ((i % 16) % 6));
   3287                     soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3288                                         RQE_Q_NUMf, ((i % 16) % 9));
   3289                 } else {
   3290                     soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3291                                         UC_COS1f, ((i % 16) % 10));
   3292                     soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3293                                         MC_COS1f, ((i % 16) % 10));
   3294                     soc_mem_field32_set(unit, PORT_COS_MAPm, port_cos_map_entry.entry_data,
   3295                                         RQE_Q_NUMf, ((i % 16) % 11));
   3296                 }
   3297                 (void) soc_mem_write(unit, PORT_COS_MAPm, COPYNO_ALL, i,
   3298                                      port_cos_map_entry.entry_data);
   3299             }
   3300         }
   3301 
   3302         /* regs */
   3303         (void) soc_reg_set(unit, CPU_LO_RQE_Q_NUMr, 0, 0, cpu_lo_rqe_q_num);
   3304         (void) soc_reg_set(unit, CPU_HI_RQE_Q_NUMr, 0, 0, cpu_hi_rqe_q_num);
   3305         (void) soc_reg_set(unit, MIRROR_RQE_Q_NUMr, 0, 0, mirror_rqe_q_num);
   3306 
   3307         if (SOC_REG_IS_VALID(unit, EGR_VLAN_CONTROL_1r)) {
   3308             PBMP_ITER(PBMP_PORT_ALL(unit), p) {
   3309                 soc_reg_fields32_modify(unit, EGR_VLAN_CONTROL_1r, p, 3,
   3310                                         egr_vlan_control_1_fields,
   3311                                         egr_vlan_control_1_values);
   3312             }
   3313         }
   3314     }
   3315 
   3316 }
   3317 #ifdef BCM_TOMAHAWK3_SUPPORT
   3318 static void
   3319 set_up_ports(int unit, pbmp_t pbmp)
   3320 {
   3321     int i;
   3322     lport_tab_entry_t lport_tab_entry;
   3323     port_tab_entry_t port_tab_entry;
   3324 
   3325     cli_out("\nCalling set_up_ports\n");
   3326 
   3327     cli_out("\nEnabling Port bridging\n");
   3328 
   3329     for (i = 0; i < soc_mem_index_max(unit, LPORT_TABm); i++) {
   3330         (void) soc_mem_read(unit, LPORT_TABm, COPYNO_ALL, i,
   3331                      lport_tab_entry.entry_data);
   3332         soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data,
   3333                             PORT_BRIDGEf, 0x1);
   3334         (void) soc_mem_write(unit, LPORT_TABm, COPYNO_ALL, i,
   3335                       lport_tab_entry.entry_data);
   3336     }
   3337 
   3338     for (i = 0; i < soc_mem_index_max(unit, PORT_TABm); i++) {
   3339         (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, i,
   3340                      port_tab_entry.entry_data);
   3341         soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data,
   3342                             PORT_BRIDGEf, 0x1);
   3343         (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, i,
   3344                           port_tab_entry.entry_data);
   3345     }
   3346 }
   3347 #endif
   3348 
   3349 /*
   3350  * Function:
   3351  *      pktdma_soc_set_up_vlan
   3352  * Purpose:
   3353  *      VLAN programming to set up packet flows.
   3354  * Parameters:
   3355  *      unit: StrataSwitch Unit #.
   3356  *      tx_bitmap: 12-bit TX virtual channel bitmap.
   3357  *      rx_bitmap: 12-bit RX virtual channel bitmap
   3358  *      pkt_size: Packet Size
   3359  *      test_vlan: VLAN on which CPU sends out pkts
   3360  *      xlate_vlan_start: Starting VLAN feom which 10 consecutive VLANs are
   3361  *                        available for VLAN xlation.
   3362  *
   3363  * Returns:
   3364  *     Nothing
   3365  */
   3366 
   3367 static void
   3368 pktdma_soc_set_up_vlan(int unit, uint32 tx_bitmap, uint32 rx_bitmap,
   3369                        uint32 pkt_size, bcm_vlan_t test_vlan,
   3370                        bcm_vlan_t xlate_vlan_start)
   3371 {
   3372     pbmp_t pbm, ubm;
   3373     int32 port, i;
   3374     uint32 *port_list;
   3375     pktdma_t *pktdma_p = pktdma_parray[unit];
   3376 
   3377     port_list = (uint32 *)(sal_alloc(pktdma_p->num_lb_ports_param *
   3378                                         sizeof(uint32), "port_list"));
   3379     i = 0;
   3380     PBMP_ITER(PBMP_PORT_ALL(unit), port) {
   3381         if (i < pktdma_p->num_lb_ports_param) {
   3382             port_list[i] = port;
   3383             i++;
   3384         }
   3385     }
   3386 
   3387     BCM_PBMP_CLEAR(pbm);
   3388     BCM_PBMP_CLEAR(ubm);
   3389 
   3390     cli_out("\nSetting up VLANs");
   3391 
   3392 
   3393     if (rx_bitmap == 0x000) {
   3394         cli_out("\nrx_bitmap = 0x000, Test is a TX only test");
   3395         BCM_PBMP_PORT_ADD(pbm, port_list[1]);
   3396         BCM_PBMP_PORT_ADD(pbm, 0);
   3397         bcm_vlan_create(unit, test_vlan);
   3398         bcm_vlan_create(unit, xlate_vlan_start);
   3399         bcm_vlan_port_add(unit, xlate_vlan_start, pbm, ubm);
   3400         bcm_vlan_port_add(unit, test_vlan, pbm, ubm);
   3401         bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE);
   3402         bcm_vlan_translate_add(unit, port_list[1], test_vlan,
   3403                                xlate_vlan_start, 0);
   3404     } else if (tx_bitmap == 0x000) {
   3405         cli_out
   3406             ("\ntx_bitmap = 0x000, Test is a RX only test."
   3407              "The test needs to be done with a TG");
   3408         BCM_PBMP_CLEAR(pbm);
   3409         BCM_PBMP_PORT_ADD(pbm, port_list[1]);
   3410         BCM_PBMP_PORT_ADD(pbm, 0);
   3411         BCM_PBMP_PORT_ADD(pbm, port_list[2]);
   3412         bcm_vlan_create(unit, test_vlan);
   3413         bcm_vlan_port_add(unit, test_vlan, pbm, ubm);
   3414     } else {
   3415         cli_out("\nThis is a loopback test");
   3416         if (pktdma_p->stream_param_tx == 1 || pktdma_p->stream_param_rx == 1
   3417             || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD
   3418             || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
   3419 #ifdef BCM_TOMAHAWK3_SUPPORT
   3420             if (SOC_IS_TOMAHAWK3(unit)) {
   3421                 /* Since VLAN_XLATE is not supported in TH3, we use port bridging
   3422                    to create the keep looping the packets. */
   3423                 for (port = 0; port < pktdma_p->num_lb_ports_param; port++) {
   3424                     BCM_PBMP_CLEAR(pbm);
   3425                     BCM_PBMP_PORT_ADD(pbm, 0);
   3426                     BCM_PBMP_PORT_ADD(pbm, port_list[port]);
   3427                     bcm_vlan_create(unit, (test_vlan + port));
   3428                     bcm_vlan_port_add(unit, (test_vlan + port), pbm, ubm);
   3429                 }
   3430 
   3431                 for (port = 0; port < pktdma_p->num_lb_ports_param; port++) {
   3432                     cli_out("\n[vlan] "
   3433                             "vlan_id :  0x%04x, "
   3434                             "ports [%0d, %0d]",
   3435                             test_vlan + port,
   3436                             0, port_list[port]);
   3437                 }
   3438                 set_up_ports(unit, pbm);
   3439            } else
   3440 #endif
   3441                 {
   3442                 cli_out("\nSetting up VLAN xlates for perf test");
   3443                 bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE);
   3444                 for (port = 0; port < pktdma_p->num_lb_ports_param; port++) {
   3445                     BCM_PBMP_CLEAR(pbm);
   3446                     BCM_PBMP_PORT_ADD(pbm, 0);
   3447                     BCM_PBMP_PORT_ADD(pbm, port_list[port]);
   3448                     bcm_vlan_create(unit, (xlate_vlan_start + port));
   3449                     bcm_vlan_port_add(unit, (xlate_vlan_start + port), pbm, ubm);
   3450                     bcm_vlan_translate_add(unit, port_list[port], test_vlan,
   3451                                            xlate_vlan_start + port, 0);
   3452                 }
   3453                 for (port = 0; port < pktdma_p->num_lb_ports_param; port++) {
   3454                     cli_out("\n[vlan_translate] "
   3455                             "old_vlan 0x%04x, new_vlan 0x%04x, "
   3456                             "ports [%0d, %0d]",
   3457                             test_vlan, xlate_vlan_start + port,
   3458                             0, port_list[port]);
   3459                 }
   3460            }
   3461         }
   3462 
   3463         BCM_PBMP_CLEAR(pbm);
   3464         if (pktdma_p->stream_param_tx == 1 || pktdma_p->stream_param_rx == 1
   3465             || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD
   3466             || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
   3467             for (port = 0; port < pktdma_p->num_lb_ports_param; port++) {
   3468                 BCM_PBMP_PORT_ADD(pbm, port_list[port]);
   3469             }
   3470         } else {
   3471             BCM_PBMP_PORT_ADD(pbm, port_list[1]);
   3472             BCM_PBMP_PORT_ADD(pbm, 0);
   3473         }
   3474         bcm_vlan_create(unit, test_vlan);
   3475         bcm_vlan_port_add(unit, test_vlan, pbm, ubm);
   3476         {
   3477             cli_out("\n[vlan_setup] vlan_id 0x%04x, port [", test_vlan);
   3478             PBMP_ITER(pbm, port) {
   3479                 cli_out("%d, ", port);
   3480             }
   3481             cli_out("]");
   3482         }
   3483     }
   3484 }
   3485 
   3486 /*
   3487  * Function:
   3488  *      pktdma_soc_turn_off_idb_fc
   3489  * Purpose:
   3490  *      Turn off IDB flow control.
   3491  * Parameters:
   3492  *      unit: StrataSwitch Unit #.
   3493  *      idb_fcc_regs: pionter to IDB flow control regs.
   3494  *      a_size: num of regs in idb_fcc_regs
   3495  *
   3496  * Returns:
   3497  *     Nothing
   3498  */
   3499 static void
   3500 pktdma_soc_turn_off_idb_fc(int unit, soc_reg_t *idb_fcc_regs, int a_size)
   3501 {
   3502     int obm_subp;
   3503     int idx;
   3504     uint64 idb_fc;
   3505     soc_field_t idb_flow_control_config_fields[] =
   3506         { PORT_FC_ENf, LOSSLESS1_FC_ENf, LOSSLESS0_FC_ENf,
   3507         LOSSLESS1_PRIORITY_PROFILEf, LOSSLESS0_PRIORITY_PROFILEf
   3508     };
   3509     uint32 idb_flow_control_config_values[] = { 0x0, 0x0, 0x0, 0xff, 0xff };
   3510 
   3511     cli_out("\nTurning off flow control at IDB/MMU");
   3512 
   3513     COMPILER_64_SET(idb_fc, 0x0, 0x0);
   3514 
   3515     if (SOC_REG_IS_VALID(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r)) {
   3516         soc_reg_fields32_modify(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
   3517                                 REG_PORT_ANY, 5, idb_flow_control_config_fields,
   3518                                 idb_flow_control_config_values);
   3519         (void) soc_reg_get(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 0, 0, &idb_fc);
   3520     }
   3521 
   3522     for (obm_subp = 0; obm_subp < NUM_SUBP_OBM; obm_subp++) {
   3523         for(idx = 0; idx < a_size; idx++) {
   3524             if(SOC_REG_IS_VALID(unit, idb_fcc_regs[idx])) {
   3525                 (void) soc_reg_set(unit, idb_fcc_regs[idx], 0, obm_subp, idb_fc);
   3526             }
   3527         }
   3528     }
   3529 }
   3530 
   3531 /*
   3532  * Function:
   3533  *      pktdma_soc_turn_off_fc
   3534  * Purpose:
   3535  *      Turn off flow control at the MAC, IDB and MMU.
   3536  * Parameters:
   3537  *      unit: StrataSwitch Unit #.
   3538  *
   3539  * Returns:
   3540  *     Nothing
   3541  */
   3542 
   3543 static void
   3544 pktdma_soc_turn_off_fc(int unit)
   3545 {
   3546     int p;
   3547     int idx;
   3548     int a_size = 0;
   3549 
   3550     soc_reg_t idb_fcc_regs[] = {
   3551         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
   3552         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r,
   3553         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r,
   3554         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r,
   3555         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r,
   3556         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r,
   3557         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r,
   3558         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r,
   3559         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r,
   3560         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r,
   3561         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r,
   3562         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r,
   3563         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE1r,
   3564         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE1r,
   3565         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE1r,
   3566         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE1r,
   3567         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r,
   3568         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r,
   3569         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r,
   3570         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r,
   3571         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE2r,
   3572         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE2r,
   3573         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE2r,
   3574         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE2r,
   3575         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r,
   3576         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r,
   3577         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r,
   3578         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r,
   3579         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE3r,
   3580         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE3r,
   3581         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE3r,
   3582         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE3r
   3583     };
   3584 
   3585 #ifdef BCM_TOMAHAWK2_SUPPORT
   3586     soc_reg_t idb_fcc_regs_th2[] = {
   3587         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
   3588         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r,
   3589         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r,
   3590         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r,
   3591         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r,
   3592         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r,
   3593         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r,
   3594         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r,
   3595         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r,
   3596         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r,
   3597         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r,
   3598         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r,
   3599         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r,
   3600         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r,
   3601         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r,
   3602         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r,
   3603         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r,
   3604         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r,
   3605         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r,
   3606         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r,
   3607         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE1r,
   3608         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE1r,
   3609         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE1r,
   3610         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE1r,
   3611         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE1r,
   3612         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE1r,
   3613         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE1r,
   3614         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE1r,
   3615         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE1r,
   3616         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE1r,
   3617         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE1r,
   3618         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE1r,
   3619         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r,
   3620         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r,
   3621         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r,
   3622         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r,
   3623         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE2r,
   3624         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE2r,
   3625         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE2r,
   3626         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE2r,
   3627         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE2r,
   3628         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE2r,
   3629         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE2r,
   3630         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE2r,
   3631         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE2r,
   3632         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE2r,
   3633         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE2r,
   3634         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE2r,
   3635         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r,
   3636         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r,
   3637         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r,
   3638         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r,
   3639         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE3r,
   3640         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE3r,
   3641         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE3r,
   3642         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE3r,
   3643         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE3r,
   3644         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE3r,
   3645         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE3r,
   3646         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE3r,
   3647         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE3r,
   3648         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE3r,
   3649         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE3r,
   3650         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE3r
   3651     };
   3652 #endif
   3653 
   3654 #ifdef BCM_TRIDENT3_SUPPORT
   3655     soc_reg_t idb_fcc_regs_td3[] = {
   3656         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
   3657         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r,
   3658         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r,
   3659         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r,
   3660         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r,
   3661         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r,
   3662         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r,
   3663         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r,
   3664         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r,
   3665         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r,
   3666         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r,
   3667         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r,
   3668         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r,
   3669         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r,
   3670         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r,
   3671         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r,
   3672         IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r,
   3673         IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r,
   3674         IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r,
   3675         IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r,
   3676         IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE1r,
   3677         IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE1r,
   3678         IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE1r,
   3679         IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE1r,
   3680         IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE1r,
   3681         IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE1r,
   3682         IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE1r,
   3683         IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE1r,
   3684         IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE1r,
   3685         IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE1r,
   3686         IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE1r,
   3687         IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE1r
   3688     };
   3689 #endif
   3690 
   3691     soc_reg_t pgw_fcc_regs[] = {
   3692         PGW_OBM_PORT0_FC_CONFIGr,
   3693         PGW_OBM_PORT1_FC_CONFIGr,
   3694         PGW_OBM_PORT2_FC_CONFIGr,
   3695         PGW_OBM_PORT3_FC_CONFIGr,
   3696         PGW_OBM_PORT4_FC_CONFIGr,
   3697         PGW_OBM_PORT5_FC_CONFIGr,
   3698         PGW_OBM_PORT6_FC_CONFIGr,
   3699         PGW_OBM_PORT7_FC_CONFIGr,
   3700         PGW_OBM_PORT8_FC_CONFIGr,
   3701         PGW_OBM_PORT9_FC_CONFIGr,
   3702         PGW_OBM_PORT10_FC_CONFIGr,
   3703         PGW_OBM_PORT11_FC_CONFIGr,
   3704         PGW_OBM_PORT12_FC_CONFIGr,
   3705         PGW_OBM_PORT13_FC_CONFIGr,
   3706         PGW_OBM_PORT14_FC_CONFIGr,
   3707         PGW_OBM_PORT15_FC_CONFIGr
   3708     };
   3709 
   3710     cli_out("\nTurning off flow control at IDB/MMU");
   3711 
   3712     if (SOC_REG_IS_VALID(unit, THDI_INPUT_PORT_XON_ENABLESr)) {
   3713         PBMP_ITER(PBMP_PORT_ALL(unit), p) {
   3714             bcm_port_pause_set(unit, p, FALSE, FALSE);
   3715             soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr, p,
   3716                                    PORT_PAUSE_ENABLEf, 0x0);
   3717         }
   3718         soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr, 0,
   3719                                PORT_PAUSE_ENABLEf, 0x0);
   3720     } else {
   3721         cli_out("\n*ERROR, invalid reg %s\n",
   3722                 SOC_REG_NAME(unit, THDI_INPUT_PORT_XON_ENABLESr));
   3723     }
   3724 
   3725 #ifdef BCM_TRIDENT3_SUPPORT
   3726     if (SOC_IS_TRIDENT3X(unit)) {
   3727         a_size = sizeof(idb_fcc_regs_td3) / sizeof(soc_reg_t);
   3728         pktdma_soc_turn_off_idb_fc(unit, idb_fcc_regs_td3, a_size);
   3729     }
   3730 #endif
   3731 #ifdef BCM_TOMAHAWK2_SUPPORT
   3732     if (SOC_IS_TOMAHAWK2(unit)) {
   3733         a_size = sizeof(idb_fcc_regs_th2) / sizeof(soc_reg_t);
   3734         pktdma_soc_turn_off_idb_fc(unit, idb_fcc_regs_th2, a_size);
   3735     }
   3736 #endif
   3737     if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT2PLUS(unit)) {
   3738         a_size = sizeof(idb_fcc_regs) / sizeof(soc_reg_t);
   3739         pktdma_soc_turn_off_idb_fc(unit, idb_fcc_regs, a_size);
   3740         for (idx = 0; idx < (sizeof(pgw_fcc_regs) / sizeof(soc_reg_t)); idx++) {
   3741             if (SOC_REG_IS_VALID(unit, pgw_fcc_regs[idx])) {
   3742                 soc_reg_field32_modify(unit, pgw_fcc_regs[idx], REG_PORT_ANY,
   3743                                        PORT_FC_ENABLEf, 0x0);
   3744             }
   3745         }
   3746     }
   3747 }
   3748 
   3749 /*
   3750  * Function:
   3751  *      pktdma_soc_check_for_stall
   3752  * Purpose:
   3753  *      Check for stalls on TX/RX DMA channels
   3754  * Parameters:
   3755  *      unit: StrataSwitch Unit #.
   3756  *      pkt_size: Packet size in bytes
   3757  *      interval_in_seconds: Interval over which rate is measured
   3758  *
   3759  * Returns:
   3760  *     Nothing
   3761  */
   3762 
   3763 static void
   3764 pktdma_soc_check_for_stall(int unit)
   3765 {
   3766     uint32 cmc, ch;
   3767     int32 vchan;
   3768     uint32 cmc_max, ch_max;
   3769     uint32 **tx_pkt_s = NULL;
   3770     uint32 **rx_pkt_s = NULL;
   3771     uint32 **tx_pkt_e = NULL;
   3772     uint32 **rx_pkt_e = NULL;
   3773 
   3774     pktdma_t *pktdma_p = pktdma_parray[unit];
   3775 
   3776     /* malloc */
   3777     cmc_max = SOC_CMCS_NUM(unit);
   3778     ch_max  = DMA_CHAN_PER_CMC(unit);
   3779     tx_pkt_s = sal_alloc(sizeof(uint32 *) * cmc_max, "txs_l1");
   3780     rx_pkt_s = sal_alloc(sizeof(uint32 *) * cmc_max, "rxs_l1");
   3781     tx_pkt_e = sal_alloc(sizeof(uint32 *) * cmc_max, "txe_l1");
   3782     rx_pkt_e = sal_alloc(sizeof(uint32 *) * cmc_max, "rxe_l1");
   3783     for (cmc = 0; cmc < cmc_max; cmc++) {
   3784         tx_pkt_s[cmc] = sal_alloc(sizeof(uint32) * ch_max, "txs_l2");
   3785         rx_pkt_s[cmc] = sal_alloc(sizeof(uint32) * ch_max, "rxs_l2");
   3786         tx_pkt_e[cmc] = sal_alloc(sizeof(uint32) * ch_max, "txe_l2");
   3787         rx_pkt_e[cmc] = sal_alloc(sizeof(uint32) * ch_max, "rxe_l2");
   3788         sal_memset(tx_pkt_s[cmc], 0, sizeof(uint32) * ch_max);
   3789         sal_memset(rx_pkt_s[cmc], 0, sizeof(uint32) * ch_max);
   3790         sal_memset(tx_pkt_e[cmc], 0, sizeof(uint32) * ch_max);
   3791         sal_memset(rx_pkt_e[cmc], 0, sizeof(uint32) * ch_max);
   3792     }
   3793 
   3794     for (cmc = 0; cmc < cmc_max; cmc++) {
   3795         for (ch = 0; ch < ch_max; ch++) {
   3796             vchan = cmc * ch_max + ch;
   3797             soc_dma_chan_counter_get(unit, vchan,
   3798                                      &tx_pkt_s[cmc][ch],
   3799                                      &rx_pkt_s[cmc][ch]);
   3800         }
   3801     }
   3802 
   3803     cli_out("\nChecking for stalls, wait 1s");
   3804     sal_usleep(1000000);
   3805 
   3806     for (cmc = 0; cmc < cmc_max; cmc++) {
   3807         for (ch = 0; ch < ch_max; ch++) {
   3808             vchan = cmc * ch_max + ch;
   3809             soc_dma_chan_counter_get(unit, vchan,
   3810                                      &tx_pkt_e[cmc][ch],
   3811                                      &rx_pkt_e[cmc][ch]);
   3812 
   3813             if ((tx_pkt_e[cmc][ch] != 0) &&
   3814                 (tx_pkt_e[cmc][ch] == tx_pkt_s[cmc][ch])) {
   3815                 test_error(unit, "\nTXDMA on CMC %0d, CH %0d stalled", cmc, ch);
   3816                 pktdma_p->test_fail = 1;
   3817             }
   3818 
   3819             if ((rx_pkt_e[cmc][ch] != 0) &&
   3820                 (rx_pkt_e[cmc][ch] == rx_pkt_s[cmc][ch])) {
   3821                 test_error(unit, "\nRXDMA on CMC %0d, CH %0d stalled", cmc, ch);
   3822                 pktdma_p->test_fail = 1;
   3823             }
   3824         }
   3825     }
   3826 
   3827     /* free */
   3828     for (cmc = 0; cmc < cmc_max; cmc++) {
   3829         sal_free(tx_pkt_s[cmc]);
   3830         sal_free(rx_pkt_s[cmc]);
   3831         sal_free(tx_pkt_e[cmc]);
   3832         sal_free(rx_pkt_e[cmc]);
   3833     }
   3834     sal_free(tx_pkt_s);
   3835     sal_free(rx_pkt_s);
   3836     sal_free(tx_pkt_e);
   3837     sal_free(rx_pkt_e);
   3838 }
   3839 
   3840 /*
   3841  * Function:
   3842  *      pktdma_convert_pbs_to_mpbs
   3843  * Purpose:
   3844  *      Calculate TX and RX data rates in bps for fixed size packets and in
   3845  *      pps (packets per second) for random sized packets
   3846  * Parameters:
   3847  *      unit: StrataSwitch Unit #.
   3848  *      pkt_size: Packet size in bytes
   3849  *      interval_in_seconds: Interval over which rate is measured
   3850  *
   3851  * Returns:
   3852  *     Nothing
   3853  */
   3854 static void
   3855 pktdma_convert_pbs_to_mpbs(uint64 bps)
   3856 {
   3857     uint64 meg_64;
   3858     uint32 mbps_hi_32, mbps_lo_32;
   3859     COMPILER_64_SET(meg_64, 0, 1000000);
   3860 
   3861     mbps_lo_32 = (uint32) COMPILER_64_LO(bps) % 1000000;
   3862     COMPILER_64_UDIV_64(bps, meg_64);
   3863     mbps_hi_32 = (uint32) COMPILER_64_LO(bps);
   3864 
   3865     if (mbps_lo_32 / 100000 > 0) {
   3866         cli_out(" (%0d.%0d Mbps)", mbps_hi_32, mbps_lo_32);
   3867     } else if (mbps_lo_32 / 10000 > 0) {
   3868         cli_out(" (%0d.0%0d Mbps)", mbps_hi_32, mbps_lo_32);
   3869     } else if (mbps_lo_32 / 1000 > 0) {
   3870         cli_out(" (%0d.00%0d Mbps)", mbps_hi_32, mbps_lo_32);
   3871     } else {
   3872         cli_out(" (%0d.000 Mbps)", mbps_hi_32);
   3873     }
   3874 }
   3875 
   3876 static void
   3877 pktdma_soc_get_counter_pkt_chan(int unit, uint32 vchan,
   3878                                 uint32 *tpkt, uint32 *rpkt)
   3879 {
   3880     (void) soc_dma_chan_counter_get(unit, vchan, tpkt, rpkt);
   3881 }
   3882 
   3883 static void
   3884 pktdma_soc_get_counter_pkt_cmc(int unit, uint32 cmc,
   3885                                uint32 *tpkt, uint32 *rpkt)
   3886 {
   3887     (void) soc_dma_cmc_counter_get(unit, cmc, tpkt, rpkt);
   3888 }
   3889 
   3890 /*
   3891  * Function:
   3892  *      pktdma_calc_rate_bps
   3893  * Purpose:
   3894  *      Calculate rate in bps from packet counter values
   3895  * Parameters:
   3896  *      pkt_num: number of packets
   3897  *      bytes: bytes per pkt (includes IPG and preamble)
   3898  *      interval_usecs: Interval over which rate is measured (usec)
   3899  *
   3900  * Returns:
   3901  *     Rate in bps
   3902  */
   3903 
   3904 static void
   3905 pktdma_calc_rate_bps(uint32 pkt_num, uint32 bytes_per_pkt,
   3906                      sal_usecs_t interval_usecs, uint64 *bps) {
   3907     uint64 rate_bps;
   3908     uint32 time_usecs_32 = (uint32) interval_usecs;
   3909     uint64 time_usecs_64;
   3910 
   3911     COMPILER_64_ZERO(*bps);
   3912     COMPILER_64_ZERO(rate_bps);
   3913     if (time_usecs_32 > 0) {
   3914         COMPILER_64_ZERO(time_usecs_64);
   3915         COMPILER_64_SET(time_usecs_64, 0x0, time_usecs_32);
   3916         COMPILER_64_SET(rate_bps, 0x0, pkt_num);
   3917         COMPILER_64_UMUL_32(rate_bps, (bytes_per_pkt * 8));
   3918         COMPILER_64_UMUL_32(rate_bps, 1000000);
   3919         COMPILER_64_UDIV_64(rate_bps, time_usecs_64);
   3920     }
   3921 
   3922     COMPILER_64_SET(*bps, COMPILER_64_HI(rate_bps), COMPILER_64_LO(rate_bps));
   3923 }
   3924 
   3925 /*
   3926  * Function:
   3927  *      pktdma_calc_rate_bps_pps
   3928  * Purpose:
   3929  *      Calculate rate in bps and pps from packet counter values
   3930  * Parameters:
   3931  *      pkt_num: number of packets
   3932  *      bytes: bytes per pkt (includes IPG and preamble)
   3933  *      interval_usecs: Interval over which rate is measured (usec)
   3934  *
   3935  * Returns:
   3936  *     Rate in bps and pps
   3937  */
   3938 
   3939 static void
   3940 pktdma_calc_rate_bps_pps(uint32 pkt_num, uint32 bytes_per_pkt,
   3941                      sal_usecs_t interval_usecs, uint64 *bps,  uint64 *pps) {
   3942     uint64 rate_bps;
   3943     uint64 rate_pps;
   3944     uint32 time_usecs_32 = (uint32) interval_usecs;
   3945     uint64 time_usecs_64;
   3946 
   3947     COMPILER_64_ZERO(*bps);
   3948     COMPILER_64_ZERO(*pps);
   3949     COMPILER_64_ZERO(rate_bps);
   3950     COMPILER_64_ZERO(rate_pps);
   3951     if (time_usecs_32 > 0) {
   3952         COMPILER_64_ZERO(time_usecs_64);
   3953         COMPILER_64_SET(time_usecs_64, 0x0, time_usecs_32);
   3954         COMPILER_64_SET(rate_bps, 0x0, pkt_num);
   3955         COMPILER_64_SET(rate_pps, 0x0, pkt_num);
   3956         COMPILER_64_UMUL_32(rate_bps, (bytes_per_pkt * 8));
   3957         COMPILER_64_UMUL_32(rate_bps, 1000000);
   3958         COMPILER_64_UMUL_32(rate_pps, 1000000);
   3959         COMPILER_64_UDIV_64(rate_bps, time_usecs_64);
   3960         COMPILER_64_UDIV_64(rate_pps, time_usecs_64);
   3961     }
   3962 
   3963     COMPILER_64_SET(*bps, COMPILER_64_HI(rate_bps), COMPILER_64_LO(rate_bps));
   3964     COMPILER_64_SET(*pps, COMPILER_64_HI(rate_pps), COMPILER_64_LO(rate_pps));
   3965 }
   3966 
   3967 
   3968 
   3969 /*
   3970  * Function:
   3971  *      pktdma_soc_calc_rate_bps
   3972  * Purpose:
   3973  *      Calculate TX and RX data rates in bps for fixed size packets and in
   3974  *      pps (packets per second) for random sized packets
   3975  * Parameters:
   3976  *      unit: StrataSwitch Unit #.
   3977  *      pkt_size: Packet size in bytes
   3978  *      interval_in_seconds: Interval over which rate is measured
   3979  *
   3980  * Returns:
   3981  *     Nothing
   3982  */
   3983 static int
   3984 pktdma_soc_calc_rate_bps(int unit, uint32 pkt_size, uint32 interval_in_seconds)
   3985 {
   3986     uint32 cmc, ch, cmc_max, ch_max, vchan;
   3987     uint32 tpkt, rpkt;
   3988     uint64 bps, pps;
   3989     char bps_str[32], pps_str[32];
   3990     pktdma_t *pktdma_p = pktdma_parray[unit];
   3991     sal_usecs_t usecs_td;
   3992     uint32 pkt_num;
   3993     uint32 bytes_per_pkt;
   3994     uint64 total_rate_tx;
   3995     uint64 total_rate_rx;
   3996     uint64 total_pps_tx;
   3997     uint64 total_pps_rx;
   3998 
   3999     uint32 **ch_tx_ps = NULL;
   4000     uint32 **ch_rx_ps = NULL;
   4001     uint32 **ch_tx_pe = NULL;
   4002     uint32 **ch_rx_pe = NULL;
   4003     uint32 *cmc_tx_ps = NULL;
   4004     uint32 *cmc_rx_ps = NULL;
   4005     uint32 *cmc_tx_pe = NULL;
   4006     uint32 *cmc_rx_pe = NULL;
   4007     sal_usecs_t **ch_tx_ts = NULL;
   4008     sal_usecs_t **ch_rx_ts = NULL;
   4009     sal_usecs_t **ch_tx_te = NULL;
   4010     sal_usecs_t **ch_rx_te = NULL;
   4011     sal_usecs_t *cmc_tx_ts = NULL;
   4012     sal_usecs_t *cmc_rx_ts = NULL;
   4013     sal_usecs_t *cmc_tx_te = NULL;
   4014     sal_usecs_t *cmc_rx_te = NULL;
   4015 
   4016 #ifdef BCM_CMICX_SUPPORT
   4017     if (soc_feature(unit, soc_feature_cmicx)) {
   4018         cmc_max = SOC_CMCS_NUM(unit);
   4019         ch_max  = DMA_CHAN_PER_CMC(unit);
   4020     } else
   4021 #endif
   4022     if (soc_feature(unit, soc_feature_cmicm)) {
   4023         cmc_max = SOC_CMCS_NUM(unit);
   4024         ch_max  = N_DMA_CHAN;
   4025     } else {
   4026         cmc_max = SOC_CMCS_NUM(unit);
   4027         ch_max  = 4;
   4028     }
   4029     cli_out("\nMAX_CMC_NUM %0d", cmc_max);
   4030     cli_out("\nMAX_CHAN_PER_CMC %0d", ch_max);
   4031     cli_out("\nStart measuring TX/RX rate");
   4032 
   4033     /* malloc */
   4034     ch_tx_ps = sal_alloc(sizeof(uint32 *) * cmc_max, "ch_tx_ps_l1");
   4035     ch_rx_ps = sal_alloc(sizeof(uint32 *) * cmc_max, "ch_rx_ps_l1");
   4036     ch_tx_pe = sal_alloc(sizeof(uint32 *) * cmc_max, "ch_tx_pe_l1");
   4037     ch_rx_pe = sal_alloc(sizeof(uint32 *) * cmc_max, "ch_rx_pe_l1");
   4038     ch_tx_ts = sal_alloc(sizeof(sal_usecs_t *) * cmc_max, "ch_tx_ts_l1");
   4039     ch_rx_ts = sal_alloc(sizeof(sal_usecs_t *) * cmc_max, "ch_rx_ts_l1");
   4040     ch_tx_te = sal_alloc(sizeof(sal_usecs_t *) * cmc_max, "ch_tx_te_l1");
   4041     ch_rx_te = sal_alloc(sizeof(sal_usecs_t *) * cmc_max, "ch_rx_te_l1");
   4042     for (cmc = 0; cmc < cmc_max; cmc++) {
   4043         ch_tx_ps[cmc]  = sal_alloc(sizeof(uint32) * ch_max, "ch_tx_ps_l2");
   4044         ch_rx_ps[cmc]  = sal_alloc(sizeof(uint32) * ch_max, "ch_rx_ps_l2");
   4045         ch_tx_pe[cmc]  = sal_alloc(sizeof(uint32) * ch_max, "ch_tx_pe_l2");
   4046         ch_rx_pe[cmc]  = sal_alloc(sizeof(uint32) * ch_max, "ch_rx_pe_l2");
   4047         ch_tx_ts[cmc] = sal_alloc(sizeof(sal_usecs_t) * ch_max, "ch_tx_ts_l2");
   4048         ch_rx_ts[cmc] = sal_alloc(sizeof(sal_usecs_t) * ch_max, "ch_rx_ts_l2");
   4049         ch_tx_te[cmc] = sal_alloc(sizeof(sal_usecs_t) * ch_max, "ch_tx_te_l2");
   4050         ch_rx_te[cmc] = sal_alloc(sizeof(sal_usecs_t) * ch_max, "ch_rx_te_l2");
   4051     }
   4052     cmc_tx_ps = sal_alloc(sizeof(uint32)   * cmc_max, "cmc_tx_ps");
   4053     cmc_rx_ps = sal_alloc(sizeof(uint32)   * cmc_max, "cmc_rx_ps");
   4054     cmc_tx_pe = sal_alloc(sizeof(uint32)   * cmc_max, "cmc_tx_pe");
   4055     cmc_rx_pe = sal_alloc(sizeof(uint32)   * cmc_max, "cmc_rx_pe");
   4056     cmc_tx_ts = sal_alloc(sizeof(sal_usecs_t) * cmc_max, "cmc_tx_ts");
   4057     cmc_rx_ts = sal_alloc(sizeof(sal_usecs_t) * cmc_max, "cmc_rx_ts");
   4058     cmc_tx_te = sal_alloc(sizeof(sal_usecs_t) * cmc_max, "cmc_tx_te");
   4059     cmc_rx_te = sal_alloc(sizeof(sal_usecs_t) * cmc_max, "cmc_rx_te");
   4060 
   4061     /* init */
   4062     COMPILER_64_ZERO(total_rate_tx);
   4063     COMPILER_64_ZERO(total_rate_rx);
   4064     COMPILER_64_ZERO(total_pps_tx);
   4065     COMPILER_64_ZERO(total_pps_rx);
   4066     COMPILER_64_ZERO(bps);
   4067     COMPILER_64_ZERO(pps);
   4068 
   4069     for (cmc = 0; cmc < cmc_max; cmc++) {
   4070         sal_memset(ch_tx_ps[cmc], 0, sizeof(uint32) * ch_max);
   4071         sal_memset(ch_rx_ps[cmc], 0, sizeof(uint32) * ch_max);
   4072         sal_memset(ch_tx_pe[cmc], 0, sizeof(uint32) * ch_max);
   4073         sal_memset(ch_rx_pe[cmc], 0, sizeof(uint32) * ch_max);
   4074         sal_memset(ch_tx_ts[cmc], 0, sizeof(sal_usecs_t) * ch_max);
   4075         sal_memset(ch_rx_ts[cmc], 0, sizeof(sal_usecs_t) * ch_max);
   4076         sal_memset(ch_tx_te[cmc], 0, sizeof(sal_usecs_t) * ch_max);
   4077         sal_memset(ch_rx_te[cmc], 0, sizeof(sal_usecs_t) * ch_max);
   4078     }
   4079     sal_memset(cmc_tx_ps, 0, sizeof(uint32) * cmc_max);
   4080     sal_memset(cmc_rx_ps, 0, sizeof(uint32) * cmc_max);
   4081     sal_memset(cmc_tx_pe, 0, sizeof(uint32) * cmc_max);
   4082     sal_memset(cmc_rx_pe, 0, sizeof(uint32) * cmc_max);
   4083     sal_memset(cmc_tx_ts, 0, sizeof(sal_usecs_t) * cmc_max);
   4084     sal_memset(cmc_rx_ts, 0, sizeof(sal_usecs_t) * cmc_max);
   4085     sal_memset(cmc_tx_te, 0, sizeof(sal_usecs_t) * cmc_max);
   4086     sal_memset(cmc_rx_te, 0, sizeof(sal_usecs_t) * cmc_max);
   4087 
   4088     /* record start pkt and time */
   4089     for (cmc = 0; cmc < cmc_max; cmc++) {
   4090         for (ch = 0; ch < ch_max; ch++) {
   4091             vchan = (cmc * ch_max) + ch;
   4092             pktdma_soc_get_counter_pkt_chan(unit, vchan, &tpkt, &rpkt);
   4093             ch_tx_ts[cmc][ch] = sal_time_usecs();
   4094             ch_rx_ts[cmc][ch] = sal_time_usecs();
   4095             ch_tx_ps[cmc][ch] = tpkt;
   4096             ch_rx_ps[cmc][ch] = rpkt;
   4097         }
   4098         pktdma_soc_get_counter_pkt_cmc(unit, cmc, &tpkt, &rpkt);
   4099         cmc_tx_ts[cmc] = sal_time_usecs();
   4100         cmc_rx_ts[cmc] = sal_time_usecs();
   4101         cmc_tx_ps[cmc] = tpkt;
   4102         cmc_rx_ps[cmc] = rpkt;
   4103     }
   4104 
   4105     /* wait for interval_in_seconds */
   4106     /* sal_sleep(interval_in_seconds); */
   4107     sal_usleep(interval_in_seconds * 1000000);
   4108 
   4109     /* record end pkt and time */
   4110     for (cmc = 0; cmc < cmc_max; cmc++) {
   4111         for (ch = 0; ch < ch_max; ch++) {
   4112             vchan = (cmc * ch_max) + ch;
   4113             pktdma_soc_get_counter_pkt_chan(unit, vchan, &tpkt, &rpkt);
   4114             ch_tx_te[cmc][ch] = sal_time_usecs();
   4115             ch_rx_te[cmc][ch] = sal_time_usecs();
   4116             ch_tx_pe[cmc][ch] = tpkt;
   4117             ch_rx_pe[cmc][ch] = rpkt;
   4118         }
   4119         pktdma_soc_get_counter_pkt_cmc(unit, cmc, &tpkt, &rpkt);
   4120         cmc_tx_te[cmc] = sal_time_usecs();
   4121         cmc_rx_te[cmc] = sal_time_usecs();
   4122         cmc_tx_pe[cmc] = tpkt;
   4123         cmc_rx_pe[cmc] = rpkt;
   4124     }
   4125 
   4126     /* calculate TX/RX rate */
   4127     if (pktdma_p->pkt_size_param != 0) {
   4128         /* calcualte and print TX rate */
   4129         cli_out("\n------------------ TX Rates -------------------\n");
   4130         for (cmc = 0; cmc < cmc_max; cmc++) {
   4131             for (ch = 0; ch < ch_max; ch++) {
   4132                 pkt_num  = ch_tx_pe[cmc][ch] - ch_tx_ps[cmc][ch];
   4133                 bytes_per_pkt = pkt_size + ENET_IPG + ENET_PREAMBLE;
   4134                 usecs_td = SAL_USECS_SUB(ch_tx_te[cmc][ch],
   4135                                          ch_tx_ts[cmc][ch]);
   4136                 pktdma_calc_rate_bps_pps(pkt_num, bytes_per_pkt, usecs_td, &bps, &pps);
   4137                 format_uint64_decimal(bps_str, bps, 0);
   4138                 format_uint64_decimal(pps_str, pps, 0);
   4139                 cli_out("\nCMC%0d, CH%0d : %s pps %s bps", cmc, ch, pps_str, bps_str);
   4140                 pktdma_convert_pbs_to_mpbs(bps);
   4141             }
   4142             pkt_num  = cmc_tx_pe[cmc] - cmc_tx_ps[cmc];
   4143             bytes_per_pkt = pkt_size + ENET_IPG + ENET_PREAMBLE;
   4144             usecs_td = SAL_USECS_SUB(cmc_tx_te[cmc],
   4145                                      cmc_tx_ts[cmc]);
   4146             pktdma_calc_rate_bps_pps(pkt_num, bytes_per_pkt, usecs_td, &bps, &pps);
   4147             COMPILER_64_ADD_64(total_rate_tx, bps);
   4148             COMPILER_64_ADD_64(total_pps_tx, pps);
   4149 
   4150             format_uint64_decimal(bps_str, bps, 0);
   4151             format_uint64_decimal(pps_str, pps, 0);
   4152             cli_out("\n\nCMC%0d : %s pps %s bps", cmc, pps_str, bps_str);
   4153             pktdma_convert_pbs_to_mpbs(bps);
   4154             cli_out("\n\n");
   4155         }
   4156 
   4157         format_uint64_decimal(bps_str, total_rate_tx, 0);
   4158         format_uint64_decimal(pps_str, total_pps_tx, 0);
   4159         cli_out("\n****Total TX rate from all CMICs : %s pps %s bps", pps_str, bps_str);
   4160         pktdma_convert_pbs_to_mpbs(total_rate_tx);
   4161 
   4162         /* calcualte and print RX rate */
   4163         cli_out("\n------------------ RX Rates -------------------\n");
   4164         for (cmc = 0; cmc < cmc_max; cmc++) {
   4165             for (ch = 0; ch < ch_max; ch++) {
   4166                 pkt_num  = ch_rx_pe[cmc][ch] - ch_rx_ps[cmc][ch];
   4167                 bytes_per_pkt = pkt_size + ENET_IPG + ENET_PREAMBLE;
   4168                 usecs_td = SAL_USECS_SUB(ch_rx_te[cmc][ch],
   4169                                          ch_rx_ts[cmc][ch]);
   4170                 pktdma_calc_rate_bps_pps(pkt_num, bytes_per_pkt, usecs_td, &bps, &pps);
   4171                 format_uint64_decimal(bps_str, bps, 0);
   4172                 format_uint64_decimal(pps_str, pps, 0);
   4173                 cli_out("\nCMC%0d, CH%0d : %s pps %s bps", cmc, ch, pps_str, bps_str);
   4174                 pktdma_convert_pbs_to_mpbs(bps);
   4175             }
   4176             pkt_num  = cmc_rx_pe[cmc] - cmc_rx_ps[cmc];
   4177             bytes_per_pkt = pkt_size + ENET_IPG + ENET_PREAMBLE;
   4178             usecs_td = SAL_USECS_SUB(cmc_rx_te[cmc],
   4179                                      cmc_rx_ts[cmc]);
   4180             pktdma_calc_rate_bps_pps(pkt_num, bytes_per_pkt, usecs_td, &bps, &pps);
   4181             COMPILER_64_ADD_64(total_rate_rx, bps);
   4182             COMPILER_64_ADD_64(total_pps_rx, pps);
   4183 
   4184             format_uint64_decimal(bps_str, bps, 0);
   4185             format_uint64_decimal(pps_str, pps, 0);
   4186             cli_out("\n\nCMC%0d : %s pps %s bps", cmc, pps_str, bps_str);
   4187             pktdma_convert_pbs_to_mpbs(bps);
   4188             cli_out("\n\n");
   4189         }
   4190 
   4191         format_uint64_decimal(bps_str, total_rate_rx, 0);
   4192         format_uint64_decimal(pps_str, total_pps_rx, 0);
   4193         cli_out("\n****Total RX rate from all CMICs : %s pps %s bps", pps_str, bps_str);
   4194         pktdma_convert_pbs_to_mpbs(total_rate_rx);
   4195     } else {
   4196         /* calcualte and print TX rate */
   4197         cli_out("\n------------------ TX Rates -------------------\n");
   4198         for (cmc = 0; cmc < cmc_max; cmc++) {
   4199             for (ch = 0; ch < ch_max; ch++) {
   4200                 pkt_num  = ch_tx_pe[cmc][ch] - ch_tx_ps[cmc][ch];
   4201                 usecs_td = SAL_USECS_SUB(ch_tx_te[cmc][ch],
   4202                                          ch_tx_ts[cmc][ch]);
   4203                 pktdma_calc_rate_bps(pkt_num, 1, usecs_td, &pps);
   4204                 format_uint64_decimal(pps_str, pps, 0);
   4205                 cli_out("\nCMC%0d, CH%0d : %s pps", cmc, ch, pps_str);
   4206             }
   4207             pkt_num  = cmc_tx_pe[cmc] - cmc_tx_ps[cmc];
   4208             usecs_td = SAL_USECS_SUB(cmc_tx_te[cmc],
   4209                                      cmc_tx_ts[cmc]);
   4210             pktdma_calc_rate_bps(pkt_num, 1, usecs_td, &pps);
   4211             format_uint64_decimal(pps_str, pps, 0);
   4212             cli_out("\nCMC%0d, CH%0d : %s pps", cmc, ch, pps_str);
   4213             cli_out("\n\n");
   4214 
   4215             COMPILER_64_ADD_64(total_rate_tx, pps);
   4216         }
   4217 
   4218         format_uint64_decimal(bps_str, total_rate_tx, 0);
   4219         cli_out("\n****Total TX rate from all CMICs : %s pps", bps_str);
   4220         pktdma_convert_pbs_to_mpbs(total_rate_tx);
   4221 
   4222         /* calcualte and print RX rate */
   4223         cli_out("\n------------------ RX Rates -------------------\n");
   4224         for (cmc = 0; cmc < cmc_max; cmc++) {
   4225             for (ch = 0; ch < ch_max; ch++) {
   4226                 pkt_num  = ch_rx_pe[cmc][ch] - ch_rx_ps[cmc][ch];
   4227                 usecs_td = SAL_USECS_SUB(ch_rx_te[cmc][ch],
   4228                                          ch_rx_ts[cmc][ch]);
   4229                 pktdma_calc_rate_bps(pkt_num, 1, usecs_td, &pps);
   4230                 format_uint64_decimal(pps_str, pps, 0);
   4231                 cli_out("\nCMC%0d, CH%0d : %s pps", cmc, ch, pps_str);
   4232             }
   4233             pkt_num  = cmc_rx_pe[cmc] - cmc_rx_ps[cmc];
   4234             usecs_td = SAL_USECS_SUB(cmc_rx_te[cmc],
   4235                                      cmc_rx_ts[cmc]);
   4236             pktdma_calc_rate_bps(pkt_num, 1, usecs_td, &pps);
   4237             format_uint64_decimal(pps_str, pps, 0);
   4238             cli_out("\nCMC%0d, CH%0d : %s pps", cmc, ch, pps_str);
   4239             cli_out("\n\n");
   4240 
   4241             COMPILER_64_ADD_64(total_rate_rx, pps);
   4242         }
   4243 
   4244         format_uint64_decimal(bps_str, total_rate_rx, 0);
   4245         cli_out("\n****Total TX rate from all CMICs : %s pps", bps_str);
   4246         pktdma_convert_pbs_to_mpbs(total_rate_rx);
   4247     }
   4248 
   4249     /* check */
   4250     for (cmc = 0; cmc < cmc_max; cmc++) {
   4251         for (ch = 0; ch < ch_max; ch++) {
   4252             if ((((pktdma_p->tx_bitmap_param >> (ch_max * cmc + ch)) % 2)
   4253                 != 0) && ch_tx_pe[cmc][ch] == 0) {
   4254                 test_error(unit, "\nTXDMA enabled on CMC %0d, CH %0d, but "
   4255                                  "no packets sent", cmc, ch);
   4256                 pktdma_p->test_fail = 1;
   4257             }
   4258 
   4259             if ((((pktdma_p->rx_bitmap_param >> (ch_max * cmc + ch)) % 2)
   4260                 != 0) && ch_rx_pe[cmc][ch] == 0) {
   4261                 test_error(unit, "\nRXDMA enabled on CMC %0d, CH %0d, but "
   4262                                  "no packets received", cmc, ch);
   4263                 pktdma_p->test_fail = 1;
   4264             }
   4265         }
   4266     }
   4267 
   4268     pktdma_soc_check_for_stall(unit);
   4269 
   4270     /* free */
   4271     for (cmc = 0; cmc < cmc_max; cmc++) {
   4272         sal_free(ch_tx_ps[cmc]);
   4273         sal_free(ch_rx_ps[cmc]);
   4274         sal_free(ch_tx_pe[cmc]);
   4275         sal_free(ch_rx_pe[cmc]);
   4276         sal_free(ch_tx_ts[cmc]);
   4277         sal_free(ch_rx_ts[cmc]);
   4278         sal_free(ch_tx_te[cmc]);
   4279         sal_free(ch_rx_te[cmc]);
   4280     }
   4281     sal_free(ch_tx_ps);
   4282     sal_free(ch_rx_ps);
   4283     sal_free(ch_tx_pe);
   4284     sal_free(ch_rx_pe);
   4285     sal_free(ch_tx_ts);
   4286     sal_free(ch_rx_ts);
   4287     sal_free(ch_tx_te);
   4288     sal_free(ch_rx_te);
   4289     sal_free(cmc_tx_ps);
   4290     sal_free(cmc_rx_ps);
   4291     sal_free(cmc_tx_pe);
   4292     sal_free(cmc_rx_pe);
   4293     sal_free(cmc_tx_ts);
   4294     sal_free(cmc_rx_ts);
   4295     sal_free(cmc_tx_te);
   4296     sal_free(cmc_rx_te);
   4297 
   4298     return SOC_E_NONE;
   4299 }
   4300 
   4301 /*
   4302  * Function:
   4303  *      pktdma_soc_set_up_mac_lpbk
   4304  * Purpose:
   4305  *      Enable MAC loopback on all ports
   4306  * Parameters:
   4307  *      unit: StrataSwitch Unit #.
   4308  *
   4309  * Returns:
   4310  *     Nothing
   4311  */
   4312 
   4313 static void
   4314 pktdma_soc_set_up_mac_lpbk(int unit)
   4315 {
   4316     int32 p;
   4317 
   4318     PBMP_ITER(PBMP_PORT_ALL(unit), p) {
   4319         (void) bcm_port_loopback_set(unit, p, BCM_PORT_LOOPBACK_MAC);
   4320     }
   4321 }
   4322 
   4323 /*
   4324  * Function:
   4325  *      dump_first_dv
   4326  * Purpose:
   4327  *      Dump first DV for each channel
   4328  * Parameters:
   4329  *      unit: StrataSwitch Unit #.
   4330  *
   4331  * Returns:
   4332  *     Nothing
   4333  */
   4334 
   4335 static void
   4336 dump_first_dv(int unit)
   4337 {
   4338     int32 channel;
   4339     int32 dv_cont;
   4340     pktdma_t *pktdma_p = pktdma_parray[unit];
   4341 
   4342     cli_out("\nDumping first DV of each Channel:");
   4343     cli_out("\n=================================");
   4344     for (dv_cont = 0; dv_cont < NUM_CONT_DMA_DV; dv_cont++) {
   4345         if (!((dv_cont > 0) && (pktdma_p->cont_dma == 0))) {
   4346             for (channel = 0; channel < MAX_CHANNELS; channel++) {
   4347                 cli_out("\nChannel %0d", channel);
   4348                 cli_out("\n-----------");
   4349                 cli_out("\n");
   4350                 if (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0) {
   4351                     soc_dma_dump_dv(unit, "[dv_tx_dump]",
   4352                                     pktdma_p->dv_tx_array[dv_cont][channel][0]);
   4353                 }
   4354                 if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   4355                     soc_dma_dump_dv(unit, "[dv_rx_dump]",
   4356                                     pktdma_p->dv_rx_array[dv_cont][channel][0]);
   4357                 }
   4358             }
   4359         }
   4360     }
   4361     cli_out("\nEnd dumping first DV");
   4362     cli_out("\n=====================");
   4363 }
   4364 
   4365 /*
   4366  * Function:
   4367  *      dump_packet_pointers
   4368  * Purpose:
   4369  *      Dump packet pointers for each channel
   4370  * Parameters:
   4371  *      unit: StrataSwitch Unit #.
   4372  *
   4373  * Returns:
   4374  *     Nothing
   4375  */
   4376 
   4377 static void
   4378 dump_packet_pointers(int unit)
   4379 {
   4380     int32 channel, i;
   4381     pktdma_t *pktdma_p = pktdma_parray[unit];
   4382 
   4383     cli_out("\nDumping packet pointers for each channel");
   4384     cli_out("\n****************************************");
   4385 
   4386     for (channel = 0; channel < MAX_CHANNELS; channel++) {
   4387         cli_out("\nDumping TX packet pointers for channel %0d", channel);
   4388         cli_out("\n------------------------------------------\n");
   4389 
   4390         if (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0) {
   4391             for (i = 0; i < pktdma_p->num_pkts_param_tx; i++) {
   4392                 cli_out("%p ", pktdma_p->pkt_tx_array[channel][i]);
   4393             }
   4394         }
   4395         cli_out("\nDumping RX packet pointers for channel %0d", channel);
   4396         cli_out("\n------------------------------------------\n");
   4397         if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   4398             for (i = 0; i < pktdma_p->num_pkts_param_rx; i++) {
   4399                 cli_out("%p ", pktdma_p->pkt_rx_array[channel][i]);
   4400             }
   4401         }
   4402         cli_out("\n");
   4403     }
   4404     cli_out("\nDone dumping packet pointers");
   4405     cli_out("\n*****************************************");
   4406 }
   4407 
   4408 /*
   4409  * Function:
   4410  *      pktdma_soc_free_all_memory
   4411  * Purpose:
   4412  *      Free all allocated memory
   4413  * Parameters:
   4414  *      unit: StrataSwitch Unit #.
   4415  *
   4416  * Returns:
   4417  *     Nothing
   4418  */
   4419 
   4420 
   4421 static void
   4422 pktdma_soc_free_all_memory(int unit)
   4423 {
   4424     pktdma_t *pktdma_p = pktdma_parray[unit];
   4425     int32 i, j, dv_cont;
   4426 
   4427     cli_out("\nFreeing all allocated memory");
   4428     for (i = 0; i < MAX_CHANNELS; i++) {
   4429         sal_free(pktdma_p->random_packet_sizes[i]);
   4430     }
   4431     sal_free(pktdma_p->random_packet_sizes);
   4432 
   4433     for (i = 0; i < MAX_CHANNELS; i++) {
   4434         if (((pktdma_p->tx_bitmap_param >> i) % 2) != 0) {
   4435             for (j = 0; j < pktdma_p->num_pkts_param_tx; j++) {
   4436                 soc_cm_sfree(unit, pktdma_p->pkt_tx_array[i][j]);
   4437             }
   4438             soc_cm_sfree(unit, pktdma_p->pkt_tx_array[i]);
   4439         }
   4440     }
   4441     soc_cm_sfree(unit, pktdma_p->pkt_tx_array);
   4442 
   4443     for (i = 0; i < MAX_CHANNELS; i++) {
   4444         if (((pktdma_p->rx_bitmap_param >> i) % 2) != 0) {
   4445             for (j = 0; j < pktdma_p->num_pkts_param_rx; j++) {
   4446                 soc_cm_sfree(unit, pktdma_p->pkt_rx_array[i][j]);
   4447             }
   4448             soc_cm_sfree(unit, pktdma_p->pkt_rx_array[i]);
   4449         }
   4450     }
   4451     soc_cm_sfree(unit, pktdma_p->pkt_rx_array);
   4452 
   4453     for (dv_cont = 0; dv_cont < NUM_CONT_DMA_DV; dv_cont++) {
   4454         if (!((dv_cont > 0) && (pktdma_p->cont_dma == 0))) {
   4455             for (i = 0; i < MAX_CHANNELS; i++) {
   4456                 if (((pktdma_p->tx_bitmap_param >> i) % 2) != 0) {
   4457                     if (pktdma_p->chain_tx == 0) {
   4458                         for (j = 0; j < pktdma_p->num_pkts_param_tx; j++) {
   4459                             soc_dma_dv_free(unit,
   4460                                             pktdma_p->
   4461                                             dv_tx_array[dv_cont][i][j]);
   4462                         }
   4463                     } else {
   4464                         soc_dma_dv_free(unit,
   4465                                         pktdma_p->dv_tx_array[dv_cont][i][0]);
   4466                     }
   4467                     soc_at_free(unit, pktdma_p->dv_tx_array[dv_cont][i]);
   4468                 }
   4469             }
   4470             soc_at_free(unit, pktdma_p->dv_tx_array[dv_cont]);
   4471 
   4472             for (i = 0; i < MAX_CHANNELS; i++) {
   4473                 if (((pktdma_p->rx_bitmap_param >> i) % 2) != 0) {
   4474                     if (pktdma_p->chain_rx == 0) {
   4475                         for (j = 0; j < pktdma_p->num_pkts_param_rx; j++) {
   4476                             soc_dma_dv_free(unit,
   4477                                             pktdma_p->
   4478                                             dv_rx_array[dv_cont][i][j]);
   4479                         }
   4480                     } else {
   4481                         soc_dma_dv_free(unit,
   4482                                         pktdma_p->dv_rx_array[dv_cont][i][0]);
   4483                     }
   4484                     soc_at_free(unit, pktdma_p->dv_rx_array[dv_cont][i]);
   4485                 }
   4486             }
   4487             soc_at_free(unit, pktdma_p->dv_rx_array[dv_cont]);
   4488         }
   4489     }
   4490 }
   4491 
   4492 /*
   4493  * Function:
   4494  *      dump_interrupt_counts
   4495  * Purpose:
   4496  *      Dump number of times each interrupt was raised.
   4497  * Parameters:
   4498  *      unit: StrataSwitch Unit #.
   4499  *
   4500  * Returns:
   4501  *     Nothing
   4502  */
   4503 
   4504 static void
   4505 dump_interrupt_counts(int unit)
   4506 {
   4507     int32 channel;
   4508     pktdma_t *pktdma_p = pktdma_parray[unit];
   4509 
   4510     cli_out("\nPrinting Interrupt counts");
   4511 
   4512     for (channel = 0; channel < MAX_CHANNELS; channel++) {
   4513         if (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0) {
   4514             cli_out("\nChannel %0d", channel);
   4515             cli_out("\n-----------");
   4516             cli_out("\ndesc_done_count_tx[%0d] = %0d", channel,
   4517                     pktdma_p->desc_done_count_tx[channel]);
   4518             cli_out("\nchain_done_count_tx[%0d] = %0d", channel,
   4519                     pktdma_p->chain_done_count_tx[channel]);
   4520             cli_out("\nreload_done_count_tx[%0d] = %0d", channel,
   4521                     pktdma_p->reload_done_count_tx[channel]);
   4522             cli_out("\n");
   4523         }
   4524 
   4525         if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   4526             cli_out("\nChannel %0d", channel);
   4527             cli_out("\n-----------");
   4528             cli_out("\ndesc_done_count_rx[%0d] = %0d", channel,
   4529                     pktdma_p->desc_done_count_rx[channel]);
   4530             cli_out("\nchain_done_count_rx[%0d] = %0d", channel,
   4531                     pktdma_p->chain_done_count_rx[channel]);
   4532             cli_out("\nreload_done_count_rx[%0d] = %0d", channel,
   4533                     pktdma_p->reload_done_count_rx[channel]);
   4534             cli_out("\n");
   4535         }
   4536     }
   4537 }
   4538 
   4539 /*
   4540  * Function:
   4541  *      set_up_all_dv
   4542  * Purpose:
   4543  *      Set up all DV arrays for all virtual channels.
   4544  * Parameters:
   4545  *      unit: StrataSwitch Unit #.
   4546  *
   4547  * Returns:
   4548  *     Nothing
   4549  */
   4550 
   4551 static void
   4552 set_up_all_dv(int unit)
   4553 {
   4554     int32 channel;
   4555     int32 dv_cont;
   4556     pktdma_t *pktdma_p = pktdma_parray[unit];
   4557 
   4558     for (dv_cont = 0; dv_cont < NUM_CONT_DMA_DV; dv_cont++) {
   4559         if (!((dv_cont > 0) && (pktdma_p->cont_dma == 0))) {
   4560             for (channel = 0; channel < MAX_CHANNELS; channel++) {
   4561                 if (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0) {
   4562                     set_up_dv(unit, pktdma_p->dv_tx_array[dv_cont][channel],
   4563                               DV_TX, pktdma_p->chain_tx, pktdma_p->sg_tx,
   4564                               pktdma_p->reload_tx, pktdma_p->poll_intr_param,
   4565                               channel, pktdma_p->pkt_tx_array,
   4566                               pktdma_p->pkt_size_param,
   4567                               pktdma_p->num_pkts_param_tx,
   4568                               pktdma_p->random_packet_sizes,
   4569                               pktdma_p->source_ch, pktdma_p->cont_dma);
   4570                 } else if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   4571                     set_up_dv(unit, pktdma_p->dv_rx_array[dv_cont][channel],
   4572                               DV_RX, pktdma_p->chain_rx, pktdma_p->sg_rx,
   4573                               pktdma_p->reload_rx, pktdma_p->poll_intr_param,
   4574                               channel, pktdma_p->pkt_rx_array,
   4575                               pktdma_p->pkt_size_param,
   4576                               pktdma_p->num_pkts_param_rx,
   4577                               pktdma_p->random_packet_sizes,
   4578                               pktdma_p->source_ch, pktdma_p->cont_dma);
   4579                 }
   4580             }
   4581         }
   4582     }
   4583 }
   4584 
   4585 /*
   4586  * Function:
   4587  *      pktdma_soc_check_packet_integrity
   4588  * Purpose:
   4589  *      Check packet integrity for finite packet counts
   4590  * Parameters:
   4591  *      unit: StrataSwitch Unit #.
   4592  *
   4593  * Returns:
   4594  *     Nothing
   4595  */
   4596 
   4597 static void
   4598 pktdma_soc_check_packet_integrity(int unit)
   4599 {
   4600     pktdma_t *pktdma_p = pktdma_parray[unit];
   4601     int32 i, j, k;
   4602     int32 num_bytes_compared;
   4603     int32 match = 1;
   4604 
   4605     cli_out("\n[CMIC_PKT_HEADER_OFFSET] %d\n", pktdma_p->header_offset);
   4606     if (pktdma_p->rx_bitmap_param == 0x0 || pktdma_p->tx_bitmap_param == 0x0) {
   4607         test_error
   4608             (unit,
   4609              "\n*ERROR: Cannot check packet integrity on a non-loopback test\n");
   4610     } else if (pktdma_p->num_pkts_param_tx != pktdma_p->num_pkts_param_rx) {
   4611         test_error
   4612             (unit,
   4613              "\n*ERROR: Cannot check packet integrity unless NumPktsTx == NumPktsRx\n");
   4614     } else {
   4615         for (i = 0; i < MAX_CHANNELS; i++) {
   4616             if (((pktdma_p->rx_bitmap_param >> i) % 2) != 0) {
   4617                 if (pktdma_p->source_ch[i] != 99) {
   4618                     cli_out
   4619                         ("\nChecking Packet integrity for rx_ch = %0d"
   4620                          " with source_ch = %0d",
   4621                          i, pktdma_p->source_ch[i]);
   4622                     for (j = 0; j < pktdma_p->num_pkts_param_rx; j++) {
   4623                         if (pktdma_p->pkt_size_param <= 0) {
   4624                             num_bytes_compared =
   4625                                 pktdma_p->random_packet_sizes[pktdma_p->
   4626                                                               source_ch[i]][j];
   4627                         } else {
   4628                             num_bytes_compared = pktdma_p->pkt_size_param;
   4629                         }
   4630                         for (k = 0; k < num_bytes_compared; k++) {
   4631                             if (pktdma_p->
   4632                                 pkt_tx_array[pktdma_p->source_ch[i]][j][k] !=
   4633                                 pktdma_p->pkt_rx_array[i][j][k +
   4634                                                     pktdma_p->header_offset]) {
   4635                                 match = 0;
   4636                                 cli_out
   4637                                     ("\nMismatch : channel = %0d, "
   4638                                      "packet = %0d, byte = %0d, "
   4639                                      "tx_location = %p, rx_location = %p "
   4640                                      "tx_byte = %02x, rx_byte = %02x",
   4641                                      i, j, k,
   4642                                      &pktdma_p->pkt_tx_array[pktdma_p->
   4643                                                              source_ch[i]][j]
   4644                                      [k], &pktdma_p->pkt_rx_array[i][j][k +
   4645                                                         pktdma_p->header_offset],
   4646                                      pktdma_p->pkt_tx_array[pktdma_p->
   4647                                                             source_ch[i]][j][k],
   4648                                      pktdma_p->pkt_rx_array[i][j][k +
   4649                                                 pktdma_p->header_offset]);
   4650                             }
   4651                         }
   4652                     }
   4653                 }
   4654             }
   4655         }
   4656         if (match == 0) {
   4657             test_error(unit,
   4658                        "\n*ERROR: PACKET INTEGRITY CHECK FAILED\n");
   4659             pktdma_p->test_fail = 1;
   4660         } else {
   4661             cli_out("\nPACKET INTEGRITY CHECK PASSED");
   4662         }
   4663     }
   4664 }
   4665 
   4666 /*
   4667  * Function:
   4668  *      gather_cmic_packet_counters
   4669  * Purpose:
   4670  *      Gather CMIC TX and RX packet counters
   4671  * Parameters:
   4672  *      unit: StrataSwitch Unit #.
   4673  *      tx_counters - TX packet counter array
   4674  *      rx_counters - RX packet counter array
   4675  *
   4676  * Returns:
   4677  *     Nothing
   4678  */
   4679 
   4680 static void
   4681 gather_cmic_packet_counters(int unit, uint32 *tx_counters,
   4682                             uint32 *rx_counters)
   4683 {
   4684     int32 cmc, ch;
   4685     int32 vchan;
   4686 
   4687     for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   4688         for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) {
   4689             vchan = (cmc * DMA_CHAN_PER_CMC(unit)) + ch;
   4690             soc_dma_chan_counter_get(unit, vchan,
   4691                                      &tx_counters[DMA_CHAN_PER_CMC(unit) * cmc + ch],
   4692                                      &rx_counters[DMA_CHAN_PER_CMC(unit) * cmc + ch]);
   4693         }
   4694     }
   4695 }
   4696 
   4697 /*
   4698  * Function:
   4699  *      check_pkt_counters
   4700  * Purpose:
   4701  *      Test end check for packet counter values.
   4702  * Parameters:
   4703  *      unit: StrataSwitch Unit #.
   4704  *
   4705  * Returns:
   4706  *     Nothing
   4707  */
   4708 
   4709 static void
   4710 check_pkt_counters(int unit)
   4711 {
   4712     int32 cmc, ch;
   4713     int32 match = 1;
   4714     int32 disable_tx_chk = 0;
   4715     int32 disable_rx_chk = 0;
   4716     pktdma_t *pktdma_p = pktdma_parray[unit];
   4717 
   4718     gather_cmic_packet_counters(unit, pktdma_p->cmic_tx_counters,
   4719                                 pktdma_p->cmic_rx_counters);
   4720 
   4721     if (pktdma_p->stream_param_tx == 1
   4722         || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD) {
   4723         disable_tx_chk = 1;
   4724         cli_out("\nStreaming enabled on TX, Disabling TX Pkt counter checks");
   4725     }
   4726 
   4727     if (pktdma_p->stream_param_rx == 1
   4728         || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
   4729         disable_rx_chk = 1;
   4730         cli_out("\nStreaming enabled on RX, Disabling RX Pkt counter checks");
   4731     }
   4732 
   4733     for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   4734         for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) {
   4735             if ((((pktdma_p->tx_bitmap_param >> (DMA_CHAN_PER_CMC(unit) * cmc + ch)) % 2) !=
   4736                  0) && (disable_tx_chk == 0)) {
   4737                 if (pktdma_p->cmic_tx_counters[DMA_CHAN_PER_CMC(unit) * cmc + ch] !=
   4738                     pktdma_p->num_pkts_param_tx) {
   4739                     cli_out("\n*ERROR: TX Counter mismatch for cmc=%0d, ch=%0d",
   4740                             cmc, ch);
   4741                     match = 0;
   4742                 }
   4743             }
   4744 
   4745             if ((((pktdma_p->rx_bitmap_param >> (DMA_CHAN_PER_CMC(unit) * cmc + ch)) % 2) !=
   4746                  0) && (disable_rx_chk == 0)) {
   4747                 if (pktdma_p->cmic_rx_counters[DMA_CHAN_PER_CMC(unit) * cmc + ch] !=
   4748                     pktdma_p->num_pkts_param_rx) {
   4749                     cli_out("\n*ERROR: RX Counter mismatch for cmc=%0d, ch=%0d",
   4750                             cmc, ch);
   4751                     match = 0;
   4752                 }
   4753             }
   4754         }
   4755     }
   4756     if ((disable_tx_chk == 0) || (disable_rx_chk == 0)) {
   4757         if (match == 0) {
   4758             test_error(unit, "\n*ERROR: PACKET COUNTER CHECKS FAILED\n");
   4759             pktdma_p->test_fail = 1;
   4760         } else {
   4761             cli_out("\nPACKET COUNTER CHECKS PASSED");
   4762         }
   4763     }
   4764 }
   4765 
   4766 /*
   4767  * Function:
   4768  *      check_interrupt_counters
   4769  * Purpose:
   4770  *      Test end check for interrupt count values.
   4771  * Parameters:
   4772  *      unit: StrataSwitch Unit #.
   4773  *
   4774  * Returns:
   4775  *     Nothing
   4776  */
   4777 
   4778 static void
   4779 check_interrupt_counters(int unit)
   4780 {
   4781     int32 cmc, ch;
   4782     int32 match = 1;
   4783     int32 disable_tx_chk = 0;
   4784     int32 disable_rx_chk = 0;
   4785     int32 sg_factor_tx;
   4786     int32 sg_factor_rx;
   4787     int32 exp_desc_done_cnt_tx;
   4788     int32 exp_chain_done_cnt_tx;
   4789     int32 exp_desc_done_cnt_rx;
   4790     int32 exp_chain_done_cnt_rx;
   4791     uint32 vchan = 0;
   4792     pktdma_t *pktdma_p = pktdma_parray[unit];
   4793 
   4794     if (pktdma_p->stream_param_tx == 1
   4795         || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD) {
   4796         disable_tx_chk = 1;
   4797         cli_out("\nStreaming enabled on TX, Disabling TX Intr counter checks");
   4798     }
   4799 
   4800     if (pktdma_p->stream_param_rx == 1
   4801         || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
   4802         disable_rx_chk = 1;
   4803         cli_out("\nStreaming enabled on RX, Disabling RX Intr counter checks");
   4804     }
   4805 
   4806     if (pktdma_p->sg_tx == 0) {
   4807         sg_factor_tx = 1;
   4808     }
   4809     else {
   4810         sg_factor_tx = 2;
   4811     }
   4812 
   4813     if (pktdma_p->sg_rx == 0) {
   4814         sg_factor_rx = 1;
   4815     }
   4816     else {
   4817         sg_factor_rx = 2;
   4818     }
   4819 
   4820     exp_desc_done_cnt_tx = pktdma_p->num_pkts_param_tx * sg_factor_tx;
   4821 
   4822     if (pktdma_p->chain_tx == 1) {
   4823         exp_chain_done_cnt_tx = 1;
   4824     }
   4825     else {
   4826         exp_chain_done_cnt_tx = pktdma_p->num_pkts_param_tx;
   4827     }
   4828 
   4829     exp_desc_done_cnt_rx = pktdma_p->num_pkts_param_rx * sg_factor_rx;
   4830 
   4831     if (pktdma_p->chain_rx == 1) {
   4832         exp_chain_done_cnt_rx = 1;
   4833     }
   4834     else {
   4835         exp_chain_done_cnt_rx = pktdma_p->num_pkts_param_rx;
   4836     }
   4837 
   4838     for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) {
   4839         for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) {
   4840             vchan = DMA_CHAN_PER_CMC(unit) * cmc + ch;
   4841             if ((((pktdma_p->tx_bitmap_param >> vchan) % 2) !=
   4842                  0) && (disable_tx_chk == 0)
   4843                  && (pktdma_p->poll_intr_param == BOTH_DESC_CHAIN_INTR)) {
   4844                 if (pktdma_p->desc_done_count_tx[vchan] !=
   4845                     exp_desc_done_cnt_tx) {
   4846                     /* soc api update output interrup per chain not per descriptor */
   4847                     /*
   4848                     cli_out("\n*WARN: TX Desc done interrupt count mismatch "
   4849                             "for cmc=%0d, ch=%0d, intr_exp %0d, intr_act %0d",
   4850                             cmc, ch,
   4851                             exp_desc_done_cnt_tx,
   4852                             pktdma_p->desc_done_count_tx[vchan]); */
   4853                     /* match = 0; */
   4854                 }
   4855                 if( pktdma_p->cont_dma == 0) {
   4856                     if (pktdma_p->chain_done_count_tx[vchan]
   4857                             != exp_chain_done_cnt_tx) {
   4858                         cli_out("\n*ERROR: TX Chain done interrupt count "
   4859                         "mismatch for cmc=%0d, ch=%0d, "
   4860                         "intr_exp %0d, intr_act %0d",
   4861                         cmc, ch,
   4862                         exp_chain_done_cnt_tx,
   4863                         pktdma_p->chain_done_count_tx[vchan]
   4864                         );
   4865                         match = 0;
   4866                     }
   4867                 }
   4868             }
   4869             if ((((pktdma_p->rx_bitmap_param >> (vchan)) % 2) !=
   4870                  0) && (disable_rx_chk == 0)
   4871                  && (pktdma_p->poll_intr_param == BOTH_DESC_CHAIN_INTR)) {
   4872                 if (pktdma_p->desc_done_count_rx[vchan] !=
   4873                     exp_desc_done_cnt_rx) {
   4874                     /* soc api update output interrup per chain not per descriptor */
   4875                     /*
   4876                     cli_out("\n*WARN: RX Desc done interrupt count mismatch"
   4877                             "for cmc=%0d, ch=%0d, intr_exp %0d, intr_act %0d",
   4878                             cmc, ch,
   4879                             exp_desc_done_cnt_rx,
   4880                             pktdma_p->desc_done_count_rx[vchan]); */
   4881                     /* match = 0; */
   4882                 }
   4883                 if( pktdma_p->cont_dma == 0) {
   4884                     if (pktdma_p->chain_done_count_rx[vchan]
   4885                             != exp_chain_done_cnt_rx) {
   4886                         cli_out("\n*ERROR: RX Chain done interrupt count "
   4887                         "mismatch for cmc=%0d, ch=%0d, "
   4888                         "intr_exp %0d, intr_act %0d",
   4889                         cmc, ch,
   4890                         exp_chain_done_cnt_rx,
   4891                         pktdma_p->chain_done_count_rx[vchan]);
   4892                         match = 0;
   4893                     }
   4894                 }
   4895             }
   4896         }
   4897     }
   4898     if ((disable_tx_chk == 0) || (disable_rx_chk == 0)) {
   4899         if (match == 0) {
   4900             test_error(unit, "\n*ERROR: INTERRUPT COUNT CHECKS FAILED\n");
   4901             pktdma_p->test_fail = 1;
   4902         } else {
   4903             cli_out("\nINTERRUPT COUNT CHECKS PASSED");
   4904         }
   4905     }
   4906 }
   4907 
   4908 static void pktdma_cmicx_loopback(int unit) {
   4909     soc_dma_loopback_config(unit, SOC_DMA_LOOPBACK_SET);
   4910 }
   4911 
   4912 
   4913 /*
   4914  * Function:
   4915  *      pktdma_soc_test_init
   4916  * Purpose:
   4917  *      Test init.Parses CLI params and allocates desc memory. Initializes most
   4918  *      of test struct.
   4919  * Parameters:
   4920  *      unit: StrataSwitch Unit #.
   4921  *
   4922  * Returns:
   4923  *     Nothing
   4924  */
   4925 
   4926 int
   4927 pktdma_soc_test_init(int unit, args_t *a, void **pa)
   4928 {
   4929     uint32 i;
   4930     uint32 dv_cont;
   4931     pktdma_t *pktdma_p;
   4932     int32 channel = 0;
   4933 
   4934     pktdma_p = pktdma_parray[unit];
   4935 
   4936     pktdma_p = sal_alloc(sizeof(pktdma_t), "pktdma_test");
   4937 
   4938     if (pktdma_p == NULL) {
   4939         test_error(unit, "\nERROR: Memory allocation unsuccessful\n");
   4940         return -1;
   4941     }
   4942     sal_memset(pktdma_p, 0, sizeof(pktdma_t));
   4943     pktdma_parray[unit] = pktdma_p;
   4944 
   4945     pktdma_p->kill_dma = 0;
   4946     pktdma_p->tx_thread_done = 0;
   4947     pktdma_p->rx_thread_done = 0;
   4948 
   4949 
   4950     cli_out("\nStart pktdma_test");
   4951     cli_out("\nCalling pktdma_soc_test_init\n");
   4952 
   4953     pktdma_p->test_fail = 0;
   4954     /* coverity[dont_call : FALSE] */
   4955     pktdma_p->pkt_seed = sal_rand();
   4956 
   4957     if (soc_property_get(unit, spn_PDMA_CONTINUOUS_MODE_ENABLE, 0)) {
   4958         cli_out("\nContinuous DMA enabled");
   4959         pktdma_p->cont_dma = 1;
   4960     } else {
   4961         cli_out("\nLegacy DMA - Cont DMA not enabled");
   4962         pktdma_p->cont_dma = 0;
   4963     }
   4964 
   4965     pktdma_soc_parse_test_params(unit, a);
   4966 
   4967     if (pktdma_p->bad_input == 1) {
   4968         goto done;
   4969     }
   4970 
   4971     if (pktdma_p->sv_override_param == 0) {
   4972         bcm_vlan_destroy_all(unit);
   4973         pktdma_soc_test_clean(unit, 0);
   4974     }
   4975 
   4976     for (channel = 0; channel < MAX_CHANNELS; channel++) {
   4977         pktdma_p->chain_done_tx[channel] = 0;
   4978         pktdma_p->chain_done_rx[channel] = 0;
   4979         pktdma_p->reload_done_tx[channel] = 0;
   4980         pktdma_p->reload_done_rx[channel] = 0;
   4981         pktdma_p->chain_done_count_tx[channel] = 0;
   4982         pktdma_p->chain_done_count_rx[channel] = 0;
   4983         pktdma_p->reload_done_count_tx[channel] = 0;
   4984         pktdma_p->reload_done_count_rx[channel] = 0;
   4985     }
   4986 
   4987     set_global_desc_attr(unit);
   4988 
   4989     if(pktdma_p->sw_threads_off_param == 1) {
   4990         cli_out("\nTurning off memscan");
   4991         soc_mem_scan_stop(unit);
   4992 
   4993         cli_out("\nPausing linkscan");
   4994         bcm_linkscan_enable_set(unit, 0);
   4995     }
   4996 
   4997     cli_out("\nTurning off IDB/MMU FC");
   4998     pktdma_soc_turn_off_fc(unit);
   4999 
   5000     if(pktdma_p->sw_threads_off_param == 1) {
   5001         cli_out("\nStopping counter collection");
   5002         soc_counter_stop(unit);
   5003     }
   5004 
   5005     if (pktdma_p->cmicx_loopback_param == 1) {
   5006         pktdma_cmicx_loopback(unit);
   5007     }
   5008 
   5009     if (pktdma_p->sv_override_param == 0) {
   5010         cli_out("\nSetting up MAC loopback on all ports");
   5011         pktdma_soc_set_up_mac_lpbk(unit);
   5012 
   5013         cli_out("\nProgramming CPU_COS_MAP");
   5014         pktdma_soc_program_cpu_cos_map(unit);
   5015 
   5016         cli_out("\nProgramming COS_MAP for 16 priorities");
   5017         pktdma_soc_program_cos_map_pri16(unit);
   5018 
   5019         cli_out("\nSetting up VLANs/streams");
   5020         pktdma_soc_set_up_vlan(unit, pktdma_p->tx_bitmap_param,
   5021                             pktdma_p->rx_bitmap_param, pktdma_p->pkt_size_param,
   5022                             (bcm_vlan_t) (VLAN), (bcm_vlan_t) (XLATE_VLAN));
   5023 
   5024         pktdma_init(unit, 1, pktdma_p->rx_bitmap_param,
   5025                     pktdma_p->skip_cos_ctrl_bmp_param);
   5026     }
   5027 
   5028     pktdma_soc_set_source_ch_array(unit, pktdma_p->tx_bitmap_param,
   5029                                    pktdma_p->rx_bitmap_param);
   5030 
   5031     set_up_isr_table(unit);
   5032 
   5033     store_l2_packets(unit);
   5034 
   5035     if (pktdma_p->cmicx_loopback_param == 1) {
   5036         soc_dma_attach(unit, 0);
   5037     } 
   5038 
   5039     soc_dma_init(unit);
   5040 
   5041 
   5042     for (dv_cont = 0; dv_cont < NUM_CONT_DMA_DV; dv_cont++) {
   5043         if (!((dv_cont > 0) && (pktdma_p->cont_dma == 0))) {
   5044             pktdma_p->dv_tx_array[dv_cont] =
   5045                 (dv_t ***) soc_at_alloc(unit, MAX_CHANNELS * sizeof(dv_t **),
   5046                                         "dv_tx_array[dv_cont]_alloc");
   5047             pktdma_p->dv_rx_array[dv_cont] =
   5048                 (dv_t ***) soc_at_alloc(unit, MAX_CHANNELS * sizeof(dv_t **),
   5049                                         "dv_rx_array[dv_cont]_alloc");
   5050 
   5051             for (channel = 0; channel < MAX_CHANNELS; channel++) {
   5052                 if (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0) {
   5053                     pktdma_p->dv_tx_array[dv_cont][channel] =
   5054                         (dv_t **) soc_at_alloc(unit,
   5055                                                pktdma_p->num_pkts_param_tx *
   5056                                                sizeof(dv_t *),
   5057                                                "dv_tx_array[dv_cont]_alloc");
   5058                     if (pktdma_p->chain_tx == 0) {
   5059                         for (i = 0; i < pktdma_p->num_pkts_param_tx; i++) {
   5060                             pktdma_p->dv_tx_array[dv_cont][channel][i] =
   5061                                 soc_dma_dv_alloc(unit, DV_TX,
   5062                                              ((pktdma_p->sg_tx == 1) ? 3 : 2));
   5063                         }
   5064                     } else {
   5065                         pktdma_p->dv_tx_array[dv_cont][channel][0] =
   5066                             soc_dma_dv_alloc(unit, DV_TX,
   5067                                                  ((pktdma_p->sg_tx ==
   5068                                                    1) ? (2 *
   5069                                                          (pktdma_p->
   5070                                                           num_pkts_param_tx +
   5071                                                           1)) : (pktdma_p->
   5072                                                                  num_pkts_param_tx
   5073                                                                  + 1)));
   5074                     }
   5075                 }
   5076 
   5077                 if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   5078                     pktdma_p->dv_rx_array[dv_cont][channel] =
   5079                         (dv_t **) soc_at_alloc(unit,
   5080                                                pktdma_p->num_pkts_param_rx *
   5081                                                sizeof(dv_t *),
   5082                                                "dv_rx_array[dv_cont]_alloc");
   5083                     if (pktdma_p->chain_rx == 0) {
   5084                         for (i = 0; i < pktdma_p->num_pkts_param_rx; i++) {
   5085                             pktdma_p->dv_rx_array[dv_cont][channel][i] =
   5086                                 soc_dma_dv_alloc(unit, DV_RX,
   5087                                                  ((pktdma_p->sg_rx ==
   5088                                                    1) ? 3 : 2));
   5089                         }
   5090                     } else {
   5091                         pktdma_p->dv_rx_array[dv_cont][channel][0] =
   5092                             soc_dma_dv_alloc(unit, DV_RX,
   5093                                              ((pktdma_p->sg_rx ==
   5094                                                1) ? (2 *
   5095                                                      (pktdma_p->
   5096                                                       num_pkts_param_rx +
   5097                                                       1)) : (pktdma_p->
   5098                                                              num_pkts_param_rx +
   5099                                                              1)));
   5100                     }
   5101                 }
   5102             }
   5103             LOG_INFO(BSL_LS_APPL_TESTS,
   5104                      (BSL_META_U(unit, "\npktdma_p->dv_tx_array[%0d] = %p"),
   5105                       dv_cont, pktdma_p->dv_tx_array[dv_cont]));
   5106             for (channel = 0; channel < MAX_CHANNELS; channel++) {
   5107                 if (((pktdma_p->tx_bitmap_param >> channel) % 2) != 0) {
   5108                     LOG_INFO(BSL_LS_APPL_TESTS,
   5109                              (BSL_META_U
   5110                               (unit, "\npktdma_p->dv_tx_array[%0d][%0d] = %p"),
   5111                               dv_cont, channel,
   5112                               pktdma_p->dv_tx_array[dv_cont][channel]));
   5113                     if (pktdma_p->chain_tx == 0) {
   5114                         for (i = 0; i < pktdma_p->num_pkts_param_tx; i++) {
   5115                             LOG_INFO(BSL_LS_APPL_TESTS,
   5116                                      (BSL_META_U
   5117                                       (unit,
   5118                                        "\npktdma_p->dv_tx_array[%0d][%0d][%0d]"
   5119                                        "= %p"),
   5120                                       dv_cont, channel, i,
   5121                                       pktdma_p->
   5122                                       dv_tx_array[dv_cont][channel][i]));
   5123                         }
   5124                     } else {
   5125                         LOG_INFO(BSL_LS_APPL_TESTS,
   5126                                  (BSL_META_U
   5127                                   (unit,
   5128                                    "\npktdma_p->dv_tx_array[%0d][%0d][%0d]"
   5129                                    "= %p"),
   5130                                   dv_cont, channel, 0,
   5131                                   pktdma_p->dv_tx_array[dv_cont][channel][0]));
   5132                     }
   5133                 }
   5134             }
   5135 
   5136             LOG_INFO(BSL_LS_APPL_TESTS,
   5137                      (BSL_META_U(unit, "\npktdma_p->dv_rx_array[%0d] = %p"),
   5138                       dv_cont, pktdma_p->dv_rx_array[dv_cont]));
   5139             for (channel = 0; channel < MAX_CHANNELS; channel++) {
   5140                 if (((pktdma_p->rx_bitmap_param >> channel) % 2) != 0) {
   5141                     LOG_INFO(BSL_LS_APPL_TESTS,
   5142                              (BSL_META_U
   5143                               (unit, "\npktdma_p->dv_rx_array[%0d][%0d] = %p"),
   5144                               dv_cont, channel,
   5145                               pktdma_p->dv_rx_array[dv_cont][channel]));
   5146                     if (pktdma_p->chain_rx == 0) {
   5147                         for (i = 0; i < pktdma_p->num_pkts_param_rx; i++) {
   5148                             LOG_INFO(BSL_LS_APPL_TESTS,
   5149                                      (BSL_META_U
   5150                                       (unit,
   5151                                        "\npktdma_p->dv_rx_array[%0d][%0d][%0d]"
   5152                                        "= %p"),
   5153                                       dv_cont, channel, i,
   5154                                       pktdma_p->
   5155                                       dv_rx_array[dv_cont][channel][i]));
   5156                         }
   5157                     } else {
   5158                         LOG_INFO(BSL_LS_APPL_TESTS,
   5159                                  (BSL_META_U
   5160                                   (unit,
   5161                                    "\npktdma_p->dv_rx_array[%0d][%0d][%0d]"
   5162                                    "= %p"),
   5163                                   dv_cont, channel, 0,
   5164                                   pktdma_p->dv_rx_array[dv_cont][channel][0]));
   5165                     }
   5166                 }
   5167             }
   5168         }
   5169     }
   5170 
   5171     pktdma_p->cmic_tx_counters =
   5172         (uint32 *) sal_alloc(MAX_CHANNELS * sizeof(uint32),
   5173                              "CMIC TX counters");
   5174     pktdma_p->cmic_rx_counters =
   5175         (uint32 *) sal_alloc(MAX_CHANNELS * sizeof(uint32),
   5176                              "CMIC RX counters");
   5177 
   5178     for (channel = 0; channel < MAX_CHANNELS; channel++) {
   5179         pktdma_p->cmic_tx_counters[channel] = 0;
   5180         pktdma_p->cmic_rx_counters[channel] = 0;
   5181     }
   5182 
   5183 done:
   5184     return 0;
   5185 }
   5186 
   5187 /*
   5188  * Function:
   5189  *      pktdma_soc_test_init
   5190  * Purpose:
   5191  *      Actual test. Kicks of TX and RX DMA threads.
   5192  * Parameters:
   5193  *      unit: StrataSwitch Unit #.
   5194  *
   5195  * Returns:
   5196  *     Nothing
   5197  */
   5198 int
   5199 pktdma_soc_test(int unit, args_t *a, void *pa)
   5200 {
   5201     pktdma_t *pktdma_p = pktdma_parray[unit];
   5202 
   5203     if (pktdma_p->bad_input == 1) {
   5204         goto done;
   5205     }
   5206 
   5207     cli_out("\nCalling pktdma_soc_test");
   5208     set_up_all_dv(unit);
   5209     config_dma_chan(unit, pktdma_p->tx_bitmap_param, pktdma_p->rx_bitmap_param,
   5210                     pktdma_p->poll_intr_param);
   5211 
   5212     if (pktdma_p->verbose_param == 1) {
   5213         dump_first_dv(unit);
   5214         dump_packet_pointers(unit);
   5215     }
   5216 
   5217     pktdma_p->pid_tx =
   5218         sal_thread_create("TXDMA thread", 16 * 1024 * 1024, 200, txdma_thread,
   5219                           INT_TO_PTR(unit));
   5220     pktdma_p->pid_rx =
   5221         sal_thread_create("RXDMA thread", 16 * 1024 * 1024, 200, rxdma_thread,
   5222                           INT_TO_PTR(unit));
   5223 
   5224     cli_out("\npid_tx = %p, pid_rx= %p", (pktdma_p->pid_tx),
   5225                                          (pktdma_p->pid_rx));
   5226 
   5227 done:
   5228     return 0;
   5229 }
   5230 
   5231 /*
   5232  * Function:
   5233  *      pktdma_soc_test_cleanup
   5234  * Purpose:
   5235  *      Test cleanup. Called at test end. Calculates rates, conducts test-end
   5236  *      checks and frees all allocated memory.
   5237  * Parameters:
   5238  *      unit: StrataSwitch Unit #.
   5239  *
   5240  * Returns:
   5241  *     Nothing
   5242  */
   5243 
   5244 int
   5245 pktdma_soc_test_cleanup(int unit, void *pa)
   5246 {
   5247     pktdma_t *pktdma_p = pktdma_parray[unit];
   5248     int rv;
   5249 #ifdef BROADCOM_DEBUG
   5250 #ifdef INCLUDE_BCM_SAL_PROFILE
   5251     uint32 alloc_curr;
   5252     uint32 alloc_max;
   5253 #endif
   5254 #endif
   5255 
   5256     if (pktdma_p->bad_input == 1) {
   5257         goto done;
   5258     }
   5259 
   5260     cli_out("\nCalling pktdma_soc_test_cleanup");
   5261 
   5262     if (pktdma_p->stream_param_rx == 1 || pktdma_p->stream_param_tx == 1
   5263         || pktdma_p->test_type_param_tx == DESC_TX_CHAIN_PKT_RELOAD
   5264         || pktdma_p->test_type_param_rx == DESC_RX_CHAIN_PKT_RELOAD) {
   5265         cli_out("\nWait 5s for traffic to stabilize");
   5266         sal_usleep(5000000);
   5267         pktdma_soc_calc_rate_bps(unit, pktdma_p->pkt_size_param,
   5268                                  pktdma_p->rate_calc_interval_param);
   5269         check_pkt_counters(unit);
   5270         if (pktdma_p->poll_intr_param != POLL) {
   5271             check_interrupt_counters(unit);
   5272         }
   5273     } else {
   5274         cli_out("\nWait 5s for traffic to stabilize");
   5275         sal_usleep(5000000);
   5276         check_pkt_counters(unit);
   5277         if (pktdma_p->check_packet_integrity_param == 1) {
   5278             pktdma_soc_check_packet_integrity(unit);
   5279         }
   5280         if (pktdma_p->poll_intr_param != POLL) {
   5281             check_interrupt_counters(unit);
   5282         }
   5283     }
   5284 
   5285     cli_out("\nKilling all DMA ops");
   5286 
   5287     pktdma_p->kill_dma = 1;
   5288 
   5289     sal_usleep(1000000);
   5290     if(pktdma_p->tx_thread_done == 0) {
   5291         test_error(unit, "\nTX thread still running");
   5292         pktdma_p->test_fail = 1;
   5293         sal_thread_destroy(pktdma_p->pid_tx);
   5294     }
   5295 
   5296     if(pktdma_p->rx_thread_done == 0) {
   5297         test_error(unit, "\nRX thread still running");
   5298         pktdma_p->test_fail = 1;
   5299         sal_thread_destroy(pktdma_p->pid_rx);
   5300     }
   5301 
   5302     bcm_vlan_destroy_all(unit);
   5303     if (pktdma_p->poll_intr_param != 0) {
   5304         dump_interrupt_counts(unit);
   5305     }
   5306 
   5307     soc_dma_abort(unit);
   5308     pktdma_soc_free_all_memory(unit);
   5309 
   5310 done:
   5311     if(pktdma_p->bad_input == 1) {
   5312         pktdma_p->test_fail = 1;
   5313     }
   5314 
   5315     if (pktdma_p->test_fail == 1) {
   5316         rv = BCM_E_FAIL;
   5317     }
   5318     else {
   5319         rv = BCM_E_NONE;
   5320     }
   5321 
   5322     sal_free(pktdma_p);
   5323 
   5324 #ifdef BROADCOM_DEBUG
   5325 #ifdef INCLUDE_BCM_SAL_PROFILE
   5326     sal_alloc_resource_usage_get(&alloc_curr, &alloc_max);
   5327     cli_out("\nalloc_curr = %0d, alloc_max = %0d", alloc_curr, alloc_max);
   5328 #endif
   5329 #endif
   5330 
   5331     cli_out("\n");
   5332     return rv;
   5333 }
   5334 #endif /* BCM_ESW_SUPPORT && (BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT) */