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 }