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