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

pause.c (6525B)


      1 /*  Feature  : Tx and Rx Pause
      2  *
      3  *  Usage    : BCM.0>cint pause.c
      4  *
      5  *  config   : pause_config.bcm
      6  *
      7  *  Log file : pause_log.txt
      8  *
      9  *  Test Topology :
     10  *
     11  *  DMAC=0x1            +------------+         DMAC=0x1
     12  *  SMAC=0x2   +-------->   56980    +-------> SMAC=0x2
     13  *  VLAN=2        cd0(1)|            |cd1(2)   VLAN=2
     14  *                      | l2:mac=0x1 |
     15  *                      |    vlan=2  |
     16  *       <-------+      |    port=2  |     <-------+
     17  *    TX PAUSE FRAMES   |            |  RX PAUSE FRAMES
     18  *                      +------------+
     19  *  Summary:
     20  *  ========
     21  *  This cint example demonstrates pause feature on TH3
     22  *    Detailed steps done in the CINT script:
     23  *    =======================================
     24  *    1) Step1 - Test Setup (Done in test_setup())
     25  *    ============================================
     26  *      a) Select one ingress and one egress port
     27  *    2) Step2 - Configuration (Done in pause_config())
     28  *    =================================================
     29  *      a) Sets up required data path for traffic and sets up Tx and Rx Pause on 
     30  *         ports
     31  *    3) Step3 - Verification (Done in verify())
     32  *    ==========================================
     33  *      a) Transmit l2 packet with dmac=0x1, vlan=1 at linerate to from Ixia
     34  *         to cd0(Port-1)
     35  *      b) Along with a), Transmit Pause frame(dmac=0x0180C2000001 smac=0x1 type=0x8808 opcode=0x0001)
     36  *         at linerate to cd1 (Port-2)
     37  *         (Pause frame: dmac=0x0180C2000001, smac=0x1, type=0x8808, opcode=0x0001)
     38  *      c) Expected Result:
     39  *         ================
     40  *         For test case mentioned in a)
     41  *         On cd0 (Port-1): verify that Pause frames should be transmitted at regular intervals as
     42  *         egress port is congested.
     43  *         In 'show c' output Pause frame Tx should be seen on cd0 (port-1)
     44  *
     45  *         On cd1 (Port-2): verify that packets egress at configured rate
     46  *
     47  *         For test case mentioned in b)
     48  *         On cd1(Port-2): verify that Port does not egress any packets as pause frames are being
     49  *         received. In 'show c' output, there should not be any Tx on on cd1 (port-2)
     50  */
     51 
     52 cint_reset();
     53 int rv = 0;
     54 int unit = 0;
     55 bcm_port_t ing_port; /*Ingress port */
     56 bcm_port_t egr_port; /*Egress port */
     57 
     58 /* This function is written so that hardcoding of port
     59    numbers in Cint scripts is removed. This function gives
     60    required number of ports
     61 */
     62 
     63 bcm_error_t portNumbersGet(int unit, int *port_list, int num_ports)
     64 {
     65 
     66   int i=0,port=0,rv=0;
     67   bcm_port_config_t configP;
     68   bcm_pbmp_t ports_pbmp;
     69 
     70   rv = bcm_port_config_get(unit,&configP);
     71   if(BCM_FAILURE(rv)) {
     72      printf("\nError in retrieving port configuration: %s.\n",bcm_errmsg(rv));
     73      return rv;
     74   }
     75 
     76   ports_pbmp = configP.e;
     77   for (i= 1; i < BCM_PBMP_PORT_MAX; i++) {
     78     if (BCM_PBMP_MEMBER(&ports_pbmp,i)&& (port < num_ports)) {
     79       port_list[port]=i;
     80       port++;
     81     }
     82   }
     83 
     84   if (( port == 0 ) || ( port != num_ports )) {
     85        printf("portNumbersGet() failed \n");
     86        return -1;
     87   }
     88 
     89   return BCM_E_NONE;
     90 
     91 }
     92 
     93 bcm_error_t test_setup(int unit)
     94 {
     95   int port_list[2], i;
     96   if (BCM_E_NONE != portNumbersGet(unit, port_list, 2)) {
     97       printf("portNumbersGet() failed\n");
     98       return -1;
     99   }
    100 
    101   ing_port = port_list[0];
    102   egr_port = port_list[1];
    103 
    104   return BCM_E_NONE;
    105 }
    106 
    107 bcm_error_t common_data_path_init(int unit)
    108 {
    109   bcm_vlan_t vid = 2;
    110   bcm_mac_t dest_mac = "00:00:00:00:00:01"; /*Destination MAC */
    111   bcm_pbmp_t pbmp,upbmp;
    112   bcm_l2_addr_t l2addr;
    113 
    114   rv = bcm_vlan_create(unit, vid);
    115   if (rv != BCM_E_NONE) { 
    116       printf("[bcm_vlan_create] returned '%s'\n",bcm_errmsg(rv));
    117       return rv; 
    118   }
    119 
    120   BCM_PBMP_CLEAR(pbmp);
    121   BCM_PBMP_CLEAR(upbmp);
    122   BCM_PBMP_PORT_ADD(pbmp, ing_port);
    123   BCM_PBMP_PORT_ADD(pbmp, egr_port);
    124   rv = bcm_vlan_port_add(unit, vid, pbmp, upbmp);
    125   if (rv != BCM_E_NONE) {
    126       printf("bcm_vlan_port_add returned :%s.\n", bcm_errmsg(rv));
    127       return rv;
    128   }
    129  
    130   bcm_l2_addr_t_init(l2addr, dest_mac, vid);
    131   l2addr.port = egr_port;
    132   l2addr.flags |= BCM_L2_STATIC;
    133   rv = bcm_l2_addr_add(unit, &l2addr);
    134   if (rv != BCM_E_NONE) {
    135       printf("bcm_l2_addr_add returned :'%s'\n",bcm_errmsg(rv));
    136       return rv;
    137   }
    138   return BCM_E_NONE;
    139 }
    140  
    141 bcm_error_t pause_tx_rx_config(int unit, bcm_port_t ing_port, bcm_port_t egr_port)
    142 {
    143   uint32 limit_kbits_sec = 100000;
    144   uint32 limit_kbits_burst = 1000;
    145   int enable = 1;
    146   int disable = 0;
    147   bcm_mac_t pause_smac = "00:11:22:33:44:55";
    148 
    149   /****set egress port rate limit  *****/
    150   rv = bcm_port_rate_egress_set(unit, egr_port, limit_kbits_sec, limit_kbits_burst);
    151   if (rv != BCM_E_NONE) {
    152       printf("bcm_port_rate_egress_set returned '%s'\n",bcm_errmsg(rv)); 
    153       return rv;
    154   }
    155 
    156  /**** Set the pause frame's Source MAC ****/
    157  rv = bcm_port_pause_addr_set(unit,ing_port, pause_smac);
    158  if (rv != BCM_E_NONE) {
    159      printf("bcm_port_pause_addr_set returned '%s'\n",bcm_errmsg(rv));
    160      return rv;
    161  }
    162 
    163  /**** Enable TX-Pause on ingress port ****/
    164  rv = bcm_port_pause_set(unit,ing_port,enable,disable);
    165  if (rv != BCM_E_NONE) {
    166      printf("bcm_port_pause_set-TX returned '%s'\n",bcm_errmsg(rv));
    167      return rv;
    168  }
    169 
    170  /**** Enable RX-Pause on egress port ****/
    171  rv = bcm_port_pause_set(unit,egr_port,disable,enable);
    172  if (rv != BCM_E_NONE) {
    173      printf("bcm_port_pause_set-RX returned '%s'\n",bcm_errmsg(rv));
    174      return rv;
    175  }
    176  return BCM_E_NONE;
    177 }
    178 
    179 bcm_error_t pause_config(int unit, bcm_port_t ing_port, bcm_port_t egr_port)
    180 {
    181   if (BCM_FAILURE((rv = common_data_path_init(unit)))) {
    182       printf("common_data_path_init() failed.: %s.\n", bcm_errmsg(rv));
    183       return rv;
    184   }
    185 
    186   if (BCM_FAILURE((rv = pause_tx_rx_config(unit, ing_port, egr_port)))) {
    187       printf("pause_tx_rx_config() failed. : %s. \n", bcm_errmsg(rv));
    188       return rv;
    189   }
    190   return BCM_E_NONE;
    191 } 
    192 
    193 void verify(int unit)
    194 {
    195   /* ing_port should send Pause frame towards Ixia
    196      egr_port should not egress anything as it receives pause frames from Ixia.
    197   */
    198   bshell(unit, "show c");   
    199 }
    200 
    201 bcm_error_t execute()
    202 {
    203   bcm_error_t rv;
    204   int unit = 0;
    205 
    206   bshell(unit, "config show; a ; version");
    207 
    208   /* select port */
    209   if (BCM_FAILURE((rv = test_setup(unit)))) {
    210       printf("test_setup() failed.\n");
    211       return -1;
    212   }
    213 
    214   if (BCM_FAILURE((rv = pause_config(unit, ing_port, egr_port)))) {
    215       printf("pause_config() failed.\n");
    216       return -1;
    217   }
    218 
    219   /* verify the result */
    220   verify(unit);
    221   return BCM_E_NONE;
    222 }
    223 
    224 const char *auto_execute = (ARGC == 1) ? ARGV[0] : "YES";
    225 if (!sal_strcmp(auto_execute, "YES")) {
    226   print execute();
    227 }
    228