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

loopback2.c (11325B)


      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  * Loopback Tests, version 2
      8  *
      9  *	MAC	Sends packets from CPU to MAC in loopback mode, and back
     10  *	PHY	Sends packets from CPU to PHY in loopback mode, and back
     11  *	EXT	Sends packets from CPU out one port, in another, and back
     12  *	SNAKE	Sends packets from CPU through ports via MAC or PHY loopback
     13  */
     14 
     15 #include <shared/bsl.h>
     16 
     17 #include <sal/core/boot.h>
     18 #include <sal/appl/sal.h>
     19 #include <shared/bsl.h>
     20 #include <appl/diag/system.h>
     21 #include <appl/diag/system.h>
     22 #include <appl/diag/test.h>
     23 
     24 #include <soc/debug.h>
     25 #include <soc/hash.h>
     26 #include <soc/drv.h>
     27 
     28 #include <soc/higig.h>
     29 
     30 #ifdef BCM_ESW_SUPPORT
     31 #include <bcm_int/esw/mbcm.h>
     32 #endif
     33 
     34 #include <bcm/error.h>
     35 #include <bcm/vlan.h>
     36 #include <bcm/link.h>
     37 #include <bcm/stg.h>
     38 #include <bcm/stat.h>
     39 #include <bcm/mcast.h>
     40 #include <bcm/stack.h>
     41 
     42 #include <appl/test/loopback2.h>
     43 
     44 #include "testlist.h"
     45 
     46 /*
     47  * Loopback work structure
     48  */
     49 
     50 STATIC loopback2_test_t lb2_work[SOC_MAX_NUM_DEVICES];
     51 
     52 int
     53 lb2_mac_init(int unit, args_t *a, void **pa)
     54 /*
     55  * Function: 	lb2_mac_init
     56  * Purpose:	Initialize MAC loopback test.
     57  * Parameters:	unit - unit number.
     58  * Returns:	0 for success, -1 for failed.
     59  */
     60 {
     61     loopback2_test_t	*lw = &lb2_work[unit];
     62     loopback2_testdata_t	*lp = &lw->params[LB2_TT_MAC];
     63     parse_table_t	pt;
     64 
     65     lbu_setup(unit, lw);
     66 
     67     parse_table_init(unit, &pt);
     68     lbu_pkt_param_add(unit, &pt, lp);
     69     lbu_port_param_add(unit, &pt, lp);
     70     lbu_other_param_add(unit, &pt, lp);
     71 
     72     if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) {
     73 	test_error(unit,
     74 		   "%s: Invalid option: %s\n",
     75 		   ARG_CMD(a),
     76 		   ARG_CUR(a) ? ARG_CUR(a) : "*");
     77 	parse_arg_eq_done(&pt);
     78 	return(-1);
     79     }
     80     parse_arg_eq_done(&pt);
     81 
     82     if (lbu_check_parms(lw, lp)) {
     83 	return(-1);
     84     }
     85 
     86     /* Perform common loopback initialization */
     87 
     88     if (lbu_init(lw, lp)) {
     89 	return(-1);
     90     }
     91 
     92     *pa = lw;
     93 
     94     return(0);
     95 }
     96 
     97 int
     98 lb2_phy_init(int unit, args_t *a, void **pa)
     99 /*
    100  * Function: 	lb2_phy_init
    101  * Purpose:	Initialize PHY loopback test.
    102  * Parameters:	unit - unit number.
    103  * Returns:	0 for success, -1 for failed.
    104  */
    105 {
    106     loopback2_test_t	*lw = &lb2_work[unit];
    107     loopback2_testdata_t	*lp = &lw->params[LB2_TT_PHY];
    108     parse_table_t	pt;
    109 
    110     lbu_setup(unit, lw);
    111 
    112     parse_table_init(unit, &pt);
    113     lbu_pkt_param_add(unit, &pt, lp);
    114     lbu_port_param_add(unit, &pt, lp);
    115     lbu_other_param_add(unit, &pt, lp);
    116 
    117     if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) {
    118 	test_error(unit,
    119 		   "%s: Invalid option: %s\n",
    120 		   ARG_CMD(a),
    121 		   ARG_CUR(a) ? ARG_CUR(a) : "*");
    122 	parse_arg_eq_done(&pt);
    123 	return(-1);
    124     }
    125     parse_arg_eq_done(&pt);
    126 
    127 
    128     if (lbu_check_parms(lw, lp)) {
    129 	return(-1);
    130     }
    131 
    132     /* Perform common loopback initialization */
    133 
    134     if (lbu_init(lw, lp)) {
    135 	return(-1);
    136     }
    137 
    138     *pa = lw;
    139 
    140     return(0);
    141 }
    142 
    143 /*ARGSUSED*/
    144 int
    145 lb2_port_test(int unit, args_t *a, void *pa)
    146 /*
    147  * Function: 	lb2_port_test
    148  * Purpose:	Perform MAC loopback tests.
    149  * Parameters:	unit - unit #
    150  *		a - arguments (Not used, assumed parse by lb_mac_init).
    151  * Returns:
    152  */
    153 {
    154     loopback2_test_t	*lw = (loopback2_test_t *)pa;
    155     loopback2_testdata_t	*lp = lw->cur_params;
    156     int		port, rv;
    157     pbmp_t	pbm, tpbm;
    158 
    159     COMPILER_REFERENCE(a);
    160 
    161     LOG_INFO(BSL_LS_APPL_TESTS,
    162              (BSL_META_U(unit,
    163                          "lb_mac_test[%d]: Starting ....\n"), unit));
    164 
    165     lbu_stats_init(lw);
    166 
    167     BCM_PBMP_ASSIGN(pbm, lp->pbm);
    168     BCM_PBMP_ASSIGN(tpbm, lp->pbm);
    169     BCM_PBMP_AND(tpbm, PBMP_FE_ALL(unit));
    170 
    171     ENET_SET_MACADDR(lw->base_mac_src, lp->mac_src);
    172     ENET_SET_MACADDR(lw->base_mac_dst, lp->mac_dst);
    173 
    174     /*
    175      * Used to determine if ARL entry needs to be setup. Typically
    176      * required only for _E_ Ports.
    177      */
    178 
    179     BCM_PBMP_ASSIGN(tpbm, pbm);
    180     BCM_PBMP_AND(tpbm, PBMP_E_ALL(unit));
    181     if (BCM_PBMP_NOT_NULL(tpbm)) { 
    182         /* Don't setup arl if only hg ports */
    183         /*
    184          * Get our current MAC address for this port and be sure the
    185          * SOC will route packets to the CPU.
    186          */
    187         LOG_INFO(BSL_LS_APPL_TESTS,
    188                  (BSL_META_U(unit,
    189                              "Setting up ARL\n")));
    190         if (lbu_setup_arl_cmic(lw)) {
    191             return(-1);
    192         }
    193     }
    194 
    195 #if defined(__KERNEL__) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT))
    196     (void)soc_cmicm_cmcx_intr0_enable(unit, 0, 0xff00);
    197     sal_usleep(50);
    198 #endif
    199 
    200     PBMP_ITER(pbm, port) {
    201         lw->tx_len = 0;                 /* Start off clean */
    202 
    203         lw->tx_port = port;
    204         lw->rx_port = port;
    205 
    206         rv = lbu_serial_txrx(lw);
    207 
    208         if (lp->inject) { /* Diagnostic */
    209             return 0;
    210         }
    211 
    212         if (rv < 0) {
    213             return -1;
    214         }
    215     }
    216     
    217     if (BCM_PBMP_NOT_NULL(tpbm)) { 
    218         lbu_cleanup_arl(lw);
    219     }
    220 
    221     lbu_stats_done(lw);
    222 
    223     return 0;
    224 }
    225 
    226 int
    227 lb2_done(int unit, void *pa)
    228 /*
    229  * Function: 	lb2_done
    230  * Purpose:	Clean up after new loopback tests.
    231  * Parameters:	unit - unit number.
    232  * Returns:	0 for success, -1 for failed.
    233  */
    234 {
    235     soc_port_t	p;
    236     int		rv;
    237 
    238     if (pa) {
    239 	loopback2_testdata_t *lp = ((loopback2_test_t *)pa)->cur_params;
    240 
    241         if (lp->inject) { /* Diagnostic */
    242             return 0;
    243         }
    244 
    245 	/* Clear MAC loopback - Only if pa is set */
    246 
    247 	PBMP_ITER(lp->pbm, p) {
    248 	    rv = bcm_port_loopback_set(unit, p, BCM_PORT_LOOPBACK_NONE);
    249 	    if (rv != BCM_E_NONE) {
    250 		test_error(unit,
    251 			   "Port %s: Failed to reset MAC loopback: %s\n",
    252 			   SOC_PORT_NAME(unit, p), bcm_errmsg(rv));
    253                 return rv;
    254 	    }
    255 	}
    256 
    257         if (lp->test_type == LB2_TT_SNAKE) {
    258             if ((rv = lbu_snake_done(&lb2_work[unit])) < 0) {
    259                 return rv;
    260             }
    261         }
    262     }
    263 
    264     if ((rv = lbu_done(&lb2_work[unit])) < 0) {
    265         return rv;
    266     }
    267 
    268 #if defined(BCM_TOMAHAWK_SUPPORT)
    269     if (SOC_IS_TOMAHAWKX(unit)) {
    270         loopback2_test_t    *lw = &lb2_work[unit];
    271         loopback2_testdata_t    *lp_snake = &lw->params[LB2_TT_SNAKE];
    272         int num_ports;
    273         SOC_PBMP_COUNT(lp_snake->saved_pbm, num_ports);
    274         if (num_ports > LB2_TH_MAX_PORTS_WITH_PROFILE) {
    275             SOC_PBMP_ASSIGN(lp_snake->pbm, lp_snake->saved_pbm);
    276         }
    277     }
    278 #endif
    279 
    280     return 0;
    281 }
    282 
    283 int
    284 lb2_snake_init(int unit, args_t *a, void **pa)
    285 /*
    286  * Function: 	lb2_snake_init
    287  * Purpose:	Initialize snake loopback test.
    288  * Parameters:	unit - unit number.
    289  * Returns:	0 for success, -1 for failed.
    290  */
    291 {
    292     loopback2_test_t	*lw = &lb2_work[unit];
    293     loopback2_testdata_t	*lp = &lw->params[LB2_TT_SNAKE];
    294     parse_table_t	pt;
    295     int rv;
    296 
    297 #if defined(BCM_TOMAHAWK_SUPPORT)
    298     bcm_port_t port;
    299     int port_count;
    300     int num_ports;
    301 #endif
    302 
    303 #if defined(__KERNEL__) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT))
    304     (void)soc_cmicm_cmcx_intr0_enable(unit, 0, 0xff00);
    305     sal_usleep(50);
    306 #endif
    307 
    308     lbu_setup(unit, lw);
    309 
    310     parse_table_init(unit, &pt);
    311     lbu_pkt_param_add(unit, &pt, lp);
    312     lbu_port_param_add(unit, &pt, lp);
    313     lbu_other_param_add(unit, &pt, lp);
    314 
    315     if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) {
    316 	test_error(unit,
    317 		   "%s: Invalid option: %s\n",
    318 		   ARG_CMD(a),
    319 		   ARG_CUR(a) ? ARG_CUR(a) : "*");
    320 	return(-1);
    321     }
    322 
    323     if (lbu_check_parms(lw, lp)) {
    324 	return(-1);
    325     }
    326 
    327     /* Snake test supported only on Ethernet ports on FB & ER */
    328     if (SOC_IS_FB_FX_HX(unit)) {
    329         SOC_PBMP_AND(lp->pbm, PBMP_E_ALL(unit));
    330     }
    331 
    332 
    333 #if defined(BCM_TOMAHAWK_SUPPORT)
    334     if (SOC_IS_TOMAHAWKX(unit)) {
    335         /*
    336         *Due to the profile management limitation Only support maximum 127 ports for the test;
    337         *When there are 128 ports for the TH/TH+. port_select_mode are uese to choose the 127 ports
    338         */
    339         SOC_PBMP_ASSIGN(lp->saved_pbm, lp->pbm);
    340         SOC_PBMP_COUNT(lp->pbm, num_ports);
    341         port_count = 0;
    342         if (num_ports > LB2_TH_MAX_PORTS_WITH_PROFILE) {
    343             PBMP_ITER(lp->pbm, port) {
    344                 port_count = port_count + 1;
    345                 if (lp->port_select_mode == LB2_TH_ASCEND_PORT_MODE) {
    346                     if (port_count > LB2_TH_MAX_PORTS_WITH_PROFILE) {
    347                         SOC_PBMP_PORT_REMOVE(lp->pbm, port);
    348                     }
    349                 } else if (lp->port_select_mode == LB2_TH_DSCEND_PORT_MODE) {
    350                     if (port_count <= (num_ports-LB2_TH_MAX_PORTS_WITH_PROFILE)) {
    351                         SOC_PBMP_PORT_REMOVE(lp->pbm, port);
    352                     }
    353                 } else {
    354                     test_error(unit, "Invalid PortSelectMode \n");
    355                     return -1;
    356                 }
    357             }
    358             lp->port_select_mode = LB2_TH_ASCEND_PORT_MODE;
    359         }
    360     }
    361 #endif
    362 
    363     /* Perform common loopback initialization */
    364     if (lbu_init(lw, lp)) {
    365 	return(-1);
    366     }
    367 
    368     /* Perform snake specific initialization */
    369     rv = lbu_snake_init(lw, lp);
    370     if (rv < 0) {
    371         return rv;
    372     }
    373 
    374     *pa = lw;
    375 
    376     return(0);
    377 }
    378 
    379 int
    380 lb2_snake_test(int unit, args_t *a, void *pa)
    381 /*
    382  * Function: 	lb2_snake_test
    383  * Purpose:	Run snake loopback test.
    384  * Parameters:	unit - unit number.
    385  * Returns:	0 for success, -1 for failed.
    386  */
    387 {
    388     loopback2_test_t	   *lw = (loopback2_test_t *) pa;
    389     loopback2_testdata_t   *lp = lw->cur_params;
    390     int		    c_count, ix;
    391     int		    rv, ret_val = 0;
    392     lb2_port_stat_t  *stats;
    393 
    394     COMPILER_REFERENCE(unit);
    395     COMPILER_REFERENCE(a);
    396     COMPILER_REFERENCE(lp);
    397 
    398     stats = sal_alloc(SOC_MAX_NUM_PORTS *
    399 				  sizeof(lb2_port_stat_t),
    400 				  "Stats");
    401 
    402     lw->tx_cos = lp->cos_start;
    403     lw->tx_len = lp->len_start;
    404     lw->tx_ppt = lp->ppt_start;
    405 
    406 
    407     for (c_count = 0; c_count < lp->iterations; c_count++) {
    408 
    409 	cli_out("\nLB: loop %d of %d: "
    410                 "circular test on ports for %d seconds\n",
    411                 c_count + 1, lp->iterations, lp->duration);
    412 
    413         /* bcm call here someday.  For now, bcm_stat_clear is
    414          * just a wrapper for this function, and only does one port */
    415         if (!lp->inject) {
    416 #ifdef BCM_ESW_SUPPORT
    417             if ((rv = soc_counter_set32_by_port(unit,  
    418                       PBMP_PORT_ALL(unit), 0)) < 0) {
    419                 test_error(unit,
    420                            "Could not clear counters: %s\n",
    421                            soc_errmsg(rv));
    422                 ret_val = -1;
    423                 break;
    424             }
    425 #endif
    426         }
    427 
    428         if (lp->inject) {
    429             lbu_snake_tx(lw);
    430             ret_val = 0;
    431             break;
    432         }
    433 
    434         for (ix = 0; ix < SOC_MAX_NUM_PORTS; ix++) {
    435             stats[ix].initialized = FALSE;
    436         }
    437 
    438         if ((rv = lbu_snake_txrx(lw, stats)) < 0) {
    439             test_error(unit, "Snake test failed\n");
    440             ret_val = -1;
    441             break;
    442         }
    443 
    444         /* Increment parameters for next cycle */
    445         lw->tx_cos += 1;
    446         if (lw->tx_cos > lp->cos_end) {
    447             lw->tx_cos = lp->cos_start;
    448         }
    449         lw->tx_len += lp->len_inc;
    450         if (lw->tx_len > lp->len_end) {
    451             lw->tx_len = lp->len_start;
    452         }
    453         lw->tx_ppt += lp->ppt_inc;
    454         if (lw->tx_ppt > lp->ppt_end) {
    455             lw->tx_ppt = lp->ppt_start;
    456         }
    457     }
    458 
    459     sal_free(stats);
    460     return ret_val;
    461 }
    462