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

bcm_tx.c (10784B)


      1 /*  Feature  : Bcm Tx 
      2  *
      3  *  Usage    : BCM.0> cint bcm_tx.c
      4  *
      5  *  config   : bcm_tx_config.bcm
      6  *
      7  *  Log file : bcm_tx_log.txt
      8  *
      9  *  Test Topology :
     10  *
     11  *                   +------------------------------+  egress_port1
     12  *                   |                              +-----------------+
     13  *                   |                              |
     14  *                   |                              |
     15  *  cpu_port         |                              |  egress_port2
     16  *  +----------------+          SWITCH              +-----------------+
     17  *                   |                              |
     18  *                   |                              |
     19  *                   |                              |  egress_port3
     20  *                   |                              +-----------------+
     21  *                   |                              |
     22  *                   +------------------------------+
     23  *  Summary:
     24  *  ========
     25  *    This CINT script demonstrates how to send packets from application which will 
     26  *    go through the ingress pipeline and pipeline decides the egress port to send out the packet.
     27  *    This example shows how application can send packets using bcm_tx() API
     28  *
     29  *    Detailed steps done in the CINT script:
     30  *    =====================================================
     31  *    1) Step1 - Test Setup (Done in test_setup())
     32  *    ============================================
     33  *      a) Select three egress port and configure them in loopback mode.
     34  *      b) Create Vlan 10 and add egress port 1 and CPU port to vlan 10.
     35  *      c) Create Vlan 20 and add egress port 2 and CPU port to vlan 20.
     36  *      d) Create Vlan 30 and add egress port 3 and CPU port to vlan 30.
     37  *      e) start Packet Watcher diag app (PW start)
     38  *
     39  *    2) Step2 - Configuration (Done in tx_setup())
     40  *    ============================================
     41  *      a) There is nothing to be done in tx_setup
     42  *
     43  *    3) Step3 - Verification(Done in verify())
     44  *    ==========================================
     45  *      a) Transmit one packet with vlan=10 using bcm_tx() API
     46  *      b) Transmit one packet with vlan=20 using bcm_tx() API
     47  *      c) Transmit one packet with vlan=30 using bcm_tx() API
     48  *      d) Expected Result:
     49  *      ===================
     50  *         The packets are looped back on egress ports and are received by CPU port.
     51  *         PW will dump the recieved packets on console.
     52  */
     53 
     54 cint_reset();
     55 bcm_port_t egress_port[3];
     56 
     57 
     58 /*
     59  * Simplest example of the bcm_tx() API.
     60  *
     61  * Sends a single packet to the switch subject to ordinary pipeline processing.
     62  *
     63  * Parameters:
     64  *   unit: tx device unit number
     65  *   pktData: Complete packet
     66  *   length: Size of commplete packet in bytes.
     67  */
     68 bcm_error_t
     69 tx_pkt_data(int unit, uint8 *pktData, int length)
     70 {
     71     bcm_pkt_t  *pkt;
     72     bcm_error_t rv;
     73 
     74     /*
     75      * Allocate a packet structure and associated DMA packet data buffer.
     76      * Set Tx flags:
     77      *    BCM_TX_CRC_REGEN: Regenerate packet CRC.
     78      *    BCM_TX_ETHER: Inject fully formed packet into the ingress
     79      *                  pipeline. Packet will be subject to all pipeline processing.
     80      */
     81     rv = bcm_pkt_alloc(unit, length, BCM_TX_CRC_REGEN | BCM_TX_ETHER, &pkt);
     82     if(BCM_FAILURE(rv)) {
     83         printf("\nError in bcm_pkt_alloc(): %s.\n",bcm_errmsg(rv));
     84         return rv;
     85     }
     86 
     87     /* Copy packet data from caller into DMA packet data buffer and set
     88      * packet length. Copy offset is 0, ignore return value which is number
     89      * of bytes copied.
     90      */
     91     bcm_pkt_memcpy(pkt, 0, pktData, length);
     92 
     93     /*
     94      * Transmit packet, wait for DMA to complete before returning. Success
     95      * status only indicates packet was transferred to switch, it does not
     96      * ensure that packet will not be dropped.
     97      */
     98     rv = bcm_tx(unit, pkt, NULL);
     99     if(BCM_FAILURE(rv)) {
    100         printf("\nError in bcm_tx(): %s.\n",bcm_errmsg(rv));
    101         return rv;
    102     }
    103  
    104     /* Free packet resources */
    105     bcm_pkt_free(unit, pkt);
    106 
    107     /* return status from bcm_tx */
    108     return rv;
    109 }
    110 
    111 
    112 /* This function is written so that hardcoding of port
    113    numbers in Cint scripts is removed. This function gives
    114    required number of ports
    115 */
    116 bcm_error_t portNumbersGet(int unit, int *port_list, int num_ports)
    117 {
    118 
    119   int i=0,port=0,rv=0;
    120   bcm_port_config_t configP;
    121   bcm_pbmp_t ports_pbmp;
    122 
    123   rv = bcm_port_config_get(unit,&configP);
    124   if(BCM_FAILURE(rv)) {
    125     printf("\nError in retrieving port configuration: %s.\n",bcm_errmsg(rv));
    126     return rv;
    127   }
    128 
    129   ports_pbmp = configP.e;
    130   for (i= 1; i < BCM_PBMP_PORT_MAX; i++) {
    131     if (BCM_PBMP_MEMBER(&ports_pbmp,i)&& (port < num_ports)) {
    132       port_list[port]=i;
    133       port++;
    134     }
    135   }
    136 
    137   if (( port == 0 ) || ( port != num_ports )) {
    138       printf("portNumbersGet() failed \n");
    139       return -1;
    140   }
    141 
    142   return BCM_E_NONE;
    143 
    144 }
    145 
    146 bcm_error_t test_setup(int unit)
    147 {
    148     const bcm_vlan_t vlan[3] = {10, 20 , 30};
    149     int i=0;
    150     char        command[128];   /* Buffer for diagnostic shell commands */
    151 
    152     /* Pick arbitrary dest MAC Address */
    153     const bcm_mac_t dest[3] = {"08:08:08:11:22:33" , "09:09:09:11:22:33", "0a:0a:0a:11:22:33"};
    154 
    155     /* Test case variables used to find a suitable test port list */
    156     bcm_l2_addr_t l2addr;
    157 
    158     int port_list[3];
    159 
    160     if (BCM_E_NONE != portNumbersGet(unit, port_list, 3)) {
    161         printf("portNumbersGet() failed\n");
    162         return -1;
    163     }
    164 
    165     egress_port[0] = port_list[0];
    166     egress_port[1] = port_list[1];
    167     egress_port[2] = port_list[2];
    168 
    169     /* Put all egress ports into loopback */
    170     BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, egress_port[0], BCM_PORT_LOOPBACK_MAC));
    171     BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, egress_port[1], BCM_PORT_LOOPBACK_MAC));
    172     BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, egress_port[2], BCM_PORT_LOOPBACK_MAC));
    173 
    174     /* Create vlan and add ports */
    175     for (i=0; i < 3; i++)
    176     {
    177         sprintf(command, "vlan create %d PortBitMap=cpu0,%d", vlan[i],egress_port[i]);
    178         bshell(unit, command);
    179     }
    180 
    181     /* Start the packet watcher (quiet mode) */
    182     bshell(unit, "pw start report +raw +decode");
    183 
    184     return BCM_E_NONE;
    185 
    186 }
    187 
    188 /* Tx Setup */
    189 bcm_error_t tx_setup(int unit)
    190 {
    191     return BCM_E_NONE;
    192 }
    193 
    194 
    195 /*******************************************************************************
    196  * Test Harness Follows
    197  *
    198  * Define the test packet for transmission:
    199  *   Singled tagged, VLAN=10, packet priority=3
    200  *   Singled tagged, VLAN=20, packet priority=3
    201  *   Singled tagged, VLAN=30, packet priority=3
    202  */
    203 const uint8 pkt1[] = {
    204 /*
    205   00    01    02    03    04    05    06    07    08    09    10    11    12    13    14    15*/
    206 0x08, 0x08, 0x08, 0x11, 0x22, 0x33, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x81, 0x00, 0x60, 0x0A,
    207 0x08, 0x00, 0x45, 0x00, 0x00, 0x8A, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xE1, 0x0E, 0xC0, 0xA8,
    208 0x0C, 0x02, 0xC0, 0xA8, 0x0C, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x76, 0x8D, 0xC8, 0x2A, 0x53,
    209 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45,
    210 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A,
    211 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C,
    212 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47,
    213 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47,
    214 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41,
    215 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x8D, 0x49, 0x42, 0x7E
    216 };
    217 
    218 const uint8 pkt2[] = {
    219 /*
    220   00    01    02    03    04    05    06    07    08    09    10    11    12    13    14    15*/
    221 0x09, 0x09, 0x09, 0x11, 0x22, 0x33, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x81, 0x00, 0x60, 0x14,
    222 0x08, 0x00, 0x45, 0x00, 0x00, 0x8A, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xE1, 0x0E, 0xC0, 0xA8,
    223 0x0C, 0x02, 0xC0, 0xA8, 0x0C, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x76, 0x8D, 0xC8, 0x2A, 0x53,
    224 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45,
    225 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A,
    226 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C,
    227 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47,
    228 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47,
    229 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41,
    230 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x8D, 0x49, 0x42, 0x7E
    231 };
    232 
    233 const uint8 pkt3[] = {
    234 /*
    235   00    01    02    03    04    05    06    07    08    09    10    11    12    13    14    15*/
    236 0x0a, 0x0a, 0x0a, 0x11, 0x22, 0x33, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x81, 0x00, 0x60, 0x1E,
    237 0x08, 0x00, 0x45, 0x00, 0x00, 0x8A, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xE1, 0x0E, 0xC0, 0xA8,
    238 0x0C, 0x02, 0xC0, 0xA8, 0x0C, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x76, 0x8D, 0xC8, 0x2A, 0x53,
    239 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45,
    240 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A,
    241 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C,
    242 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47,
    243 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47,
    244 0x4C, 0x45, 0x2D, 0x54, 0x41, 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x2D, 0x54, 0x41,
    245 0x47, 0x2A, 0x53, 0x49, 0x4E, 0x47, 0x4C, 0x45, 0x8D, 0x49, 0x42, 0x7E
    246 };
    247 
    248 /* Use "sizeof" to get packet size */
    249 const int   pkt1_SIZEOF = sizeof(pkt1);
    250 const int   pkt2_SIZEOF = sizeof(pkt2);
    251 const int   pkt3_SIZEOF = sizeof(pkt3);
    252 
    253 /* Simple wrapper function used to transmit test packet */
    254 bcm_error_t
    255 test_harness(int unit)
    256 {
    257     bcm_error_t rv=0; 
    258     rv = tx_pkt_data(unit, pkt1, pkt1_SIZEOF);
    259     rv = tx_pkt_data(unit, pkt2, pkt2_SIZEOF);
    260     rv = tx_pkt_data(unit, pkt3, pkt3_SIZEOF);
    261     return rv;
    262 }
    263 
    264 /* Run the test, save and possibly display error status */
    265 void verify(int unit)
    266 {
    267     bcm_error_t rv;
    268     if (BCM_FAILURE(rv = test_harness(0))) {
    269         printf("Tx verification failed: %s\n", bcm_errmsg(rv));
    270     }
    271 }
    272 
    273 bcm_error_t execute()
    274 {
    275   bcm_error_t rv;
    276   int unit =0;
    277   bshell(unit, "config show; a ; version");
    278   if (BCM_FAILURE((rv = test_setup(unit)))) {
    279     printf("test_setup() failed.\n");
    280     return -1;
    281   }
    282 
    283   if (BCM_FAILURE((rv = tx_setup(unit)))) {
    284     printf("Tx Setup Failed\n");
    285     return -1;
    286   }
    287 
    288   verify(unit);
    289   return BCM_E_NONE;
    290 }
    291 
    292 const char *auto_execute = (ARGC == 1) ? ARGV[0] : "YES";
    293 if (!sal_strcmp(auto_execute, "YES")) {
    294   print execute();
    295 }