cint_sat.c (73169B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 */ 6 7 /* 8 * File: cint_sat.c 9 * 10 * Background: 11 * Service Activation Test (SAT) feature is basically a validation of an Ethernet Service for a customer 12 * by a service provider operator before activating theservice. The customer may be another operator, 13 * upstream or downstream, or an end-point customer. It is usually done with an Ethernet Test Equipment and involves a Truck Roll to 14 * the premises where the network endpoint or the intermediate point resides. 15 * The industry is moving towards the use of embedded test application within the network switch element. 16 * 17 * The SAT implementation borrows concept of MEP points from Ethernet OAM. Each SAT MEP has an Rx and Tx point. 18 * These SAT MEP Tx/Rx points in SAT context are defined as Service Activation Measurement Points (SAMP). 19 * SAT MEP Rx point is where a SAT packet coming from wire is trapped and sent to OLP. 20 * SAT MEP Tx point is where a SAT packet is injected from OLP before going out on wire. 21 * 22 * A SAT MEP (SAMP) can perform one or all of the functions defined below: 23 * Generator Function (GTF): SAT logic that injects test frames for OVC/EVC at specified rate and 24 * Test frames processed like customer service frames. 25 * Collector Function (CTF): SAT Test frames are processed like customerservice frames and 26 * logic has instrumentation counters for SAT. 27 * Reflector Function (Latching Loopback Function): Loops back customerservice frames 28 * at remote end for two-way measurement with GTF and CTF at the same end. 29 * 30 * Purpose: 31 * Example of using SAT APIs. 32 * The following CINT provides a calling sequence example to Setup one GTF and one CTF. 33 * 34 * Global - configure sequence: 35 * 1. global configure 36 * - Call bcm_sat_config_set() 37 * 38 * GTF - Set up sequence: 39 * 1. Create GTF Object 40 * - Call bcm_sat_gtf_create() 41 * 2. Configure packet info, including header type, header info, payload, packet edit info and packet offset. 42 * Note: The format of SAT packet transsmitted from GTF is defined in MEF Sat spec. 43 * - Call bcm_sat_gtf_packet_config() 44 * 3. Set Bandwidth 45 * - Call bcm_sat_gtf_bandwidth_set() 46 * 4. Set Rate Pattern 47 * - Call bcm_sat_gtf_rate_pattern_set() 48 * 49 * CTF - Set up sequence: 50 * 1. Create CTF Object 51 * - Call bcm_sat_ctf_create() 52 * 2. Use PMF to capture the sat packets to OAMP 53 * - Call bcm_field_group_create() 54 * 3. Map identification to specific flow 55 * - Call bcm_sat_ctf_trap_add() 56 * - Call bcm_sat_ctf_trap_data_to_session_map() 57 * - Call bcm_sat_ctf_identifier_map() 58 * 4. Get the collected information 59 * - Call bcm_sat_ctf_stat_get() 60 * 61 * 62 * To Activate Above Settings Run: 63 * BCM> cint examples/sat/cint_sat.c 64 * BCM> cint 65 * cint> print sat_setup(0); 66 * cint> print sat_cleanup(0); 67 */ 68 69 int is_xgs = 1; /* Device Type Configure */ 70 71 /************** Packet Parameters - used by both GTF and CTF ******************/ 72 bcm_mac_t pkt_dmac = {0x00, 0x00, 0x00, 0xca, 0xfe, 0xda}; 73 bcm_mac_t pkt_smac = {0x00, 0x00, 0x00, 0xca, 0xfe, 0x5a}; 74 bcm_vlan_t pkt_vlans[2] = {0x100, 0x200}; 75 uint8 pkt_vlan_pri[2] = {0, 1}; 76 uint8 pkt_vlan_cfi[2] = {0, 0}; 77 uint16 pkt_ether_type = 0x8902; 78 /* FL Packet Related Rarameter */ 79 uint32 gtf_seq_number_offset = -1; 80 /* FD Packet Related Rarameter */ 81 uint32 gtf_timestamp_offset = 0; 82 83 /************** CTF Parameters ******************/ 84 bcm_field_group_t grp; 85 int trap_id=0; 86 int trap_code_qualifier = 0; 87 bcm_sat_ctf_identifier_t identifier; 88 bcm_sat_ctf_t ctf_id = 0; 89 90 /************** PMF for receiving SAT packet on JR2 ******************/ 91 bcm_field_group_t sat_fg_id=0; 92 bcm_field_entry_t sat_fg_entry_id = 0; 93 bcm_field_context_t sat_field_context_id; 94 /* 95 * Create a FG to capture matched packets to SAT engine. 96 * The filter can be SA, DA, SIP, DIP or other packet's fields. 97 */ 98 int ctf_jer_specific_config(int unit, int ctf_id) { 99 100 bcm_field_qset_t qset; 101 bcm_field_aset_t aset; 102 bcm_field_entry_t ent; 103 int group_priority = 1; 104 bcm_ip_t src_ip = 0x0a0a0a0a; 105 bcm_ip_t src_ip_mask = 0xffffffff; 106 bcm_ip_t dst_ip = 0x0b0b0b0b; 107 bcm_ip_t dst_ip_mask = 0xffffffff; 108 uint32 dest_port = 232; /*dest_port (OAMP PP port)*/ 109 bcm_gport_t sat_gport; 110 bcm_rx_trap_config_t trap_config; 111 bcm_sat_config_t sat_cfg; 112 uint32 oam_value = 0; 113 int rv = 0; 114 /* uint16 ether_type = 0x8902; */ 115 116 rv = bcm_sat_config_get(unit, &sat_cfg); 117 if (BCM_E_NONE != rv) { 118 printf("Error in bcm_sat_config_get\n"); 119 return rv; 120 } 121 oam_value = (sat_cfg.timestamp_format == bcmSATTimestampFormatIEEE1588v1) ? 0x8000: 0xC000; 122 123 /* Create a trap for SAT */ 124 /* create trap */ 125 rv = bcm_rx_trap_type_create(unit, 0, bcmRxTrapUserDefine, &trap_id); 126 if (rv != BCM_E_NONE) { 127 printf("Error in bcm_rx_trap_type_create (%s) \n",bcm_errmsg(rv)); 128 return rv; 129 } 130 131 sal_memset(&trap_config, 0, sizeof(trap_config)); 132 trap_config.flags = (BCM_RX_TRAP_UPDATE_DEST | BCM_RX_TRAP_TRAP | BCM_RX_TRAP_REPLACE); 133 trap_config.trap_strength = 0; 134 trap_config.dest_port = dest_port; 135 136 rv = bcm_rx_trap_set(unit, trap_id, &trap_config); 137 if (rv != BCM_E_NONE) { 138 printf("Error in bcm_rx_trap_set (%s) \n",bcm_errmsg(rv)); 139 return rv; 140 } 141 BCM_GPORT_TRAP_SET(sat_gport, trap_id, 7, 0); 142 143 /* Jericho specific - set PMF */ 144 BCM_FIELD_QSET_INIT(qset); 145 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyStageIngress); 146 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyOuterVlan); 147 148 BCM_FIELD_ASET_INIT(aset); 149 BCM_FIELD_ASET_ADD(aset, bcmFieldActionTrap); 150 BCM_FIELD_ASET_ADD(aset, bcmFieldActionOam); 151 152 rv = bcm_field_group_create(unit, qset, group_priority, &grp); 153 if (BCM_E_NONE != rv) { 154 printf("Error in bcm_field_group_create\n"); 155 return rv; 156 } 157 158 rv = bcm_field_group_action_set(unit, grp, aset); 159 if (BCM_E_NONE != rv) { 160 printf("Error in bcm_field_group_action_set\n"); 161 return rv; 162 } 163 164 rv = bcm_field_group_install(unit, grp); 165 if (BCM_E_NONE != rv) { 166 printf("Error in bcm_field_group_install\n"); 167 return rv; 168 } 169 170 rv = bcm_field_entry_create(unit, grp, &ent); 171 if (BCM_E_NONE != rv) { 172 printf("Error in bcm_field_entry_create\n"); 173 return rv; 174 } 175 176 /*rv = bcm_field_qualify_SrcIp(unit, ent, src_ip, src_ip_mask); 177 if (BCM_E_NONE != rv) { 178 printf("Error in bcm_field_qualify_SrcIp\n"); 179 return rv; 180 } 181 182 rv = bcm_field_qualify_DstIp(unit, ent, dst_ip, dst_ip_mask); 183 if (BCM_E_NONE != rv) { 184 printf("Error in bcm_field_qualify_DstIp\n"); 185 return rv; 186 } 187 188 rv = bcm_field_qualify_EtherType(unit, ent, ether_type, 0xFFFF); 189 if (BCM_E_NONE != rv) { 190 printf("Error in bcm_field_qualify_EtherType\n"); 191 return rv; 192 }*/ 193 194 rv = bcm_field_qualify_OuterVlan(unit, ent, 5, 0xFFFF); 195 if (BCM_E_NONE != rv) { 196 printf("Error in bcm_field_qualify_EtherType\n"); 197 return rv; 198 } 199 200 /*rv = bcm_field_qualify_InPort(unit, ent, 40, 0xFFFFFFFF); 201 if (BCM_E_NONE != rv) { 202 printf("Error in bcm_field_qualify_EtherType\n"); 203 return rv; 204 }*/ 205 206 /* Trap the packets to SAT engine, and update the FHEI header as followed. 207 * Trap-Code: trap_id 208 * Trap-Qualifier: ctf_id 209 * 210 * In this case, 211 * As for the Trap-Code, viewed it as the trap origin 212 * As for the Trap-Qualifier, viewed it as the SAT test flow-id 213 */ 214 215 216 trap_code_qualifier = ctf_id; 217 rv = bcm_field_action_add(unit, ent, bcmFieldActionTrap, sat_gport, trap_code_qualifier); 218 if (BCM_E_NONE != rv) { 219 printf("Error in bcm_field_action_add -- bcmFieldActionTrap\n"); 220 return rv; 221 } 222 223 rv = bcm_field_action_add(unit, ent, bcmFieldActionOam, oam_value, 0); 224 if (BCM_E_NONE != rv) { 225 printf("Error in bcm_field_action_add -- bcmFieldActionOam\n"); 226 return rv; 227 } 228 229 rv = bcm_field_entry_install(unit, ent); 230 if (BCM_E_NONE != rv) { 231 printf("Error in bcm_field_entry_install\n"); 232 return rv; 233 } 234 235 return 0; 236 } 237 238 /* 239 * Set followed CTF configuration. 240 * Set recieved packet information. 241 * Add trap id, it is used to mapping identification to specific flow. 242 * Set a mapping between trap qualifier and session id. 243 * Set a mapping between identification and specific flow. 244 * Set Statistic collecting configuration. 245 * Set Availability configuration 246 */ 247 int ctf_general_config(int unit, bcm_sat_ctf_t ctf_id) { 248 249 bcm_sat_ctf_packet_info_t packet_info; 250 bcm_sat_ctf_stat_config_t stat_config; 251 bcm_sat_ctf_availability_config_t availability_config; 252 bcm_sat_ctf_bin_limit_t bins[9]; 253 int i = 0; 254 int rv = 0; 255 256 /* Set the recieved packet information */ 257 bcm_sat_ctf_packet_info_t_init(&packet_info); 258 packet_info.sat_header_type = bcmSatHeaderUserDefined; 259 if (gtf_timestamp_offset != 0) { 260 packet_info.offsets.timestamp_offset = gtf_timestamp_offset - gtf_pkt_len_of_int_hdr; 261 } 262 else { 263 packet_info.offsets.timestamp_offset = gtf_timestamp_offset; 264 } 265 if (gtf_seq_number_offset != -1) { 266 packet_info.offsets.seq_number_offset = gtf_seq_number_offset - gtf_pkt_len_of_int_hdr; 267 } 268 else { 269 packet_info.offsets.seq_number_offset = gtf_seq_number_offset; 270 } 271 272 /*packet_info.offsets.seq_number_offset = 30;*/ 273 /*packet_info.offsets.timestamp_offset = 22;*/ 274 275 packet_info.offsets.payload_offset = 32; 276 packet_info.payload.payload_type = bcmSatPayloadConstant4Bytes; 277 packet_info.offsets.crc_byte_offset = gtf_crc_byte_offset; 278 packet_info.flags = BCM_SAT_CTF_PACKET_INFO_ADD_END_TLV | BCM_SAT_CTF_PACKET_INFO_ADD_CRC; 279 rv = bcm_sat_ctf_packet_config (unit, ctf_id, &packet_info); 280 if (BCM_E_NONE != rv) { 281 printf("Error in bcm_sat_ctf_packet_config\n"); 282 return rv; 283 } 284 285 /* Add trap id, it is used to mapping identification to specific flow 286 * Needn't add trap id for saber2 device as trap_id always is 0. 287 * and it's same with default value. 288 */ 289 if (is_xgs == 0) { 290 rv = bcm_sat_ctf_trap_add(unit, trap_id); 291 if (BCM_E_NONE != rv) { 292 printf("Error in bcm_sat_ctf_trap_add\n"); 293 return rv; 294 } 295 } 296 /* Map trap data to session id */ 297 rv = bcm_sat_ctf_trap_data_to_session_map(unit, trap_code_qualifier, 0xff, 0); 298 if (BCM_E_NONE != rv) { 299 printf("Error in bcm_sat_ctf_trap_data_to_session_map\n"); 300 return rv; 301 } 302 303 /* Map identification to specific flow */ 304 bcm_sat_ctf_identifier_t_init(&identifier); 305 identifier.session_id = 0; /* the result from trap data mapping */ 306 identifier.trap_id = 0; /* index in trap_id array */ 307 identifier.color = 1; 308 identifier.tc = 0; 309 rv = bcm_sat_ctf_identifier_unmap(unit, &identifier); 310 if (BCM_E_NONE != rv) { 311 printf("Error in bcm_sat_ctf_identifier_unmap\n"); 312 return rv; 313 } 314 rv = bcm_sat_ctf_identifier_map(unit, &identifier, ctf_id); 315 if (BCM_E_NONE != rv) { 316 printf("Error in bcm_sat_ctf_identifier_map\n"); 317 return rv; 318 } 319 320 /* Statistic collecting configuration */ 321 bcm_sat_ctf_stat_config_t_init(stat_config); 322 stat_config.use_global_bin_config = 0; 323 stat_config.bin_min_delay = 50; 324 stat_config.bin_step = 10; 325 stat_config.update_counters_in_unvavail_state = 1; 326 rv = bcm_sat_ctf_stat_config_set(unit, ctf_id, &stat_config); 327 if (BCM_E_NONE != rv) { 328 printf("Error in bcm_sat_ctf_stat_config_set\n"); 329 return rv; 330 } 331 332 /* If want to set configuration for each bin, please use followed BCM API */ 333 for (i = 0; i < 9; i++) 334 { 335 bins[i].bin_select = i; 336 bins[i].bin_limit = 100 + i*100; 337 } 338 rv = bcm_sat_ctf_bin_limit_set(unit, 9, &bins); 339 if (BCM_E_NONE != rv) { 340 printf("Error in bcm_sat_ctf_bin_limit_set\n"); 341 return rv; 342 } 343 344 /* SAT Availability */ 345 bcm_sat_ctf_availability_config_t_init(&availability_config); 346 availability_config.switch_state_num_of_slots = 10; 347 availability_config.switch_state_threshold_per_slot = 100; 348 rv = bcm_sat_ctf_availability_config_set(unit, ctf_id, &availability_config); 349 if (BCM_E_NONE != rv) { 350 printf("Error in bcm_sat_ctf_availability_config_set\n"); 351 return rv; 352 } 353 354 return 0; 355 } 356 357 /* Get the collected information */ 358 int ctf_general_show_results(int unit, bcm_sat_ctf_t ctf_id, int read_clear) { 359 360 bcm_sat_ctf_stat_t stat; 361 int i = 0; 362 int rv = 0; 363 uint32 flags = 0; 364 365 if (read_clear == 0) { 366 flags = BCM_SAT_CTF_STAT_DO_NOT_CLR_ON_READ; 367 } 368 rv = bcm_sat_ctf_stat_get (unit, ctf_id, flags, &stat); 369 if (BCM_E_NONE != rv) { 370 printf("Error in bcm_sat_ctf_stat_get\n"); 371 return rv; 372 } 373 374 printf("STAT informations:\n"); 375 print stat; 376 377 return 0; 378 } 379 380 int cb_sat(int unit, 381 bcm_sat_event_type_t event_type, 382 bcm_sat_report_event_data_t *event_data, 383 void *user_data) { 384 385 print unit; 386 print event_type; 387 print *event_data; 388 389 return 0; 390 } 391 392 int ctf_setup(int unit) { 393 394 int rv = BCM_E_NONE; 395 396 /* Create a CTF */ 397 rv = bcm_sat_ctf_create(unit, 0, &ctf_id); 398 if (BCM_E_NONE != rv) { 399 printf("Error in bcm_sat_ctf_create\n"); 400 return rv; 401 } 402 403 /* Capture the matched packets to SAT engine. 404 * In Jericho, use PMF to capture packets to SAT engine. 405 * In Saber2, use bcm_sat_endpoint_create() to capture 406 * packets to SAT engine. 407 */ 408 if (is_xgs) { 409 410 /* Configure OLP header - already implemented in olp_config() . 411 * These bcm command should be convert to BCM APIs by IDC 412 * as IDC is owner of this feature. 413 */ 414 415 /*bshell(unit, "modify EGR_OLP_DGLP_CONFIG 0 1 DGLP=0x5 MACDA=0xD0C0"); 416 bshell(unit, "modify EGR_OLP_DGLP_CONFIG 1 1 DGLP=0x1f84 MACDA=0x100020304051"); 417 bshell(unit, "modify EGR_OLP_CONFIG 0 1 MACSA=0x202122232425 ETHERTYPE=0xb4b4 VLAN_TPID=0x8100"); 418 bshell(unit, "modify EGR_OLP_HEADER_TYPE_MAPPING 0 1 HDR_TYPE=1 HDR_SUBTYPE=12"); 419 bshell(unit, "modreg EGR_OLP_VLAN VLAN_TAG=0x8002"); 420 bshell(unit, "modreg EGR_OAM_RX_MODE_FOR_CPU ADD_OLP=1");*/ 421 422 423 /* Configure endpoint to trap the packet to OAMP port. 424 * These bcm command should be convert to BCM APIs by IDC 425 * as IDC is owner of this feature. 426 */ 427 428 /*bshell(unit, "write ING_SAT_SAMP_TCAM 0 1 VALID=0x3 GLP=1 OTAG_VALID=1 OVID=0x100 MACSA=0xcafe5a MACDA=0xcafeda ETHERTYPE=0x8902 GLP_MASK=0xFFFF OTAG_VALID_MASK=0x1 OVID_MASK=0xFFF MACSA_MASK=0xFFFFFFFFFFFF MACDA_MASK=0xFFFFFFFFFFFF"); 429 bshell(unit, "write ING_SAT_SAMP_DATA 0 1 FORWARD_ACTION=0x1 COPYTO_CPU=0 DESTINATION=0x5 ADD_OLP_HDR=0x1 SAMPLE_TIMESTAMP=1 TIMESTAMP_TYPE=1 SAT_SESSION_ID=0xFF INT_PRI=0 OLP_HDR_TYPE_COMPRESSED=0x0");*/ 430 431 bcm_sat_endpoint_info_t endpoint_info; 432 433 /* UPMEP SAT TCAM Key fields */ 434 endpoint_info.flags = BCM_SAT_ENDPOINT_DOWNMEP | 435 BCM_SAT_ENDPOINT_MATCH_OUTER_VLAN; 436 437 endpoint_info.outer_vlan = pkt_vlan_pri[0]<<13 | pkt_vlan_cfi[0]<<12 | pkt_vlans[0]; 438 endpoint_info.src_gport = 0x8000001; 439 endpoint_info.ether_type = pkt_ether_type; 440 sal_memcpy(endpoint_info.src_mac_address, pkt_smac, 6); 441 sal_memcpy(endpoint_info.dst_mac_address, pkt_dmac, 6); 442 443 /* UPMEP SAT TCAM Data fields */ 444 endpoint_info.action_flags = BCM_SAT_ACTION_FWD_ACTION_REDIRECT; 445 endpoint_info.action_flags |= BCM_SAT_ACTION_SAMPLE_TIMESTAMP; 446 endpoint_info.dest_gport = 0x8000005; 447 endpoint_info.timestamp_format = 1; 448 endpoint_info.session_id = 0xff; 449 450 rv = bcm_sat_endpoint_create(unit, &endpoint_info); 451 if(rv != BCM_E_NONE) 452 { 453 printf("Error ! Failed to create SAT endpoint rv %d \n",rv); 454 return rv; 455 } 456 /* It will be used as trap_data in bcm_sat_ctf_trap_data_to_session_map() */ 457 trap_code_qualifier = endpoint_info.session_id; 458 } else { 459 rv = ctf_jer_specific_config(unit, ctf_id); 460 if (BCM_E_NONE != rv) { 461 printf("Error in ctf_jer_specific_config\n"); 462 return rv; 463 } 464 } 465 /* Set CTF configuration */ 466 rv = ctf_general_config(unit, ctf_id); 467 if (BCM_E_NONE != rv) { 468 printf("Error in ctf_general_config\n"); 469 return rv; 470 } 471 472 /*Set CTF Report*/ 473 bcm_sat_ctf_report_config_t ctf_report_config; 474 bcm_sat_ctf_report_config_t_init(&ctf_report_config); 475 ctf_report_config.report_sampling_percent = 90; 476 ctf_report_config.flags = BCM_SAT_CTF_REPORT_ADD_SEQ_NUM; 477 rv = bcm_sat_ctf_reports_config_set(unit, ctf_id, &ctf_report_config); 478 if (BCM_E_NONE != rv) { 479 printf("Error in bcm_sat_ctf_reports_config_set\n"); 480 return rv; 481 } 482 483 /* Sat event register 484 rv = bcm_sat_event_register(unit, bcmSATEventReport, cb_sat, (void*)1); 485 if (BCM_E_NONE != rv) { 486 printf("Error in bcm_sat_event_register\n"); 487 return rv; 488 } 489 */ 490 491 /* Get the collected information */ 492 rv = ctf_general_show_results(unit, ctf_id, 1); 493 if (BCM_E_NONE != rv) { 494 printf("Error in ctf_general_show_results\n"); 495 return rv; 496 } 497 498 return rv; 499 500 } 501 502 /* Clean up CTF configuration */ 503 int ctf_setup_cleanup(int unit) { 504 505 int rv = BCM_E_NONE; 506 507 /* clean up */ 508 /* Set the CTF flow as invalid */ 509 rv = bcm_sat_ctf_identifier_unmap(unit, &identifier); 510 if (BCM_E_NONE != rv) { 511 printf("Error in soc_sat_ctf_identifier_unmap\n"); 512 return rv; 513 } 514 515 /* Remove all trap id */ 516 rv = bcm_sat_ctf_trap_remove_all(unit); 517 if (BCM_E_NONE != rv) { 518 printf("Error in bcm_sat_ctf_trap_add\n"); 519 return rv; 520 } 521 522 /* Destroy the CTF flow */ 523 rv = bcm_sat_ctf_destroy(unit, ctf_id); 524 if (BCM_E_NONE != rv) { 525 printf("Error in bcm_sat_ctf_destroy\n"); 526 return rv; 527 } 528 529 return rv; 530 531 } 532 533 /**************Gtf Structure*********************************/ 534 enum gtf_test_mode_e { 535 gtf_test_mode_fl_down, /* Test SAT Frame LM Packet for Down Mep */ 536 gtf_test_mode_fl_up, /* Test SAT Frame LM Packet for Up Mep */ 537 gtf_test_mode_fd_down, /* Test SAT Frame DM Packet for Down Mep */ 538 gtf_test_mode_fd_up /* Test SAT Frame DM Packet for Up Mep */ 539 }; 540 541 /**************Envrionment Configure**********************/ 542 int gtf_debug_on = 1; /* Gtf Debug */ 543 544 int gtf_test_mode = gtf_test_mode_fl_down; 545 uint32 gtf_counters = 0; 546 547 /**************Gtf Object*********************************/ 548 bcm_sat_gtf_t gtf_id; 549 550 /**************Gtf Packet Parameter***********************/ 551 bcm_sat_header_type_t gtf_header_type = bcmSatHeaderUserDefined; 552 553 bcm_sat_payload_type_t gtf_payload_type = bcmSatPayloadConstant8Bytes; 554 uint8 gtf_payload_pattern[BCM_SAT_PAYLOAD_MAX_PATTERN_SIZE] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; 555 556 uint32 gtf_packet_length[BCM_SAT_GTF_NUM_OF_PRIORITIES][BCM_SAT_GTF_PACKET_LENGTH_NUM_OF_PATTERNS] = { /* 6bytes dune header + 64bytes */ 557 {64, 128, 256, 512, 1024, 1280, 1518, 9000}, 558 {64, 128, 256, 512, 1024, 1280, 1518, 9000}}; 559 uint32 gtf_packet_length_pattern[BCM_SAT_GTF_NUM_OF_PRIORITIES][BCM_SAT_GTF_PACKET_MAX_PATTERN_LENGTH] = { 560 {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7}, 561 {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7}}; 562 uint32 gtf_pattern_length[BCM_SAT_GTF_NUM_OF_PRIORITIES] = {1,1}; 563 564 bcm_sat_stamp_type_t gtf_stamp_type[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = { 565 {bcmSatStampConstant2Bit, bcmSatStampCounter8Bit, bcmSatStampCounter16Bit}, 566 {bcmSatStampConstant2Bit, bcmSatStampCounter8Bit, bcmSatStampCounter16Bit}}; 567 bcm_sat_stamp_field_t gtf_stamp_field[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = { 568 {bcmSatStampFieldUserDefined, bcmSatStampFieldOuterVlan, bcmSatStampFieldSrcMac}, 569 {bcmSatStampFieldUserDefined, bcmSatStampFieldOuterVlan, bcmSatStampFieldSrcMac}}; 570 uint32 gtf_stamp_inc_step[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = { 571 {1, 1, 1}, 572 {1, 1, 1}}; 573 uint32 gtf_stamp_inc_period_packets[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = { 574 {1, 1, 1}, 575 {1, 1, 1}}; 576 uint32 gtf_stamp_value[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = { 577 {1, 0, 0}, 578 {2, 0, 0}}; 579 uint32 gtf_stamp_offset[BCM_SAT_GTF_NUM_OF_PRIORITIES][3] = { /* start from ethernet header, index of first bit is 1 */ 580 {50, 1, 1}, /* stamp last two bits of SMAC to differentiate cir and eir */ 581 {50, 1, 1}}; 582 uint32 gtf_number_of_stamps[BCM_SAT_GTF_NUM_OF_PRIORITIES] = {0,0}; 583 584 uint32 gtf_number_of_ctfs[BCM_SAT_GTF_NUM_OF_PRIORITIES] = {1,1}; 585 586 uint32 gtf_add_data_tlv = 0; /* valid only when there is one paket length for one GTF */ 587 uint32 gtf_add_end_tlv = 1; 588 uint32 gtf_add_crc = 0; 589 uint32 gtf_crc_byte_offset = 38; 590 591 /* FD Packet Related Rarameter */ 592 uint32 gtf_ts_offset = 22; /* length of ethernet header + offset in FD PDU */ 593 594 /**************Gtf Bandwidth Parameter*********************/ 595 uint32 gtf_bw_cir_rate = 100; /* traffic rate - 5G. Units: kbps */ 596 uint32 gtf_bw_cir_max_burst = 1000; /* traffic burst - 1Mbit. Units: kbit */ 597 uint32 gtf_bw_eir_rate = 100; /* traffic rate - 5G. Units: kbps */ 598 uint32 gtf_bw_eir_max_burst = 1000; /* traffic burst - 1Mbit. Units: kbit */ 599 600 /**************Gtf Rate Pattern Parameter******************/ 601 bcm_sat_gtf_rate_pattern_mode_t gtf_rate_pattern_mode = bcmSatGtfRatePatternInterval; 602 uint32 gtf_rate_pattern_high = 10; /* 10kbits */ 603 uint32 gtf_rate_pattern_low = 10; /* 10kbits */ 604 uint32 gtf_rate_pattern_stop_iter_count = 1000; /* Stop after 1000 iterations */ 605 uint32 gtf_rate_pattern_stop_burst_count = 10000; 606 uint32 gtf_rate_pattern_stop_interval_count = 10000; 607 uint32 gtf_rate_pattern_burst_packet_weight = 1; /* Every packet in burst state increases the counter by 1 */ 608 uint32 gtf_rate_pattern_interval_packet_weight = 1; /* Every packet in interval state increases the counter by 1 */ 609 610 /**************GTF Packet Parameter - Packet Header******************/ 611 bcm_port_t gtf_source_port = 13; /* For UP-MEP case, port from where traffic will exit ASIC */ 612 bcm_port_t gtf_dst_port = 0; /* Port where MEP resides. GTF simulate traffic generation from this port */ 613 int gtf_dst_modid = 0; /* relevant to XGS */ 614 615 uint16 gtf_tpids[2] = {0x8100, 0x9100}; 616 int gtf_no_tags = 1; 617 618 uint8 gtf_mel = 0x3; 619 uint8 gtf_version = 0x0; 620 uint8 gtf_fl_opcode = 43; 621 uint8 gtf_fd_opcode = 47; 622 uint8 gtf_flags = 0; 623 uint16 gtf_source_mep_id = 0; 624 uint32 gtf_session_id = 0x12345678; 625 int gtf_fd_timestamp_offset = 22; 626 627 /* Temp varible */ 628 bcm_gport_t gtf_dst_sys_port = 0; 629 uint32 gtf_pkt_len_of_int_hdr = 0; 630 uint32 gtf_data_tlv_type = 3; 631 uint16 gtf_data_tlv_len = 0; 632 633 /**********************OLP Parameter**************************/ 634 bcm_mac_t olp_mac = {0xc0, 0x94, 0x2f, 0xc3, 0x83, 0x9e}; 635 bcm_mac_t xgs_mac = {0xf2, 0x44, 0x49, 0x39, 0x30, 0xec}; 636 uint16 olp_tpid = 0xa96d; 637 uint16 olp_vlan = 0xdd4; 638 uint16 olp_ether_type = 0x5843; 639 bcm_port_t olp_port = 5; 640 uint32 olp_tx_header_subtype = 2; 641 int olp_timestamp_action = 1; 642 643 644 int olp_config(int unit) { 645 int rv = BCM_E_NONE; 646 int station_id; 647 bcm_l2_station_t station; 648 bcm_gport_t gport; 649 650 rv = bcm_port_gport_get(unit, olp_port, &gport); 651 if (rv != BCM_E_NONE) { 652 printf("Failed($rv) in bcm_port_gport_get\n"); 653 return rv; 654 } 655 656 /* set olp tpid */ 657 rv = bcm_switch_control_set(unit, bcmSwitchOamOlpChipTpid, olp_tpid); 658 if (rv != BCM_E_NONE) { 659 printf("Failed($rv) in bcmSwitchOamOlpChipEtherType\n"); 660 return rv; 661 } 662 663 /* set VLAN for olp-xgs communication */ 664 rv = bcm_switch_control_set(unit, bcmSwitchOamOlpChipVlan, olp_vlan); 665 if (rv != BCM_E_NONE) { 666 printf("Failed($rv) in bcmSwitchOamOlpChipVlan\n"); 667 return rv; 668 } 669 670 /* set olp ethertype */ 671 rv = bcm_switch_control_set(unit, bcmSwitchOamOlpChipEtherType, olp_ether_type); 672 if (rv != BCM_E_NONE) { 673 printf("Failed($rv) in bcmSwitchOamOlpChipEtherType\n"); 674 return rv; 675 } 676 677 /* set olp mac */ 678 station.flags = BCM_L2_STATION_OLP; 679 station.src_port = gport; 680 station.dst_mac[0] = olp_mac[0]; 681 station.dst_mac[1] = olp_mac[1]; 682 station.dst_mac[2] = olp_mac[2]; 683 station.dst_mac[3] = olp_mac[3]; 684 station.dst_mac[4] = olp_mac[4]; 685 station.dst_mac[5] = olp_mac[5]; 686 rv = bcm_l2_station_add(unit, &station_id, &station); 687 if (rv != BCM_E_NONE) { 688 printf("Failed($rv) in setting olp mac\n"); 689 return rv; 690 } 691 692 /* set xgs mac */ 693 station.flags = BCM_L2_STATION_XGS_MAC; 694 station.src_port = gport; 695 station.dst_mac[0] = xgs_mac[0]; 696 station.dst_mac[1] = xgs_mac[1]; 697 station.dst_mac[2] = xgs_mac[2]; 698 station.dst_mac[3] = xgs_mac[3]; 699 station.dst_mac[4] = xgs_mac[4]; 700 station.dst_mac[5] = xgs_mac[5]; 701 rv = bcm_l2_station_add(unit, &station_id, &station); 702 if (rv != BCM_E_NONE) { 703 printf("Failed($rv) in setting xgs mac\n"); 704 return rv; 705 } 706 707 return rv; 708 } 709 710 int l2_addr_add(int unit, bcm_mac_t mac, uint16 vid, bcm_gport_t port) { 711 int rv = BCM_E_NONE; 712 bcm_l2_addr_t l2addr; 713 714 bcm_l2_addr_t_init(&l2addr, mac, vid); 715 l2addr.port = port; 716 717 rv = bcm_l2_addr_add(unit, &l2addr); 718 if (rv != BCM_E_NONE) { 719 printf("Failed($rv) in bcm_l2_addr_add\n"); 720 return rv; 721 } 722 723 return rv; 724 } 725 726 int set_port_keep_tag(int unit, uint16 vid, bcm_port_t port) { 727 int rv = BCM_E_NONE; 728 bcm_pbmp_t pbmp, ut_pbmp; 729 730 BCM_PBMP_PORT_SET(pbmp, port); 731 BCM_PBMP_CLEAR(ut_pbmp); 732 rv = bcm_vlan_port_remove(unit, vid, pbmp); 733 if (rv != BCM_E_NONE) { 734 printf("Failed($rv) in bcm_vlan_port_remove\n"); 735 return rv; 736 } 737 738 rv = bcm_vlan_port_add(unit, vid, pbmp, ut_pbmp); 739 if (rv != BCM_E_NONE) { 740 printf("Failed($rv) in bcm_vlan_port_add\n"); 741 return rv; 742 } 743 744 return rv; 745 } 746 747 /* 748 * PTCH-2 Header format: 749 * Field Size Bit/s 750 * Parser-Program-Control 1 15 751 * Opaque-PT-Attributes 3 14:12 752 * Reserved 4 11:8 753 * PP-SSP 8 7:0 754 */ 755 int _insert_dnx_ptch2(uint8* buffer, int byte_start_offset, 756 uint8 next_header_is_itmh, 757 uint8 opaque_value, 758 uint8 pp_ssp) 759 { 760 int offset = byte_start_offset; 761 int parser_program_ctl = 0; 762 763 parser_program_ctl = next_header_is_itmh ? 0 : 1; 764 buffer[offset++] = (parser_program_ctl<<7) | (opaque_value<<4); 765 buffer[offset++] = pp_ssp; 766 767 return offset; 768 } 769 770 /* 771 * Jericho-style ITMH Header format: 772 * Field Size Bit/s 773 * PPH_TYPE 2 31:30 774 * IN_MIRR_DISABLE 1 29 775 * FWD_DP 2 28:27 776 * FWD_DEST_INFO 19 26:8 777 * SNOOP_CMD 4 7:4 778 * FWD_TRAFFIC_CLASS 3 3:1 779 * ITMH_DESTINATION_INFO 1 0 780 * EXTENSION_EXISTS 781 * 782 * Jericho-style FWD_DEST_INFO(19bits) 783 * 1 1 Flow-ID(17) 784 * 1 0 Multicast-ID(17) 785 * 0 1 FEC-Pointer-ID(17) 786 * 0 0 1 Dest-System-Port-Agr(16) 787 */ 788 789 int _insert_dnx_itmh_jer(uint8* buffer, int byte_start_offset, 790 int dst_sys_port, 791 uint8 fwd_tc, 792 uint8 fwd_dp, 793 uint8 snoop_cmd, 794 uint8 in_mirr_flag, 795 uint8 pph_type) 796 { 797 int offset = byte_start_offset; 798 int fwd_dest_info = 1<<16 | dst_sys_port; 799 int dest_exten = 0; 800 801 buffer[offset++] = ((pph_type&0x3)<<6)|((in_mirr_flag&0x1)<<5)|((fwd_dp&0x3)<<3)|((fwd_dest_info&0x70000)>>16); 802 buffer[offset++] = ((fwd_dest_info&0xff00)>>8); 803 buffer[offset++] = (fwd_dest_info&0xff); 804 buffer[offset++] = ((snoop_cmd&0xf)<<4)|((fwd_tc&0x7)<<1)|(dest_exten&0x1); 805 806 return offset; 807 } 808 809 /* 810 * Arad-style ITMH Header format: 811 * Field Size Bit/s 812 * PPH_TYPE 2 31:30 813 * IN_MIRR_DISABLE 1 29 814 * SNOOP_CMD 4 28:25 815 * FWD_TRAFFIC_CLASS 3 24:22 816 * FWD_DP 2 21:20 817 * FWD_DEST_INFO 20 19:0 818 * 819 * Arad-style FWD_DEST_INFO(20bits) 820 821 * 0 Multicast-ID(19) 822 * 1 0 0 ISQ-Flow-ID(17) 823 * 1 1 1 OUTLIT(17) 824 * 1 1 0 0 Dest-System-Port-Agr(16) 825 * 1 1 0 1 Multicast-Flow-ID(17) 826 * 1 1 1 Flow-ID(17) 827 */ 828 829 int _insert_dnx_itmh_arad(uint8* buffer, int byte_start_offset, 830 int dst_sys_port, 831 uint8 fwd_tc, 832 uint8 fwd_dp, 833 uint8 snoop_cmd, 834 uint8 in_mirr_flag, 835 uint8 pph_type) 836 { 837 int offset = byte_start_offset; 838 int fwd_dest_info = 0xc0000 | dst_sys_port; 839 int dest_exten = 0; 840 841 buffer[offset++] = ((pph_type&0x3)<<6)|((in_mirr_flag&0x1)<<5)|((snoop_cmd&0xf)<<1)|((fwd_tc&0x4)>>2); 842 buffer[offset++] = ((fwd_tc&0x3)<<6) | ((fwd_dp&0x3)<<4) | ((fwd_dest_info&0xf0000)>>16); 843 buffer[offset++] = (fwd_dest_info&0xff00)>>8; 844 buffer[offset++] = (fwd_dest_info&0xff); 845 846 return offset; 847 } 848 849 /* 850 * OAM-TS Header format: 851 * Field Size Bit/s 852 * Type 2 47:46 853 * OAM-Sub-Type 3 45:43 854 * MEP-Type 1 42 855 * OAM-TS-Data 34 41:8 856 * Offset 8 7:0 857 */ 858 859 int _insert_dnx_oam_ts(uint8* buffer, int byte_start_offset, 860 uint8 type, 861 uint8 sub_type, 862 uint8 is_up_mep, 863 uint64 ts_data, 864 uint8 ts_offset) 865 { 866 int offset = byte_start_offset; 867 int mep_type; 868 int ts_data_hi = 0, ts_data_lo = 0; 869 870 mep_type = is_up_mep?1:0; 871 ts_data_hi = COMPILER_64_HI(ts_data); 872 ts_data_lo = COMPILER_64_LO(ts_data); 873 buffer[offset++] = ((type&0x3)<<6)|((sub_type&0x7)<<3)|((mep_type&0x1)<<2)|(ts_data_hi&0x3); 874 buffer[offset++] = (ts_data_lo&0xff000000)>>24; 875 buffer[offset++] = (ts_data_lo&0xff0000)>>16; 876 buffer[offset++] = (ts_data_lo&0xff00)>>8; 877 buffer[offset++] = (ts_data_lo&0xff); 878 buffer[offset++] = ts_offset&0xff; 879 880 return offset; 881 } 882 883 int _insert_dnx_pph_arad(uint8* buffer, int byte_start_offset) 884 { 885 int offset = byte_start_offset; 886 887 buffer[offset++] = 0; 888 buffer[offset++] = 0; 889 buffer[offset++] = 0; 890 buffer[offset++] = 0; 891 buffer[offset++] = 0; 892 buffer[offset++] = 0; 893 buffer[offset++] = 0; 894 895 return offset; 896 } 897 898 /* 899 * XGS OLP L2 Header 900 * Field Size 901 * OLP-DA 48 902 * OLP-SA 48 903 * OLP-VLAN 32 904 */ 905 int _insert_xgs_olp_l2(uint8* buffer, int byte_start_offset, 906 bcm_mac_t dest_addr, 907 bcm_mac_t src_addr, 908 uint16 tpid, 909 bcm_vlan_t vlan, 910 uint8 vlan_pri, 911 uint8 vlan_cfi, 912 uint16 ether_type) 913 { 914 int i = 0, offset = byte_start_offset; 915 for (i = 0; i < 6; i++) { 916 buffer[offset++] = dest_addr[i]; 917 } 918 for (i = 0; i < 6; i++) { 919 buffer[offset++] = src_addr[i]; 920 } 921 922 buffer[offset++] = (tpid>>8)&0xff; 923 buffer[offset++] = tpid&0xff; 924 buffer[offset++] = (vlan_pri<<5)|((vlan_cfi&&0x1)<<4)|((vlan>>8)&0xff); 925 buffer[offset++] = vlan&0xff; 926 927 buffer[offset++] = (ether_type>>8)&0xff; 928 buffer[offset++] = ether_type&0xff; 929 930 return offset; 931 } 932 933 /* 934 * XGS OLP TX Header 935 * From SB2_OLP_Architecture_Spec_0.94_Clean.docx 936 * Field Size Bit/s Bytes Description 937 * Version 4 127:124 15 Version =0 for Saber 2 & Katana 2 938 * HEADER_TYPE 8 123:116 15-14 00=OAM_TX_HEADER 939 * HEADER_SUBTYPE 8 115:108 14-13 03 = SAT_DOWN_MEP_TX 940 * 04 = SAT_UPMEP_TX 941 * INT_PRI 4 107:104 13 Internal Priority used for UP-MEP Tx. DP is assumed to be green. 942 * PORT_ID 16 103:88 12-11 [15-8] : MODID 943 * [7-0] : PORT_NUM 944 * COUNTER_1_LOCATION 1 87 10 0 = in IP 945 * 1 = in EP 946 * COUNTER_1_ID 15 86:72 10-9 Counter ID to be incremented or sampled by this packet 947 * COUNTER_1_ACTION 2 71:70 8 00: No-op 948 * 01: Increment 949 * 10: Sample 950 * 11: reserved 951 * COUNTER_2_LOCATION 1 69 8 952 * COUNTER_2_ID 15 68:54 8-6 953 * COUNTER_2_ACTION 2 53:52 6 954 * TIMESTAMP_ACTION 2 51:50 6 00: No-op 955 * 01: Sample 1588 Timestamp 956 * 10: Sample NTP Timestamp 957 * 11: Reserved 958 * OAM_REPLACEMENT_OFFSET 8 49:42 6-5 959 * RELATIVE_LM_REPLACEMENT_OFFSET 4 41:38 5-4 960 * RELATIVE_LM_REPLACEMENT_OFFSET_ADD_OR_SUB 1 37 4 961 * COUNTER_3_LOCATION 1 36 4 962 * COUNTER_3_ID 15 35:21 4-2 963 * COUNTER_3_ACTION 2 20:19 2 964 * COUNTER1_OFFSET_TO_LM_PAYLOAD 6 18:13 2-1 965 * COUNTER2_OFFSET_TO_LM_PAYLOAD 6 12:7 1-0 966 * COUNTER3_OFFSET_TO_LM_PAYLOAD 6 6:1 0 967 * Reserved 1 0 0 968 * Total 128 969 */ 970 int _insert_xgs_olp_tx(uint8* buffer, int byte_start_offset, 971 int is_down_mep, 972 int modid, 973 int port, 974 int timestamp_action, 975 int oam_offset) 976 { 977 int offset = byte_start_offset; 978 int version = 0; 979 int header_type = 0; 980 int header_subtype = (is_down_mep) ? (2) : (3); 981 int int_pri = 0; 982 983 int oam_replacement_offset = 0; 984 985 int counter_1_location = 0; 986 int counter_1_id = 0; 987 int counter_1_action = 0; 988 int counter_1_offset_to_lm_payload = 0; 989 int counter_2_location = 0; 990 int counter_2_id = 0; 991 int counter_2_action = 0; 992 int counter_2_offset_to_lm_payload = 0; 993 int counter_3_location = 0; 994 int counter_3_id = 0; 995 int counter_3_action = 0; 996 int counter_3_offset_to_lm_payload = 0; 997 998 int relative_lm_repalce_offset = 0; 999 int relative_lm_repalce_offset_add_or_sub = 0; 1000 1001 oam_replacement_offset = (oam_offset - 14) / 2; 1002 1003 /* byte 15: Version [3:0]->[7:4], 1004 * header_type[7:4]->[3:0] 1005 */ 1006 buffer[offset++] = ((version&0xf)<<4)|((header_type&0xf0)>>4); 1007 /* byte 14: header_type [3:0]->[7:4], 1008 * header_subtype[7:4]->[3:0] 1009 */ 1010 buffer[offset++] = ((header_type&0xf)<<4)|((header_subtype&0xf0)>>4); 1011 /* byte 13: header_subtype[3:0]->[7:4], 1012 * int_pri [3:0]->[3:0] 1013 */ 1014 buffer[offset++] = ((header_subtype&0xf)<<4)|((int_pri&0xf)>>4); 1015 /* byte 12: MODID [7:0]->[7:0] */ 1016 buffer[offset++] = (modid&0xff); 1017 /* byte 11: port [7:0]->[7:0] */ 1018 buffer[offset++] = (port&0xff); 1019 /* byte 10: COUNTER_1_LOCATION [0]->[7] 1020 * COUNTER_1_ID [14:8]->[6:0] 1021 */ 1022 buffer[offset++] = 0; 1023 /* byte 9: COUNTER_1_ID [7:0]->[7:0] */ 1024 buffer[offset++] = 0; 1025 /* byte 8: COUNTER_1_ACTION [1:0]->[7:6] 1026 * COUNTER_2_LOCATION [0]->[5] 1027 * COUNTER_2_ID [14:10]->[4:0] 1028 */ 1029 buffer[offset++] = 0; 1030 /* byte 7: COUNTER_2_ID [9:2]->[7:0] 1031 */ 1032 buffer[offset++] = 0; 1033 /* byte 6: COUNTER_2_ID [1:0]->[7:6] 1034 * COUNTER_2_ACTION [1:0]->[5:4] 1035 * TIMESTAMP_ACTION [1:0]->[3:2] 1036 * OAM_REPLACEMENT_OFFSET [7:6]->[1:0] 1037 */ 1038 buffer[offset++] = ((timestamp_action&0x3)<<2)|((oam_replacement_offset&0xc0)>>6); 1039 /* byte 5: OAM_REPLACEMENT_OFFSET [5:0]->[7:2] 1040 * RELATIVE_LM_REPLACEMENT_OFFSET [3:2]->[1:0] 1041 */ 1042 buffer[offset++] = (oam_replacement_offset&0x3f)<<2; 1043 /* byte 4: RELATIVE_LM_REPLACEMENT_OFFSET [1:0]->[7:6] 1044 * RELATIVE_LM_REPLACEMENT_OFFSET_ADD_OR_SUB [0]->[5] 1045 * COUNTER_3_LOCATION [0]->[4] 1046 * COUNTER_3_ID [14:11]->[3:0] 1047 */ 1048 buffer[offset++] = 0; 1049 /* byte 3: COUNTER_3_ID [10:3]->[7:0] */ 1050 buffer[offset++] = 0; 1051 /* byte 2: COUNTER_3_ID [2:0]->[7:5] 1052 * COUNTER_3_ACTION [1:0]->[4:3] 1053 * COUNTER1_OFFSET_TO_LM_PAYLOAD [5:3]->[2:0] 1054 */ 1055 buffer[offset++] = 0; 1056 /* byte 1: COUNTER1_OFFSET_TO_LM_PAYLOAD [2:0]->[7:5] 1057 * COUNTER2_OFFSET_TO_LM_PAYLOAD [5:1]->[4:0] 1058 */ 1059 buffer[offset++] = 0; 1060 /* byte 0: COUNTER2_OFFSET_TO_LM_PAYLOAD [0]->[7] 1061 * COUNTER2_OFFSET_TO_LM_PAYLOAD [5:0]->[6:1] 1062 * Reserved [0]->[0] 1063 */ 1064 buffer[offset++] = 0; 1065 1066 return offset; 1067 } 1068 1069 /* 1070 * Insert Ethernet Header 1071 */ 1072 int _insert_eth(uint8* buffer, int byte_start_offset, 1073 bcm_mac_t dest_addr, 1074 bcm_mac_t src_addr, 1075 uint16* tpids, 1076 bcm_vlan_t* vlans, 1077 uint8* vlan_pri, 1078 uint8* vlan_cfi, 1079 int no_tags, 1080 uint16 ether_type) 1081 { 1082 int i = 0, offset = byte_start_offset; 1083 for (i = 0; i < 6; i++) { 1084 buffer[offset++] = dest_addr[i]; 1085 } 1086 for (i = 0; i < 6; i++) { 1087 buffer[offset++] = src_addr[i]; 1088 } 1089 i = 0; 1090 while (no_tags) { 1091 buffer[offset++] = (tpids[i]>>8)&0xff; 1092 buffer[offset++] = tpids[i]&0xff; 1093 buffer[offset++] = (vlan_pri[i]<<5)|((vlan_cfi[i]&&0x1)<<4)|((vlans[i]>>8)&0xff); 1094 buffer[offset++] = vlans[i]&0xff; 1095 --no_tags; 1096 i++; 1097 } 1098 1099 buffer[offset++] = (ether_type>>8)&0xff; 1100 buffer[offset++] = ether_type&0xff; 1101 1102 return offset; 1103 } 1104 1105 /* 1106 * FL PDU Header format: Refer to MEF Sat spec. 1107 */ 1108 int _insert_fl_pdu(uint8* buffer, int byte_start_offset, 1109 uint8 mel, 1110 uint8 version, 1111 uint8 opcode, 1112 uint8 flags, 1113 uint8 tlv_offset, 1114 uint16 source_mep_id, 1115 uint32 session_id, 1116 uint8 add_data_tlv) 1117 { 1118 int tmp = 0, offset = byte_start_offset; 1119 buffer[offset++] = ((mel&0x7)<<5)|(version&0x1f); 1120 buffer[offset++] = opcode; 1121 buffer[offset++] = flags; 1122 buffer[offset++] = tlv_offset; /* TLV Offset: 16 */ 1123 buffer[offset++] = source_mep_id>>8; 1124 buffer[offset++] = source_mep_id&0xff; 1125 buffer[offset++] = 0; /* Reserved */ 1126 buffer[offset++] = 0; /* Reserved */ 1127 buffer[offset++] = (session_id>>24)&0xff; 1128 buffer[offset++] = (session_id>>16)&0xff; 1129 buffer[offset++] = (session_id>>8)&0xff; 1130 buffer[offset++] = (session_id&0xff); 1131 gtf_seq_number_offset = offset; /* Sequence Number */ 1132 offset += 4; 1133 buffer[offset++] = 0; /* Reserved */ 1134 buffer[offset++] = 0; /* Reserved */ 1135 buffer[offset++] = 0; /* Reserved */ 1136 buffer[offset++] = 0; /* Reserved */ 1137 1138 if (add_data_tlv) { 1139 tmp = offset - gtf_pkt_len_of_int_hdr; 1140 gtf_data_tlv_len = gtf_packet_length[0][0] - tmp - 4 - 3; /* 4bytes CRC for whole packet + 3bytes Data TLV Header */ 1141 gtf_data_tlv_len = gtf_add_crc?(gtf_data_tlv_len-4):gtf_data_tlv_len; 1142 gtf_data_tlv_len = gtf_add_end_tlv?(gtf_data_tlv_len-1):gtf_data_tlv_len; 1143 1144 buffer[offset++] = gtf_data_tlv_type; /* Data TLV Type */ 1145 buffer[offset++] = (gtf_data_tlv_len>>8)&0xff; /* Data TLV Length */ 1146 buffer[offset++] = (gtf_data_tlv_len&0xff); /* Data TLV Length */ 1147 } 1148 1149 return offset; 1150 } 1151 1152 /* 1153 * FD PDU Header format: Refer to MEF Sat spec. 1154 */ 1155 int _insert_fd_pdu(uint8* buffer, int byte_start_offset, 1156 uint8 mel, 1157 uint8 version, 1158 uint8 opcode, 1159 uint8 flags, 1160 uint8 tlv_offset, 1161 uint8 add_data_tlv) 1162 { 1163 int i = 0, tmp = 0, offset = byte_start_offset; 1164 1165 buffer[offset++] = ((mel&0x7)<<5)|(version&0x1f); 1166 buffer[offset++] = opcode; 1167 buffer[offset++] = flags; 1168 buffer[offset++] = tlv_offset; /* TLV Offset: 32 */ 1169 1170 gtf_timestamp_offset = offset; 1171 for (i = 0; i < 8; i++) { /* TxTimeStampf: 8bytes */ 1172 buffer[offset++] = 0; 1173 } 1174 1175 for (i = 0; i < 8; i++) { /* RxTimeStampf: 8bytes */ 1176 buffer[offset++] = 0; 1177 } 1178 1179 for (i = 0; i < 8; i++) { /* TxTimeStampb: 8bytes */ 1180 buffer[offset++] = 0; 1181 } 1182 1183 for (i = 0; i < 8; i++) { /* Reserved for DMR receiving equipment: 8bytes */ 1184 buffer[offset++] = 0x0; 1185 } 1186 1187 return offset; 1188 } 1189 1190 /* 1191 * Dump data in buffer - For debug usage. 1192 */ 1193 void _buffer_dump(uint8* buffer, int len) { 1194 int i = 0; 1195 printf(" len:%d\n", len); 1196 printf(" data:"); 1197 for (i = 0; i < len; i++) { 1198 if ((i % 16) == 0) printf("\n"); 1199 else if ((i % 4) == 0) printf(" "); 1200 printf("%02x", buffer[i]); 1201 } 1202 printf("\n\n"); 1203 } 1204 1205 /* 1206 * FL Packet format will be : 1207 * PTCH_2-O-ITMH-O-PPH-O-EthernetHeader-O-FL PDU for Down MEPs 1208 */ 1209 int _sat_gtf_packet_header_config_fl_down(int unit, uint8* pkt_data) { 1210 int offset = 0; 1211 1212 /* 1. Prepare internal header */ 1213 if (!is_xgs) { 1214 /* 1.1 Prepare internal DUNE header: PTCH */ 1215 offset = _insert_dnx_ptch2(pkt_data, offset, 1216 /* next_header_is_itmh */ 1, 1217 /* opaque_value */ 7, 1218 /* pp_ssp */ gtf_source_port); 1219 if (gtf_debug_on) { 1220 printf("After _insert_dnx_ptch2:\n"); 1221 _buffer_dump(pkt_data, offset); 1222 } 1223 1224 /* 1.2 Prepare internal DUNE header: ITMH */ 1225 offset = _insert_dnx_itmh_jer(pkt_data, offset, 1226 /* dst_sys_port */ gtf_dst_sys_port, 1227 /* fwd_tc */ 3, 1228 /* fwd_dp */ 0, 1229 /* snoop_cmd */ 0, 1230 /* in_mirr_flag */ 0, 1231 /* pph_type */ 1); 1232 if (gtf_debug_on) { 1233 printf("After _insert_dnx_itmh:\n"); 1234 _buffer_dump(pkt_data, offset); 1235 } 1236 1237 /* 1.3 Prepare internal DUNE header: PPH */ 1238 offset = _insert_dnx_pph_arad(pkt_data, offset); 1239 if (gtf_debug_on) { 1240 printf("After _insert_dnx_pph:\n"); 1241 _buffer_dump(pkt_data, offset); 1242 } 1243 } 1244 else { 1245 /* 1.1 Prepare XGS OLP L2 Header */ 1246 offset = _insert_xgs_olp_l2(pkt_data, offset, 1247 /* dest_addr */ xgs_mac, 1248 /* src_addr */ olp_mac, 1249 /* tpid */ olp_tpid, 1250 /* vlan */ olp_vlan, 1251 /* vlan_pri */ 0, 1252 /* vlan_cfi */ 0, 1253 /* ether_type */ olp_ether_type); 1254 if (gtf_debug_on) { 1255 printf("After _insert_xgs_olp_l2:\n"); 1256 _buffer_dump(pkt_data, offset); 1257 } 1258 1259 /* 1.2 Prepare XGS OLP TX Header */ 1260 offset = _insert_xgs_olp_tx(pkt_data, offset, 1261 /* is_down_mep */ 1, 1262 /* modid */ gtf_dst_modid, 1263 /* port */ gtf_dst_port, 1264 /* timestamp_action */ 0, 1265 /* oam_offset */ 0); 1266 if (gtf_debug_on) { 1267 printf("After _insert_xgs_olp_tx:\n"); 1268 _buffer_dump(pkt_data, offset); 1269 } 1270 } 1271 1272 gtf_pkt_len_of_int_hdr = offset; 1273 1274 /* 2. Prepare Ethernet header */ 1275 offset = _insert_eth(pkt_data, offset, 1276 pkt_dmac, 1277 pkt_smac, 1278 gtf_tpids, 1279 pkt_vlans, 1280 pkt_vlan_pri, 1281 pkt_vlan_cfi, 1282 gtf_no_tags, 1283 pkt_ether_type); 1284 if (gtf_debug_on) { 1285 printf("After _insert_eth:\n"); 1286 _buffer_dump(pkt_data, offset); 1287 } 1288 1289 /* 3. Prepare FL PDU header */ 1290 offset = _insert_fl_pdu(pkt_data, offset, 1291 gtf_mel, 1292 gtf_version, 1293 gtf_fl_opcode, 1294 gtf_flags, 1295 /* tlv_offset */ 16, 1296 gtf_source_mep_id, 1297 gtf_session_id, 1298 gtf_add_data_tlv); 1299 if (gtf_debug_on) { 1300 printf("After _insert_fl_pdu:\n"); 1301 _buffer_dump(pkt_data, offset); 1302 } 1303 1304 return offset; 1305 } 1306 1307 /* 1308 * FL Packet format will be : 1309 * PTCH-2-O-EthernetHeader-O-FL PDU for Up MEPs 1310 */ 1311 int _sat_gtf_packet_header_config_fl_up(int unit, uint8* pkt_data) { 1312 int offset = 0; 1313 1314 /* 1. Prepare internal header */ 1315 if (!is_xgs) { 1316 /*1.1 Prepare internal DUNE header: PTCH */ 1317 offset = _insert_dnx_ptch2(pkt_data, offset, 1318 /* next_header_is_itmh */ 0, 1319 /* opaque_value */ 7, 1320 /* pp_ssp */ gtf_source_port); 1321 if (gtf_debug_on) { 1322 printf("After _insert_dnx_ptch2:\n"); 1323 _buffer_dump(pkt_data, offset); 1324 } 1325 } 1326 else { 1327 /* 1.1 Prepare XGS OLP L2 Header */ 1328 offset = _insert_xgs_olp_l2(pkt_data, offset, 1329 /* dest_addr */ xgs_mac, 1330 /* src_addr */ olp_mac, 1331 /* tpid */ olp_tpid, 1332 /* vlan */ olp_vlan, 1333 /* vlan_pri */ 0, 1334 /* vlan_cfi */ 0, 1335 /* ether_type */ olp_ether_type); 1336 if (gtf_debug_on) { 1337 printf("After _insert_xgs_olp_l2:\n"); 1338 _buffer_dump(pkt_data, offset); 1339 } 1340 1341 /* 1.2 Prepare XGS OLP TX Header */ 1342 offset = _insert_xgs_olp_tx(pkt_data, offset, 1343 /* is_down_mep */ 0, 1344 /* modid */ gtf_dst_modid, 1345 /* port */ gtf_dst_port, 1346 /* timestamp_action */ 0, 1347 /* oam_offset */ 0); 1348 if (gtf_debug_on) { 1349 printf("After _insert_xgs_olp_tx:\n"); 1350 _buffer_dump(pkt_data, offset); 1351 } 1352 } 1353 1354 1355 gtf_pkt_len_of_int_hdr = offset; 1356 1357 /*2. Prepare Ethernet header */ 1358 offset = _insert_eth(pkt_data, offset, 1359 pkt_dmac, 1360 pkt_smac, 1361 gtf_tpids, 1362 pkt_vlans, 1363 pkt_vlan_pri, 1364 pkt_vlan_cfi, 1365 gtf_no_tags, 1366 pkt_ether_type); 1367 if (gtf_debug_on) { 1368 printf("After _insert_eth:\n"); 1369 _buffer_dump(pkt_data, offset); 1370 } 1371 1372 /*3. Prepare FL PDU header */ 1373 offset = _insert_fl_pdu(pkt_data, offset, 1374 gtf_mel, 1375 gtf_version, 1376 gtf_fl_opcode, 1377 gtf_flags, 1378 /* tlv_offset */ 16, 1379 gtf_source_mep_id, 1380 gtf_session_id, 1381 gtf_add_data_tlv); 1382 if (gtf_debug_on) { 1383 printf("After _insert_fl_pdu:\n"); 1384 _buffer_dump(pkt_data, offset); 1385 } 1386 1387 return offset; 1388 } 1389 1390 /* 1391 * FD Packet format will be : 1392 * PTCH-2-O-ITMH-O-OAM-TS-O-EthernetHeader-O-FL PDU for Down MEPs 1393 */ 1394 int _sat_gtf_packet_header_config_fd_down(int unit, uint8* pkt_data) { 1395 int offset = 0; 1396 int oam_sub_type = 3; 1397 uint64 oam_ts_data; 1398 1399 /* 1. Prepare internal header */ 1400 if (!is_xgs) { 1401 /*1.1 Prepare internal DUNE header: PTCH */ 1402 offset = _insert_dnx_ptch2(pkt_data, offset, 1403 /* next_header_is_itmh */ 1, 1404 /* opaque_value */ 7, 1405 /* pp_ssp */ gtf_source_port); 1406 if (gtf_debug_on) { 1407 printf("After _insert_dnx_ptch2:\n"); 1408 _buffer_dump(pkt_data, offset); 1409 } 1410 1411 /*1.2 Prepare internal DUNE header: ITMH */ 1412 offset = _insert_dnx_itmh_jer(pkt_data, offset, 1413 /* dst_sys_port */ gtf_dst_sys_port, 1414 /* fwd_tc */ 3, 1415 /* fwd_dp */ 0, 1416 /* snoop_cmd */ 0, 1417 /* in_mirr_flag */ 0, 1418 /* pph_type */ 3); 1419 if (gtf_debug_on) { 1420 printf("After _insert_dnx_itmh:\n"); 1421 _buffer_dump(pkt_data, offset); 1422 } 1423 1424 /*1.3 Prepare internal DUNE header: OAM-TS */ 1425 bcm_sat_config_t config; 1426 int rv = BCM_E_NONE; 1427 rv = bcm_sat_config_get(unit, &config); 1428 if (BCM_E_NONE != rv) { 1429 printf("Error in bcm_sat_config_get\n"); 1430 return rv; 1431 } 1432 if (config.timestamp_format == bcmSATTimestampFormatIEEE1588v1){ 1433 oam_sub_type = 2; 1434 } 1435 1436 1437 COMPILER_64_ZERO(oam_ts_data); 1438 offset = _insert_dnx_oam_ts(pkt_data, offset, 1439 /* type */ 0, 1440 /* sub_type */ oam_sub_type, 1441 /* is_up_mep */ 0, 1442 /* ts_data */ oam_ts_data, 1443 /* ts_offset */ gtf_ts_offset); 1444 if (gtf_debug_on) { 1445 printf("After _insert_dns_oam_ts:\n"); 1446 _buffer_dump(pkt_data, offset); 1447 } 1448 1449 /*1.4 Prepare internal DUNE header: PPH */ 1450 offset = _insert_dnx_pph_arad(pkt_data, offset); 1451 if (gtf_debug_on) { 1452 printf("After _insert_dnx_pph:\n"); 1453 _buffer_dump(pkt_data, offset); 1454 } 1455 } 1456 else { 1457 /* 1.1 Prepare XGS OLP L2 Header */ 1458 offset = _insert_xgs_olp_l2(pkt_data, offset, 1459 /* dest_addr */ xgs_mac, 1460 /* src_addr */ olp_mac, 1461 /* tpid */ olp_tpid, 1462 /* vlan */ olp_vlan, 1463 /* vlan_pri */ 0, 1464 /* vlan_cfi */ 0, 1465 /* ether_type */ olp_ether_type); 1466 if (gtf_debug_on) { 1467 printf("After _insert_xgs_olp_l2:\n"); 1468 _buffer_dump(pkt_data, offset); 1469 } 1470 1471 /* 1.2 Prepare XGS OLP TX Header */ 1472 offset = _insert_xgs_olp_tx(pkt_data, offset, 1473 /* is_down_mep */ 1, 1474 /* modid */ gtf_dst_modid, 1475 /* port */ gtf_dst_port, 1476 /* timestamp_action */ olp_timestamp_action, 1477 /* oam_offset */ gtf_fd_timestamp_offset); 1478 if (gtf_debug_on) { 1479 printf("After _insert_xgs_olp_tx:\n"); 1480 _buffer_dump(pkt_data, offset); 1481 } 1482 } 1483 1484 gtf_pkt_len_of_int_hdr = offset; 1485 1486 /*4. Prepare Ethernet header */ 1487 offset = _insert_eth(pkt_data, offset, 1488 pkt_dmac, 1489 pkt_smac, 1490 gtf_tpids, 1491 pkt_vlans, 1492 pkt_vlan_pri, 1493 pkt_vlan_cfi, 1494 gtf_no_tags, 1495 pkt_ether_type); 1496 if (gtf_debug_on) { 1497 printf("After _insert_eth:\n"); 1498 _buffer_dump(pkt_data, offset); 1499 } 1500 1501 /*5. Prepare FD PDU header */ 1502 offset = _insert_fd_pdu(pkt_data, offset, 1503 gtf_mel, 1504 gtf_version, 1505 gtf_fd_opcode, 1506 gtf_flags, 1507 /* tlv_offset */ 32, 1508 gtf_add_data_tlv); 1509 if (gtf_debug_on) { 1510 printf("After _insert_fd_pdu:\n"); 1511 _buffer_dump(pkt_data, offset); 1512 } 1513 1514 return offset; 1515 } 1516 1517 /* 1518 * setup an gtf: 1519 * 1. Create an GTF Object 1520 * 2. Configure packet info, including header type, header info, payload, packet edit info and packet offset. 1521 * 3. Set Bandwidth 1522 * 4. Set Rate Pattern 1523 */ 1524 int sat_gtf_setup(int unit, bcm_sat_gtf_t *gtf_id) { 1525 int rv = 0; 1526 bcm_sat_gtf_packet_config_t config; 1527 bcm_pkt_t *sat_header; 1528 uint8 pkt_data[128] = {0}; 1529 int pkt_size = 0; 1530 bcm_sat_gtf_bandwidth_t bw; 1531 bcm_sat_gtf_rate_pattern_t rate_pattern; 1532 int i = 0, priority = 0; 1533 bcm_gport_t dst_local_port; 1534 bcm_gport_t dst_sys_port; 1535 1536 if (!is_xgs) { 1537 BCM_GPORT_LOCAL_SET(dst_local_port, gtf_dst_port); 1538 rv = bcm_stk_gport_sysport_get(unit, dst_local_port, &dst_sys_port); 1539 if (rv != BCM_E_NONE) { 1540 printf("Failed($rv) in bcm_stk_gport_sysport_get\n"); 1541 return rv; 1542 } 1543 gtf_dst_sys_port = BCM_GPORT_SYSTEM_PORT_ID_GET(dst_sys_port); 1544 print gtf_dst_sys_port; 1545 } 1546 1547 if ((gtf_test_mode == gtf_test_mode_fl_up) || (gtf_test_mode == gtf_test_mode_fd_up)) { 1548 bcm_port_t port; 1549 1550 if (!is_xgs) { 1551 port = gtf_dst_port; 1552 } else { 1553 port = gtf_source_port; 1554 printf("UP-MEP: Simulate Traffic generated from %d and egress from %d \n", gtf_dst_port, gtf_source_port); 1555 } 1556 1557 /* add l2 addr for UP Mep test */ 1558 rv = l2_addr_add(unit, pkt_dmac, pkt_vlans[0], port); 1559 if (rv != BCM_E_NONE) { 1560 printf("Failed($rv) in l2_addr_add\n"); 1561 return rv; 1562 } 1563 1564 /* for egress port, configure to be transmitted as tagged */ 1565 rv = set_port_keep_tag(unit, pkt_vlans[0], port); 1566 if (rv != BCM_E_NONE) { 1567 printf("Failed($rv) in set_port_keep_tag\n"); 1568 return rv; 1569 } 1570 } 1571 1572 /* 1. Create GTF */ 1573 rv = bcm_sat_gtf_create(unit, 0, gtf_id); 1574 if (rv != BCM_E_NONE) { 1575 printf("Failed($rv) in bcm_sat_gtf_create\n"); 1576 return rv; 1577 } 1578 if (gtf_debug_on) printf("bcm_sat_gtf_create success\n"); 1579 1580 /* 2. Set Bandwidth */ 1581 bw.rate = gtf_bw_cir_rate; 1582 bw.max_burst = gtf_bw_cir_max_burst; 1583 rv = bcm_sat_gtf_bandwidth_set(unit, *gtf_id, 0, &bw); 1584 if (rv != BCM_E_NONE) { 1585 printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n"); 1586 return rv; 1587 } 1588 if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_set for cir success\n"); 1589 1590 bw.rate = gtf_bw_eir_rate; 1591 bw.max_burst = gtf_bw_eir_max_burst; 1592 rv = bcm_sat_gtf_bandwidth_set(unit, *gtf_id, 1, &bw); 1593 if (rv != BCM_E_NONE) { 1594 printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n"); 1595 return rv; 1596 } 1597 if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_set for eir success\n"); 1598 1599 bw.rate = gtf_bw_cir_rate + gtf_bw_eir_rate; 1600 bw.max_burst = gtf_bw_cir_max_burst+ gtf_bw_eir_max_burst; 1601 rv = bcm_sat_gtf_bandwidth_set(unit, *gtf_id, -1, &bw); 1602 if (rv != BCM_E_NONE) { 1603 printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n"); 1604 return rv; 1605 } 1606 if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_set for eir success\n"); 1607 1608 /* 3. Set Rate Pattern */ 1609 rate_pattern.rate_pattern_mode = gtf_rate_pattern_mode; 1610 rate_pattern.high_threshold = gtf_rate_pattern_high; 1611 rate_pattern.low_threshold = gtf_rate_pattern_low; 1612 rate_pattern.stop_iter_count = gtf_rate_pattern_stop_iter_count; 1613 rate_pattern.stop_burst_count = gtf_rate_pattern_stop_burst_count; 1614 rate_pattern.stop_interval_count = gtf_rate_pattern_stop_interval_count; 1615 rate_pattern.burst_packet_weight = gtf_rate_pattern_burst_packet_weight; 1616 rate_pattern.interval_packet_weight = gtf_rate_pattern_interval_packet_weight; 1617 rv = bcm_sat_gtf_rate_pattern_set(unit, *gtf_id, 0, &rate_pattern); 1618 if (rv != BCM_E_NONE) { 1619 printf("Failed($rv) in bcm_sat_gtf_rate_pattern_set\n"); 1620 return rv; 1621 } 1622 if (gtf_debug_on) printf("bcm_sat_gtf_rate_pattern_set success\n"); 1623 1624 rv = bcm_sat_gtf_rate_pattern_set(unit, *gtf_id, 1, &rate_pattern); 1625 if (rv != BCM_E_NONE) { 1626 printf("Failed($rv) in bcm_sat_gtf_rate_pattern_set\n"); 1627 return rv; 1628 } 1629 if (gtf_debug_on) printf("bcm_sat_gtf_rate_pattern_set success\n"); 1630 1631 /* 4. Configure packet */ 1632 bcm_sat_gtf_packet_config_t_init(&config); 1633 1634 /* 4.1 Configure header type*/ 1635 config.sat_header_type = gtf_header_type; 1636 1637 /* 4.2 Configure header info */ 1638 rv = bcm_pkt_alloc(unit, 128, 0, &sat_header); 1639 if (rv != BCM_E_NONE) { 1640 printf("Failed($rv) in bcm_pkt_alloc\n"); 1641 return rv; 1642 } 1643 if (gtf_debug_on) printf("bcm_pkt_alloc success\n"); 1644 1645 switch(gtf_test_mode) { 1646 case gtf_test_mode_fl_down: 1647 pkt_size = _sat_gtf_packet_header_config_fl_down(unit, sat_header->pkt_data->data); 1648 break; 1649 case gtf_test_mode_fl_up: 1650 pkt_size = _sat_gtf_packet_header_config_fl_up(unit, sat_header->pkt_data->data); 1651 break; 1652 case gtf_test_mode_fd_down: 1653 pkt_size = _sat_gtf_packet_header_config_fd_down(unit, sat_header->pkt_data->data); 1654 break; 1655 default: 1656 printf("ERR: wrong gtf_test_mode(%d)\n", gtf_test_mode); 1657 return BCM_E_PARAM; 1658 } 1659 1660 sat_header->pkt_data->len = pkt_size; 1661 1662 config.header_info.pkt_data = sat_header->pkt_data; 1663 config.header_info.blk_count = 1; 1664 1665 /* 4.3 Configure payload */ 1666 config.payload.payload_type = gtf_payload_type; 1667 if (config.payload.payload_type != bcmSatPayloadPRBS) { 1668 for (i = 0; i < BCM_SAT_PAYLOAD_MAX_PATTERN_SIZE; i++) { 1669 config.payload.payload_pattern[i] = gtf_payload_pattern[i]; 1670 } 1671 } 1672 1673 /* 4.4 Configure packet edit */ 1674 for (priority = 0; priority < 2; priority++) { 1675 for (i = 0; i < BCM_SAT_GTF_PACKET_LENGTH_NUM_OF_PATTERNS; i++) { 1676 config.packet_edit[priority].packet_length[i] = gtf_packet_length[priority][i] + gtf_pkt_len_of_int_hdr - 4; /* subtract 4bytes CRC for whole packet */ 1677 } 1678 config.packet_edit[priority].pattern_length = gtf_pattern_length[priority]; 1679 for (i = 0; i < gtf_pattern_length[priority]; i++) { 1680 config.packet_edit[priority].packet_length_pattern[i] = gtf_packet_length_pattern[priority][i]; 1681 } 1682 config.packet_edit[priority].number_of_stamps = gtf_number_of_stamps[priority]; 1683 for (i = 0; i < gtf_number_of_stamps[priority]; i++) { 1684 config.packet_edit[priority].stamps[i].stamp_type = gtf_stamp_type[priority][i]; 1685 config.packet_edit[priority].stamps[i].field_type = gtf_stamp_field[priority][i]; 1686 config.packet_edit[priority].stamps[i].inc_step = gtf_stamp_inc_step[priority][i]; 1687 config.packet_edit[priority].stamps[i].inc_period_packets = gtf_stamp_inc_period_packets[priority][i]; 1688 config.packet_edit[priority].stamps[i].value = gtf_stamp_value[priority][i]; 1689 config.packet_edit[priority].stamps[i].offset = gtf_stamp_offset[priority][i] + gtf_pkt_len_of_int_hdr*8; 1690 } 1691 config.packet_edit[priority].number_of_ctfs = gtf_number_of_ctfs[priority]; 1692 1693 if (gtf_add_end_tlv) { 1694 config.packet_edit[priority].flags |= BCM_SAT_GTF_PACKET_EDIT_ADD_END_TLV; 1695 } 1696 if (gtf_add_crc) { 1697 config.packet_edit[priority].flags |= BCM_SAT_GTF_PACKET_EDIT_ADD_CRC; 1698 } 1699 } 1700 1701 /* 4.5 Configure packet offset */ 1702 config.offsets.seq_number_offset = gtf_seq_number_offset; 1703 config.offsets.crc_byte_offset = gtf_crc_byte_offset + gtf_pkt_len_of_int_hdr; 1704 config.offsets.timestamp_offset = gtf_timestamp_offset; 1705 1706 if (is_xgs == 0) { 1707 config.packet_context_id = 0; 1708 } 1709 1710 rv = bcm_sat_gtf_packet_config(unit, *gtf_id, &config); 1711 if (rv != BCM_E_NONE) { 1712 printf("Failed($rv) in bcm_sat_gtf_packet_config\n"); 1713 return rv; 1714 } 1715 if (gtf_debug_on) printf("bcm_sat_gtf_packet_config success\n"); 1716 1717 /* 5. Start packet generation */ 1718 rv = bcm_sat_gtf_packet_start(unit, *gtf_id, bcmSatGtfPriAll); 1719 if (rv != BCM_E_NONE) { 1720 printf("Failed($rv) in bcm_sat_gtf_packet_start\n"); 1721 return rv; 1722 } 1723 if (gtf_debug_on) printf("bcm_sat_gtf_packet_start success\n"); 1724 1725 printf("create gtf(%d) success\n", *gtf_id); 1726 return rv; 1727 } 1728 1729 int sat_gtf_cleanup(int unit, bcm_sat_gtf_t gtf_id) { 1730 int rv = 0; 1731 bcm_sat_gtf_bandwidth_t bw; 1732 1733 /* Reset GTF bandwidth */ 1734 bw.rate = 0; 1735 bw.max_burst = 0; 1736 rv = bcm_sat_gtf_bandwidth_set(unit, gtf_id, 0, &bw); 1737 if (rv != BCM_E_NONE) { 1738 printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n"); 1739 return rv; 1740 } 1741 rv = bcm_sat_gtf_bandwidth_set(unit, gtf_id, 0, &bw); 1742 if (rv != BCM_E_NONE) { 1743 printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n"); 1744 return rv; 1745 } 1746 rv = bcm_sat_gtf_bandwidth_set(unit, gtf_id, 0, &bw); 1747 if (rv != BCM_E_NONE) { 1748 printf("Failed($rv) in bcm_sat_gtf_bandwidth_set\n"); 1749 return rv; 1750 } 1751 1752 /* Destroy the GTF Object */ 1753 rv = bcm_sat_gtf_destroy(unit, gtf_id); 1754 if (BCM_E_NONE != rv) { 1755 printf("Failed($rv) in bcm_sat_gtf_destroy\n"); 1756 return rv; 1757 } 1758 if (gtf_debug_on) printf("bcm_sat_gtf_destroy success\n"); 1759 1760 return rv; 1761 } 1762 1763 int sat_gtf_enable(int unit, bcm_sat_gtf_t gtf_id, int priority, int is_enable) { 1764 int rv = 0; 1765 1766 if (is_enable) { 1767 /* Start packet generation */ 1768 rv = bcm_sat_gtf_packet_start(unit, gtf_id, priority); 1769 if (BCM_E_NONE != rv) { 1770 printf("Failed($rv) in bcm_sat_gtf_packet_start\n"); 1771 return rv; 1772 } 1773 if (gtf_debug_on) printf("bcm_sat_gtf_packet_start success\n"); 1774 } 1775 else { 1776 /* Stop packet generation */ 1777 rv = bcm_sat_gtf_packet_stop(unit, gtf_id, priority); 1778 if (BCM_E_NONE != rv) { 1779 printf("Failed($rv) in bcm_sat_gtf_packet_stop\n"); 1780 return rv; 1781 } 1782 if (gtf_debug_on) printf("bcm_sat_gtf_packet_stop success\n"); 1783 } 1784 1785 return rv; 1786 } 1787 1788 int sat_gtf_show(int unit, bcm_sat_gtf_t gtf_id) { 1789 int rv = 0; 1790 bcm_sat_gtf_bandwidth_t bw; 1791 bcm_sat_gtf_rate_pattern_t rate_pattern; 1792 uint64 stat_value; 1793 int priority = 0; 1794 1795 /* 1. Get Bandwidth */ 1796 for (priority = -1; priority < 2; priority++) { 1797 rv = bcm_sat_gtf_bandwidth_get(unit, gtf_id, priority, &bw); 1798 if (rv != BCM_E_NONE) { 1799 printf("Failed($rv) in bcm_sat_gtf_bandwidth_get\n"); 1800 return rv; 1801 } 1802 if (gtf_debug_on) printf("bcm_sat_gtf_bandwidth_get success\n"); 1803 print bw; 1804 } 1805 1806 /* 2. Get Rate Pattern */ 1807 for (priority = 0; priority < 2; priority++) { 1808 rv = bcm_sat_gtf_rate_pattern_get(unit, gtf_id, priority, &rate_pattern); 1809 if (rv != BCM_E_NONE) { 1810 printf("Failed($rv) in bcm_sat_gtf_rate_pattern_get\n"); 1811 return rv; 1812 } 1813 if (gtf_debug_on) printf("bcm_sat_gtf_rate_pattern_get success\n"); 1814 print rate_pattern; 1815 } 1816 1817 /* 3. Get Stat */ 1818 for (priority = 0; priority < 2; priority++) { 1819 rv = bcm_sat_gtf_stat_get(unit, gtf_id, priority, 0, bcmSatGtfStatPacketCount, &stat_value); 1820 if (rv != BCM_E_NONE) { 1821 printf("Failed($rv) in bcm_sat_gtf_stat_get\n"); 1822 return rv; 1823 } 1824 if (gtf_debug_on) printf("bcm_sat_gtf_stat_get success\n"); 1825 print stat_value; 1826 } 1827 1828 return 0; 1829 } 1830 1831 int sat_gtf_stat_show(int unit, bcm_sat_gtf_t gtf_id) { 1832 int rv = 0; 1833 uint64 stat_value; 1834 int priority = 0; 1835 1836 /* 1. Get Stat */ 1837 for (priority = 0; priority < 2; priority++) { 1838 rv = bcm_sat_gtf_stat_get(unit, gtf_id, priority, 0, bcmSatGtfStatPacketCount, &stat_value); 1839 if (rv != BCM_E_NONE) { 1840 printf("Failed($rv) in bcm_sat_gtf_stat_get\n"); 1841 return rv; 1842 } 1843 if (gtf_debug_on) printf("bcm_sat_gtf_stat_get success\n"); 1844 print stat_value; 1845 } 1846 1847 return 0; 1848 } 1849 1850 /* 1851 * In Jericho, the gtf counters can't get correctly both during the SAT traffic and also after stopping SAT traffic 1852 * The workaround is avariable if the sequence number is enabled. 1853 */ 1854 int get_gtf_tx_counter(int chip, bcm_sat_gtf_t gtf_id_wk) 1855 { 1856 int rv=0; 1857 int priority=0; 1858 uint32 flags=0; 1859 bcm_sat_gtf_stat_counter_t type=0; 1860 uint32 value_last=0; 1861 int cnt; 1862 uint32 total_hi=0; 1863 uint32 total_lo=0; 1864 uint32 lo_work=0; 1865 mem_val value = {0}; 1866 1867 /*start GTF pkt*/ 1868 rv |= bcm_sat_gtf_packet_start(chip, gtf_id_wk, bcmSatGtfPriCir); 1869 1870 printf("The transmission of pkt begins.\n"); 1871 printf("... It waits for 10 seconds.\n"); 1872 sal_sleep(10); 1873 1874 for(cnt=0; cnt<10; cnt++) 1875 { 1876 lo_work = total_lo; 1877 /*get sequence number*/ 1878 diag_mem_field_get(0, "OAMP_SAT_TX_GEN_PARAMS", "SEQ_NUM_NXT_VALUE", (16 + gtf_id_wk), value); 1879 1880 total_lo += (value[0] - value_last); 1881 if(total_lo < lo_work) 1882 { 1883 total_hi += 1; 1884 } 1885 /*printf("[cnt=%04d] %08x %08x ", cnt, total_hi, total_lo); 1886 print (value[0] - value_last);*/ 1887 value_last = value[0]; 1888 } 1889 1890 /*stop pkt*/ 1891 rv |= bcm_sat_gtf_packet_stop(chip, gtf_id_wk, bcmSatGtfPriCir); 1892 1893 printf("The transmission of pkt is stopped.\n"); 1894 printf("... It waits for 1 seconds.\n"); 1895 sal_sleep(1); 1896 1897 /*get sequence number*/ 1898 diag_mem_field_get(0, "OAMP_SAT_TX_GEN_PARAMS", "SEQ_NUM_NXT_VALUE", (16 + gtf_id_wk) , value); 1899 1900 total_lo += (value[0] - value_last); 1901 if(total_lo < lo_work) 1902 { 1903 total_hi += 1; 1904 } 1905 1906 printf("[cnt=%04d] %08x %08x ", cnt, total_hi, total_lo); 1907 print value[0]; 1908 gtf_counters = value[0]; 1909 1910 return 0; 1911 } 1912 int sat_setup(int unit) { 1913 1914 bcm_sat_config_t config; 1915 int rv = BCM_E_NONE; 1916 1917 /* global configuration */ 1918 bcm_sat_config_t_init(&config); 1919 config.timestamp_format = bcmSATTimestampFormatNTP; 1920 config.config_flags = 0; 1921 rv = bcm_sat_config_set(unit, &config); 1922 if (BCM_E_NONE != rv) { 1923 printf("Error in bcm_sat_config_set\n"); 1924 return rv; 1925 } 1926 1927 /* setup a GTF */ 1928 rv = sat_gtf_setup(unit, >f_id); 1929 if (BCM_E_NONE != rv) { 1930 printf("Failed($rv) in sat_gtf_setup\n"); 1931 return rv; 1932 } 1933 1934 /* show GTF info */ 1935 rv = sat_gtf_show(unit, gtf_id); 1936 if (BCM_E_NONE != rv) { 1937 printf("Failed($rv) in sat_gtf_show\n"); 1938 return rv; 1939 } 1940 1941 /* setup a CTF */ 1942 rv = ctf_setup(unit); 1943 if (BCM_E_NONE != rv) { 1944 printf("Error in ctf_setup\n"); 1945 return rv; 1946 } 1947 1948 return rv; 1949 1950 } 1951 /** 1952 * \brief 1953 * Add the PMF field group that SAT uses it to capture matched packets to SAT engine. 1954 * \param [in] unit - Device ID 1955 * \param [in] in_port - IN port 1956 * \param [in] ctf_id - CTF ID 1957 * \param [in] oam_offset - OAM offset to set in the OAM PMF action 1958 * \return 1959 * int - Error Type 1960 * \remark 1961 * * None 1962 * \see 1963 * * None 1964 */ 1965 int ctf_pmf_config_jr2(int unit,int in_port,bcm_gport_t sat_gport,int ctf_id,int oam_offset ) 1966 { 1967 bcm_field_group_info_t fg_info; 1968 bcm_field_group_attach_info_t attach_info; 1969 bcm_field_entry_info_t ent_info; 1970 bcm_field_context_info_t context_info; 1971 bcm_field_presel_entry_data_t p_data; 1972 bcm_field_presel_entry_id_t p_id; 1973 int rv = BCM_E_NONE; 1974 int trap_code_qualifier; 1975 uint32 attach_presel = 5; 1976 bcm_gport_t gport; 1977 1978 bcm_field_group_info_t_init(&fg_info); 1979 fg_info.fg_type = bcmFieldGroupTypeTcam; 1980 fg_info.stage = bcmFieldStageIngressPMF1; 1981 1982 /* Set quals */ 1983 fg_info.nof_quals = 1; 1984 fg_info.qual_types[0] = bcmFieldQualifyInPort; 1985 /*fg_info.qual_types[1] = bcmFieldQualifyStageIngress;*/ 1986 1987 /* Set actions */ 1988 fg_info.nof_actions = 2; 1989 fg_info.action_types[0] = bcmFieldActionTrap; /*bcmFieldActionTrapCodeQualifier */ 1990 fg_info.action_types[1] = bcmFieldActionOam; 1991 1992 rv = bcm_field_group_add(unit, BCM_FIELD_FLAG_MSB_RESULT_ALIGN, &fg_info, &sat_fg_id); 1993 if (rv != BCM_E_NONE) 1994 { 1995 printf("Error (%d), in bcm_field_group_add\n", rv); 1996 return rv; 1997 } 1998 printf("Created TCAM field group (%d) in iPMF1 \n", sat_fg_id); 1999 2000 /**Attach context**/ 2001 bcm_field_group_attach_info_t_init(&attach_info); 2002 bcm_field_context_info_t_init(&context_info); 2003 2004 rv = bcm_field_context_create(unit, 0, bcmFieldStageIngressPMF1, &context_info, &sat_field_context_id); 2005 if (rv != BCM_E_NONE) 2006 { 2007 printf("Error (%d), in bcm_field_context_create\n", rv); 2008 return rv; 2009 } 2010 2011 attach_info.key_info.nof_quals = fg_info.nof_quals; 2012 attach_info.payload_info.nof_actions = fg_info.nof_actions; 2013 attach_info.key_info.qual_types[0] = fg_info.qual_types[0]; 2014 attach_info.payload_info.action_types[0] = fg_info.action_types[0]; 2015 attach_info.payload_info.action_types[1] = fg_info.action_types[1]; 2016 2017 attach_info.key_info.qual_info[0].input_type = bcmFieldInputTypeMetaData; 2018 attach_info.key_info.qual_info[0].input_arg = 1; 2019 attach_info.key_info.qual_info[0].offset = 0; 2020 2021 2022 rv = bcm_field_group_context_attach(unit, 0, sat_fg_id, sat_field_context_id, &attach_info); 2023 if (rv != BCM_E_NONE) 2024 { 2025 printf("Error (%d), in bcm_field_group_context_attach\n", rv); 2026 return rv; 2027 } 2028 printf("Attached FG (%d) to context (%d)\n",sat_fg_id,sat_field_context_id); 2029 2030 bcm_field_entry_info_t_init(&ent_info); 2031 ent_info.priority = 1; 2032 ent_info.nof_entry_quals = 1; 2033 2034 ent_info.entry_qual[0].type = fg_info.qual_types[0]; 2035 /**in port 13*/ 2036 BCM_GPORT_LOCAL_SET(gport, in_port); 2037 ent_info.entry_qual[0].value[0] = gport; 2038 ent_info.entry_qual[0].mask[0] = 0xffffffff; 2039 2040 trap_code_qualifier = ctf_id; 2041 ent_info.nof_entry_actions = 2; 2042 ent_info.entry_action[0].type = fg_info.action_types[0]; 2043 ent_info.entry_action[0].value[0] = sat_gport; 2044 ent_info.entry_action[0].value[1] = trap_code_qualifier; 2045 ent_info.entry_action[1].type = fg_info.action_types[1]; 2046 ent_info.entry_action[1].value[0] = 0; 2047 ent_info.entry_action[1].value[1] = oam_offset; 2048 ent_info.entry_action[1].value[2] = 0; 2049 ent_info.entry_action[1].value[3] = 0; 2050 2051 rv = bcm_field_entry_add(unit, 0, sat_fg_id, &ent_info, &sat_fg_entry_id); 2052 if (rv != BCM_E_NONE) 2053 { 2054 printf("Error (%d), in bcm_field_entry_add\n", rv); 2055 return rv; 2056 } 2057 printf("Entry add: id:(0x%x) Src_ip:(0x%x) tc_val:(%d)\n",sat_fg_entry_id,ent_info.entry_qual[0].value[0], 2058 ent_info.entry_action[0].value[0] ); 2059 2060 bcm_field_presel_entry_id_info_init(&p_id); 2061 bcm_field_presel_entry_data_info_init(&p_data); 2062 2063 p_id.presel_id = attach_presel; 2064 p_id.stage = bcmFieldStageIngressPMF1; 2065 p_data.entry_valid = TRUE; 2066 p_data.context_id = sat_field_context_id; 2067 p_data.nof_qualifiers = 1; 2068 2069 p_data.qual_data[0].qual_type = bcmFieldQualifyForwardingType; 2070 p_data.qual_data[0].qual_arg = 0; 2071 p_data.qual_data[0].qual_value = bcmFieldLayerTypeEth; 2072 p_data.qual_data[0].qual_mask = 0x1F; 2073 2074 rv = bcm_field_presel_set(unit, 0, &p_id, &p_data); 2075 if (rv != BCM_E_NONE) 2076 { 2077 printf("Error (%d), in dnx_field_presel_set \n", rv); 2078 return rv; 2079 } 2080 2081 printf("Presel (%d) was configured for stage(iPMF1) context(%d) fwd_layer(Ethernet) \n", 2082 attach_presel,sat_field_context_id); 2083 2084 return 0; 2085 } 2086 2087 2088 /** 2089 * \brief 2090 * Delete the PMF field group that SAT uses it. 2091 * \param [in] unit - Device ID 2092 * \return 2093 * int - Error Type 2094 * \remark 2095 * * None 2096 * \see 2097 * * None 2098 */ 2099 int ctf_pmf_destroy_jr2(int unit) 2100 { 2101 int rv = BCM_E_NONE; 2102 int ii= 0; 2103 bcm_field_entry_qual_t entry_qual_info[BCM_FIELD_NUMBER_OF_QUALS_PER_GROUP]; 2104 uint32 attach_presel = 5; 2105 bcm_field_presel_entry_data_t p_data; 2106 bcm_field_presel_entry_id_t p_id; 2107 2108 bcm_field_presel_entry_id_info_init(&p_id); 2109 bcm_field_presel_entry_data_info_init(&p_data); 2110 2111 p_id.presel_id = attach_presel; 2112 p_id.stage = bcmFieldStageIngressPMF1; 2113 p_data.entry_valid = FALSE; 2114 p_data.context_id = 0; 2115 2116 rv = bcm_field_presel_set(unit, 0, &p_id, &p_data); 2117 if (rv != BCM_E_NONE) 2118 { 2119 printf("Error (%d), in dnx_field_presel_set \n", rv); 2120 return rv; 2121 } 2122 2123 rv = bcm_field_group_context_detach(unit, sat_fg_id, sat_field_context_id); 2124 if(rv != BCM_E_NONE) 2125 { 2126 printf("Error (%d), in bcm_field_group_context_detach\n", rv); 2127 return rv; 2128 } 2129 2130 rv = bcm_field_context_destroy(unit,bcmFieldStageIngressPMF1,sat_field_context_id); 2131 if (rv != BCM_E_NONE) 2132 { 2133 printf("Error (%d), in bcm_field_context_destroy eth\n", rv); 2134 return rv; 2135 } 2136 2137 rv = bcm_field_entry_delete(unit, sat_fg_id, &entry_qual_info, sat_fg_entry_id); 2138 if (rv != BCM_E_NONE) 2139 { 2140 printf("Error (%d), in bcm_field_group_delete\n", rv); 2141 return rv; 2142 } 2143 2144 rv = bcm_field_group_delete(unit, sat_fg_id); 2145 if (rv != BCM_E_NONE) 2146 { 2147 printf("Error (%d), in bcm_field_group_delete\n", rv); 2148 return rv; 2149 } 2150 return 0; 2151 2152 } 2153 2154 int sat_cleanup(int unit) { 2155 2156 int rv = BCM_E_NONE; 2157 2158 /* clean up CTF */ 2159 rv = ctf_setup_cleanup(unit); 2160 if (BCM_E_NONE != rv) { 2161 printf("Error in ctf_setup_cleanup\n"); 2162 return rv; 2163 } 2164 2165 /* clean up GTF */ 2166 rv = sat_gtf_cleanup(unit, gtf_id); 2167 if (BCM_E_NONE != rv) { 2168 printf("Failed($rv) in sat_gtf_cleanup\n"); 2169 return rv; 2170 } 2171 2172 2173 return rv; 2174 2175 } 2176