txrx.c (58541B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * socdiag tx (transmit) and rx (receive) commands 8 */ 9 10 #include <sal/types.h> 11 #include <sal/core/time.h> 12 #include <sal/core/thread.h> 13 #include <sal/core/libc.h> 14 #include <sal/appl/sal.h> 15 #include <sal/appl/io.h> 16 #include <shared/bsl.h> 17 #include <soc/types.h> 18 #include <soc/debug.h> 19 #include <soc/cm.h> 20 #include <soc/higig.h> 21 #include <soc/dma.h> 22 #include <soc/dcb.h> 23 #include <soc/drv.h> 24 25 #ifdef __KERNEL__ 26 #include <linux/kernel.h> 27 #include <linux/net.h> 28 #include <linux/in.h> 29 #else 30 #include <stdlib.h> 31 #include <sys/types.h> 32 #include <sys/socket.h> 33 #include <netinet/in.h> 34 #endif 35 36 #include <bcm/tx.h> 37 #include <bcm/pkt.h> 38 #include <bcm/rx.h> 39 #include <bcm/port.h> 40 #include <bcm/error.h> 41 #include <bcm/stack.h> 42 43 #include <appl/diag/system.h> 44 #include <appl/diag/dport.h> 45 #include <appl/diag/visibility.h> 46 47 #if defined(BCM_BRADLEY_SUPPORT) 48 #include <soc/bradley.h> 49 #endif 50 #if defined(BCM_ESW_SUPPORT) 51 #include <bcm_int/common/multicast.h> 52 #endif 53 54 #if defined(BCM_XGS_SUPPORT) && defined(BCM_CPU_TX_PROC_SUPPORT) 55 #include <soc/proc_hdr.h> 56 #endif 57 58 /* These modes must correspond with the order of strings below */ 59 #define ENCAP_IEEE 0 60 #define ENCAP_HIGIG 1 61 #define ENCAP_B5632 2 62 #define ENCAP_HIGIG2 3 /* Note: no BCM_PORT_ENCAP_ equivalent */ 63 #define ENCAP_RAW 4 /* Note: no BCM_PORT_ENCAP_ equivalent */ 64 #define ENCAP_COUNT 5 /* Number of CLI encapsulation modes */ 65 66 static char *hdr_modes[] = { 67 "Ieee", 68 "Higig", 69 "B5632", 70 "Higig2", 71 "Raw", 72 NULL}; 73 74 typedef struct xd_s { /* TX/RX description */ 75 int xd_unit; /* Unit # */ 76 int xd_tx_unit; /* TX device */ 77 int xd_ppsm; /* true --> per port src macs */ 78 enum { 79 XD_IDLE, /* Not doing anything */ 80 XD_RUNNING, /* Running */ 81 XD_STOP /* Stop requested */ 82 } xd_state; 83 uint32 xd_tot_cnt; /* # to send/receive */ 84 uint32 xd_cur_cnt; /* # sent/received */ 85 int xd_pkt_len; /* Packet length */ 86 char *xd_file; /* File name of packet data */ 87 sal_mac_addr_t xd_mac_dst; /* Destination mac address */ 88 sal_mac_addr_t xd_mac_src; /* Source mac address */ 89 sal_mac_addr_t xd_mac_src_base; /* Source mac address for pps */ 90 /* port source mac */ 91 uint32 xd_mac_dst_inc; /* Destination mac increment */ 92 uint32 xd_mac_src_inc; /* Source mac increment */ 93 uint32 xd_pat; /* XMIT pattern */ 94 uint32 xd_pat_inc; /* Pattern Increment */ 95 int xd_pat_random; /* Use Random Pattern */ 96 pbmp_t xd_ppsm_pbm; /* Saved port bit map for per */ 97 /* port source mac */ 98 uint32 xd_vlan; /* vlan id (0 if untagged) */ 99 uint32 xd_prio; /* vlan prio */ 100 uint32 xd_prio_int; /* Internal priority */ 101 uint32 xd_cong_int; /* Internal congestion */ 102 uint32 xd_crc; 103 104 /* Packet info is now in bcm_pkt_t structure */ 105 bcm_pkt_t pkt_info; 106 107 /* XGS Header Fields. Most are in pkt_info */ 108 int hdr_mode; /* Mode type */ 109 int ether_pkt; /* Use Ethernet packet */ 110 uint32 w0,w1,w2,w3,w4; /* Raw mode words */ 111 uint32 xd_hg_dmod; /* Higig Dest Mod */ 112 uint32 xd_hg_dport; /* Higig Dest Port */ 113 uint32 xd_hg_smod; /* Higig Src Mod */ 114 uint32 xd_hg_sport; /* Higig Src Port */ 115 uint32 xd_hg_opcode; /* Higig Opcode */ 116 uint32 xd_hg_cos; /* Higig Class of Service */ 117 uint32 xd_hg_pfm; /* Higig Port Filtering Mode */ 118 #ifdef BCM_HIGIG2_SUPPORT 119 uint32 xd_hg_mgid; /* Higig2 Multicast Group ID */ 120 uint32 xd_hg_lbid; /* Higig2 Load Balancing ID */ 121 uint32 xd_hg_dp; /* Higig2 Drop Precendece */ 122 #endif /* BCM_HIGIG2_SUPPORT */ 123 uint32 xd_s_portid; /* BCM5632 Source port ID */ 124 uint32 xd_d_portid; /* BCM5632 Destination port ID */ 125 uint32 xd_length; /* BCM5632 Length Field */ 126 uint32 xd_start; /* BCM5632 Start Field */ 127 int xd_untag; /* FB/ER Send Untagged */ 128 int xd_purge; /* FB/ER Send Purge */ 129 char *xd_data; /* packet data */ 130 #if defined(BCM_TRIUMPH3_SUPPORT) 131 int xd_rpl_type; /* replacement type */ 132 int xd_rpl_offset; /* replacement offset */ 133 int xd_lm_ctr_index; /* LM counter Index */ 134 #endif 135 136 #ifdef BCM_INSTRUMENTATION_SUPPORT 137 int xd_vis_options; 138 int xd_vis_sport; 139 #endif /* BCM_INSTRUMENTATION_SUPPORT */ 140 #ifdef BCM_CPU_TX_PROC_SUPPORT 141 int xd_ph_destination_type; /* CPU TX Proc Destination type */ 142 int xd_ph_destination; /* CPU TX Proc Destination */ 143 int xd_ph_destination_port; /* CPU TX Proc Destination Port */ 144 int xd_ph_source_port; /* CPU TX Proc Source Port */ 145 int xd_ph_routed_pkt; /* CPU TX Proc Routed Packet */ 146 int xd_ph_qos_fields_valid; /* CPU TX Proc QoS Fields Valid */ 147 int xd_ph_dp; /* CPU TX Proc Drop Precedence */ 148 int xd_ph_mcast_lb_index_valid; /* CPU TX Proc Mcast LB index valid */ 149 int xd_ph_mcast_lb_index; /* CPU TX Proc Mcast LB index */ 150 int xd_ph_ecmp_group_index; /* CPU TX Proc Group index */ 151 int xd_ph_ecmp_member_index; /* CPU TX Proc Member index */ 152 #endif /* BCM_CPU_TX_PROC_SUPPORT */ 153 int xd_mc_qtype; /*To MC queue(SOBMH) */ 154 int xd_rqe_q_num; /*RQE Queue num(SOBMH) */ 155 int xd_link_down_tx; /* Allow tx to link down port */ 156 } xd_t; 157 158 static xd_t *xd_units[SOC_MAX_NUM_DEVICES]; 159 160 #define _XD_INIT(unit, xd) do { \ 161 if (xd_units[unit] == NULL) \ 162 _xd_init(unit); \ 163 if (xd_units[unit] == NULL) \ 164 return CMD_FAIL; \ 165 xd = xd_units[unit]; } while (0) 166 167 #define XD_FILE(xd) ((xd)->xd_file != NULL && (xd)->xd_file[0] != 0) 168 #define XD_STRING(xd) ((xd)->xd_data != NULL && (xd)->xd_data[0] != 0) 169 170 #define UNTAGGED_PACKET_LENGTH 1024 171 172 #if defined(BCM_HIGIG2_SUPPORT) || defined(BCM_CPU_TX_PROC_SUPPORT) 173 STATIC char *drop_precedence[] = { 174 "Green", "Red", "Invalid", "Yellow", NULL 175 }; 176 #endif /* BCM_HIGIG2_SUPPORT || BCM_CPU_TX_PROC_SUPPORT */ 177 178 #define XD_PRIO_INT_INVALID 0xffffffff 179 #define XD_CONG_INT_INVALID 0xffffffff 180 181 #if defined(BCM_CPU_TX_PROC_SUPPORT) 182 #define XD_DEST_TYPE_INVALID 0xff 183 #endif 184 185 STATIC void 186 _xd_init(int unit) 187 { 188 xd_t *xd; 189 int port; 190 sal_mac_addr_t default_mac_src ={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; 191 sal_mac_addr_t default_mac_dst ={ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 }; 192 bcm_port_config_t pcfg; 193 194 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 195 cli_out("WARNING: bcm ports not initialized\n"); 196 return; 197 } 198 199 xd = xd_units[unit]; 200 if (xd == NULL) { 201 xd = sal_alloc(sizeof(xd_t), "xd"); 202 if (xd == NULL) { 203 cli_out("WARNING: xd memory allocation failed\n"); 204 return; 205 } 206 sal_memset(xd, 0, sizeof(xd_t)); 207 } 208 #ifdef BCM_XGS_SUPPORT 209 if (SOC_IS_SHADOW(unit)) { 210 xd->xd_hg_smod = 0; 211 } else 212 if (bcm_stk_my_modid_get(unit, (int *)&xd->xd_hg_smod) < 0 ) { 213 cli_out("WARNING: getting my_modid failed\n"); 214 if (xd_units[unit] == NULL) { 215 sal_free(xd); 216 } 217 /* coverity[leaked_storage : FALSE] */ 218 return; 219 } 220 xd->xd_hg_dmod = 0; 221 xd->xd_hg_dport = 0; 222 xd->xd_hg_opcode = SOC_HIGIG_OP_CPU; 223 BCM_PBMP_ITER(pcfg.cpu, port) { 224 xd->xd_hg_sport = port; 225 break; 226 } 227 xd->xd_hg_pfm = 0; 228 #endif /* BCM_XGS_SUPPORT */ 229 230 /* get the encapsulation of the first higig port or default to IEEE */ 231 xd->hdr_mode = ENCAP_IEEE; 232 BCM_PBMP_ITER(pcfg.stack_ext, port) { 233 if (bcm_port_encap_get(unit, port, &xd->hdr_mode) < 0) { 234 xd->hdr_mode = ENCAP_IEEE; 235 } 236 break; 237 } 238 239 xd->xd_unit = unit; 240 xd->xd_tx_unit = unit; 241 xd->xd_state = XD_IDLE; 242 xd->xd_file = NULL; 243 xd->xd_data = NULL; 244 xd->xd_pkt_len = 68; 245 xd->xd_pat = 0x12345678; 246 xd->xd_pat_inc = 1; 247 xd->xd_pat_random = 0; 248 BCM_PBMP_ASSIGN(xd->pkt_info.tx_pbmp, pcfg.all); 249 #if defined(BCM_XGS3_SWITCH_SUPPORT) 250 if (SOC_IS_XGS3_SWITCH(xd->xd_unit)) { 251 SOC_PBMP_CLEAR(xd->pkt_info.tx_pbmp); 252 } 253 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 254 BCM_PBMP_ASSIGN(xd->xd_ppsm_pbm, pcfg.all); 255 xd->xd_vlan = 0x1; 256 xd->xd_prio = 0; 257 xd->xd_prio_int = XD_PRIO_INT_INVALID; 258 xd->xd_cong_int = XD_CONG_INT_INVALID; 259 xd->xd_ppsm = 0; 260 261 #if defined(BCM_CPU_TX_PROC_SUPPORT) 262 xd->xd_ph_destination_type = XD_DEST_TYPE_INVALID; 263 #endif 264 265 ENET_SET_MACADDR(xd->xd_mac_dst, default_mac_dst); 266 ENET_SET_MACADDR(xd->xd_mac_src, default_mac_src); 267 xd->xd_crc = 1; /* Re-gen CRC by default */ 268 269 if (xd->pkt_info.pkt_data) { /* Has been setup before */ 270 soc_cm_sfree(unit, xd->pkt_info._pkt_data.data); 271 xd->pkt_info.pkt_data = NULL; 272 } 273 xd->pkt_info.flags = 0; 274 275 if ((xd->pkt_info._pkt_data.data = (uint8 *)soc_cm_salloc(unit, 276 xd->xd_pkt_len, 277 "xd tx")) == NULL) { 278 cli_out("WARNING: xd tx packet memory allocation failed\n"); 279 xd->pkt_info.pkt_data = NULL; 280 xd->pkt_info._pkt_data.len = 0; 281 } else { 282 xd->pkt_info.pkt_data = &xd->pkt_info._pkt_data; 283 xd->pkt_info.blk_count = 1; 284 xd->pkt_info._pkt_data.len = xd->xd_pkt_len; 285 } 286 287 xd_units[unit] = xd; 288 } 289 290 bcm_pkt_t * 291 txrx_pkt_alloc(int unit, int nblocks, int *sizes, int flags) 292 { 293 bcm_pkt_t *pkt; 294 int i, j; 295 296 if (!(pkt = sal_alloc(sizeof(bcm_pkt_t), "txrx pkt"))) { 297 return NULL; 298 } 299 300 pkt->blk_count = nblocks; 301 if (nblocks == 1) { 302 pkt->pkt_data = &pkt->_pkt_data; 303 } else { 304 if (!(pkt->pkt_data = sal_alloc(sizeof(bcm_pkt_blk_t) * nblocks, 305 "tx pdata"))) { 306 sal_free(pkt); 307 return NULL; 308 } 309 } 310 311 for (i = 0; i < nblocks; i++) { 312 pkt->pkt_data[i].len = sizes[i]; 313 if (!(pkt->pkt_data[i].data = soc_cm_salloc(unit, sizes[i], 314 "txrx data"))) { 315 for (j = 0; j < i; j++) { 316 soc_cm_sfree(unit, pkt->pkt_data[j].data); 317 } 318 if (nblocks > 1) { 319 sal_free(pkt->pkt_data); 320 } 321 sal_free(pkt); 322 return NULL; 323 } 324 } 325 326 pkt->unit = unit; 327 pkt->flags = flags; 328 return pkt; 329 } 330 331 void 332 txrx_pkt_free(int unit, bcm_pkt_t *pkt) 333 { 334 int i; 335 336 for (i = 0; i < pkt->blk_count; i++) { 337 soc_cm_sfree(unit, pkt->pkt_data[i].data); 338 } 339 340 if (pkt->pkt_data != &pkt->_pkt_data) { 341 sal_free(pkt->pkt_data); 342 } 343 344 sal_free(pkt); 345 } 346 347 cmd_result_t 348 tx_parse(int u, args_t *a, xd_t *xd) 349 /* 350 * Function: txrx_parse 351 * Purpose: Parse input parameters into a xd structure. 352 * Parameters: u - unit #. 353 * a - pointer to arguments 354 * xd - pointer to xd structure to fill in. 355 * Returns: 0 - success, -1 failed. 356 */ 357 { 358 char *crc_list[] = {"None", "Recompute", "Append", NULL}; 359 parse_table_t pt; 360 int min_len, tagged; 361 362 /* First arg is count */ 363 364 if (!ARG_CNT(a) || !isint(ARG_CUR(a))) { 365 return(CMD_USAGE); 366 } 367 368 _XD_INIT(u, xd); 369 370 xd->xd_tot_cnt = parse_integer(ARG_GET(a)); 371 372 parse_table_init(u, &pt); 373 374 /* Add XGS Ethernet/BCM5632/HIGIG Options */ 375 if (xd->hdr_mode == ENCAP_IEEE) { 376 if (SOC_IS_XGS3_SWITCH(u)) { 377 parse_table_add(&pt, "Untagged", PQ_DFL|PQ_BOOL, 0, 378 &xd->xd_untag, NULL); 379 parse_table_add(&pt, "HGSrcMod", PQ_DFL|PQ_INT, 0, 380 &xd->xd_hg_smod, NULL); 381 } 382 xd->pkt_info.flags &= (~(BCM_TX_HG_READY)); 383 } else if (xd->hdr_mode == ENCAP_HIGIG || 384 xd->hdr_mode == ENCAP_HIGIG2) { 385 if (SOC_IS_XGS_FABRIC(u) || SOC_IS_XGS3_SWITCH(u)) { 386 xd->pkt_info.flags |= (BCM_TX_HG_READY); 387 } 388 parse_table_add(&pt, "HGDestMod", PQ_DFL|PQ_INT, 0, 389 &xd->xd_hg_dmod, NULL); 390 parse_table_add(&pt, "HGDestPort", PQ_DFL|PQ_INT, 0, 391 &xd->xd_hg_dport, NULL); 392 parse_table_add(&pt, "HGOpcode", PQ_DFL|PQ_INT, 0, 393 &xd->xd_hg_opcode, NULL); 394 parse_table_add(&pt, "HGSrcMod", PQ_DFL|PQ_INT, 0, 395 &xd->xd_hg_smod, NULL); 396 parse_table_add(&pt, "HGSrcPort", PQ_DFL|PQ_INT, 0, 397 &xd->xd_hg_sport, NULL); 398 parse_table_add(&pt, "PFM", PQ_DFL|PQ_INT, 0, 399 &xd->xd_hg_pfm, NULL); 400 parse_table_add(&pt, "EthernetPacket", PQ_DFL|PQ_BOOL, 0, 401 &xd->ether_pkt, NULL); 402 #ifdef BCM_HIGIG2_SUPPORT 403 if (xd->hdr_mode == ENCAP_HIGIG2 && 404 soc_feature(u, soc_feature_higig2)) { 405 /* Map traffic class to internal priority */ 406 parse_table_add(&pt, "TrafficClass", PQ_DFL|PQ_INT, 0, 407 &xd->xd_prio_int, NULL); 408 parse_table_add(&pt, "McastGroupID", PQ_DFL|PQ_INT, 0, 409 &xd->xd_hg_mgid, NULL); 410 parse_table_add(&pt, "LoadBalID", PQ_DFL|PQ_INT, 0, 411 &xd->xd_hg_lbid, NULL); 412 parse_table_add(&pt, "DropPrecedence", PQ_DFL|PQ_MULTI, 0, 413 &xd->xd_hg_dp, drop_precedence); 414 } 415 #endif /* BCM_HIGIG2_SUPPORT */ 416 } else if (xd->hdr_mode == ENCAP_B5632) { 417 parse_table_add(&pt, "SourcePortID", PQ_DFL|PQ_INT, 0, 418 &xd->xd_s_portid, NULL); 419 parse_table_add(&pt, "DestPortID", PQ_DFL|PQ_INT, 0, 420 &xd->xd_d_portid, NULL); 421 parse_table_add(&pt, "Start", PQ_DFL|PQ_INT,0, 422 &xd->xd_start, NULL); 423 parse_table_add(&pt, "Length", PQ_DFL|PQ_INT,0, 424 &xd->xd_length, NULL); 425 } else if (xd->hdr_mode == ENCAP_RAW) { 426 parse_table_add(&pt, "Word0", PQ_DFL|PQ_INT,0, 427 &xd->w0, NULL); 428 parse_table_add(&pt, "Word1", PQ_DFL|PQ_INT,0, 429 &xd->w1, NULL); 430 parse_table_add(&pt, "Word2", PQ_DFL|PQ_INT,0, 431 &xd->w2, NULL); 432 433 #if defined(BCM_HIGIG2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 434 if (soc_feature(u, soc_feature_higig2) || SOC_IS_TOMAHAWK3(u)) { 435 parse_table_add(&pt, "Word3", PQ_DFL|PQ_INT,0, 436 &xd->w3, NULL); 437 parse_table_add(&pt, "Word4", PQ_DFL|PQ_INT,0, 438 &xd->w4, NULL); 439 } 440 #endif /* BCM_HIGIG2_SUPPORT */ 441 } 442 443 parse_table_add(&pt, "TXUnit", PQ_DFL|PQ_INT, 0, &xd->xd_tx_unit, NULL); 444 parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 0, 445 &xd->pkt_info.tx_pbmp, NULL); 446 447 #ifdef BCM_INSTRUMENTATION_SUPPORT 448 parse_table_add(&pt, "VisibilityOptions", PQ_DFL|PQ_INT, 0, 449 &xd->xd_vis_options, NULL); 450 parse_table_add(&pt, "VisibilitySourcePort", PQ_DFL|PQ_PORT, 0, 451 &xd->xd_vis_sport, NULL); 452 #endif /* BCM_INSTRUMENTATION_SUPPORT */ 453 454 #ifdef BCM_CPU_TX_PROC_SUPPORT 455 if (soc_feature(u, soc_feature_cpu_tx_proc)) { 456 parse_table_add(&pt, "TxProcMhDestinationType", PQ_DFL|PQ_INT, 0, 457 &xd->xd_ph_destination_type, NULL); 458 parse_table_add(&pt, "TxProcMhSourcePort", PQ_DFL|PQ_PORT, 0, 459 &xd->xd_ph_source_port, NULL); 460 parse_table_add(&pt, "TxProcMhDestinationPort", PQ_DFL|PQ_PORT, 0, 461 &xd->xd_ph_destination_port, NULL); 462 parse_table_add(&pt, "TxProcMhDestination", PQ_DFL|PQ_INT, 0, 463 &xd->xd_ph_destination, NULL); 464 parse_table_add(&pt, "TxProcMhMcastLbIndexValid", PQ_DFL|PQ_BOOL, 0, 465 &xd->xd_ph_mcast_lb_index_valid, NULL); 466 parse_table_add(&pt, "TxProcMhMcastLbIndex", PQ_DFL|PQ_INT, 0, 467 &xd->xd_ph_mcast_lb_index, NULL); 468 parse_table_add(&pt, "TxProcMhQosFieldsValid", PQ_DFL|PQ_BOOL, 0, 469 &xd->xd_ph_qos_fields_valid, NULL); 470 parse_table_add(&pt, "TxProcMhDropPrecedence", PQ_DFL|PQ_MULTI, 0, 471 &xd->xd_ph_dp, drop_precedence); 472 parse_table_add(&pt, "TxProcMhInternalPriority", PQ_DFL|PQ_INT, 0, 473 &xd->xd_prio_int, NULL); 474 parse_table_add(&pt, "TxProcMhInternalCongestion", PQ_DFL|PQ_INT, 0, 475 &xd->xd_cong_int, NULL); 476 parse_table_add(&pt, "TxProcMhRoutedPkt", PQ_DFL|PQ_BOOL, 0, 477 &xd->xd_ph_routed_pkt, NULL); 478 parse_table_add(&pt, "TxProcMhEcmpGroup", PQ_DFL|PQ_INT, 0, 479 &xd->xd_ph_ecmp_group_index, NULL); 480 parse_table_add(&pt, "TxProcMhEcmpMember", PQ_DFL|PQ_INT, 0, 481 &xd->xd_ph_ecmp_member_index, NULL); 482 } 483 #endif /* BCM_CPU_TX_PROC_SUPPORT */ 484 485 if (!SOC_IS_XGS_FABRIC(u)) { 486 parse_table_add(&pt, "UntagBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 0, 487 &xd->pkt_info.tx_upbmp, NULL); 488 } 489 490 if (!SOC_IS_XGS3_SWITCH(u)) { 491 if (SOC_IS_XGS_SWITCH(u)) { 492 parse_table_add(&pt, "L3BitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 0, 493 &xd->pkt_info.tx_l3pbmp, NULL); 494 } 495 } 496 497 parse_table_add(&pt, "DATA", PQ_DFL|PQ_STRING,0, 498 &xd->xd_data, NULL); 499 parse_table_add(&pt, "Filename", PQ_DFL|PQ_STRING,0, 500 &xd->xd_file, NULL); 501 parse_table_add(&pt, "Length", PQ_DFL|PQ_INT, 0, 502 &xd->xd_pkt_len, NULL); 503 parse_table_add(&pt, "VLantag", PQ_DFL|PQ_HEX, 0, 504 &xd->xd_vlan, NULL); 505 parse_table_add(&pt, "VlanPrio", PQ_DFL|PQ_INT, 0, 506 &xd->xd_prio, NULL); 507 parse_table_add(&pt, "PrioInt", PQ_DFL|PQ_INT, 0, 508 &xd->xd_prio_int, NULL); 509 parse_table_add(&pt, "Pattern", PQ_DFL|PQ_HEX, 0, 510 &xd->xd_pat, NULL); 511 parse_table_add(&pt, "PatternInc", PQ_DFL|PQ_INT, 0, 512 &xd->xd_pat_inc, NULL); 513 parse_table_add(&pt, "PatternRandom", PQ_DFL|PQ_BOOL, 0, 514 &xd->xd_pat_random, NULL); 515 parse_table_add(&pt, "PerPortSrcMac",PQ_DFL|PQ_INT, 0, 516 &xd->xd_ppsm, NULL); 517 parse_table_add(&pt, "SourceMac", PQ_DFL|PQ_MAC, 0, 518 &xd->xd_mac_src, NULL); 519 parse_table_add(&pt, "SourceMacInc",PQ_DFL|PQ_INT, 0, 520 &xd->xd_mac_src_inc,NULL); 521 parse_table_add(&pt, "DestMac", PQ_DFL|PQ_MAC, 0, 522 &xd->xd_mac_dst, NULL); 523 parse_table_add(&pt, "DestMacInc", PQ_DFL|PQ_INT, 0, 524 &xd->xd_mac_dst_inc,NULL); 525 parse_table_add(&pt, "LinkDownTX", PQ_DFL|PQ_INT, 0, 526 &xd->xd_link_down_tx, NULL); 527 #if defined(BCM_XGS3_SWITCH_SUPPORT) 528 if (SOC_IS_XGS3_SWITCH(u)) { 529 parse_table_add(&pt, "PurGe", PQ_DFL|PQ_BOOL, 0, 530 &xd->xd_purge, NULL); 531 parse_table_add(&pt, "McQType", PQ_DFL|PQ_BOOL, 0, 532 &xd->xd_mc_qtype, NULL); 533 } 534 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 535 parse_table_add(&pt, "COSqueue", PQ_DFL|PQ_INT, 0, 536 &xd->xd_hg_cos, NULL); 537 parse_table_add(&pt, "CRC", PQ_DFL|PQ_MULTI,0, 538 &xd->xd_crc, crc_list); 539 parse_table_add(&pt, "RQEnum", PQ_DFL|PQ_INT, 0, 540 &xd->xd_rqe_q_num, NULL); 541 #if defined(BCM_TRIUMPH3_SUPPORT) 542 parse_table_add(&pt, "RplType", PQ_DFL|PQ_INT, 0, 543 &xd->xd_rpl_type, NULL); 544 parse_table_add(&pt, "RplOffset", PQ_DFL|PQ_INT, 0, 545 &xd->xd_rpl_offset, NULL); 546 parse_table_add(&pt, "LmCtrIdx", PQ_DFL|PQ_INT, 0, 547 &xd->xd_lm_ctr_index, NULL); 548 #endif /* BCM_TRIUMPH3_SUPPORT */ 549 550 if (SOC_IS_XGS_FABRIC(u)) { 551 SOC_PBMP_PORT_REMOVE(xd->pkt_info.tx_pbmp, CMIC_PORT(u)); 552 } 553 554 /* Parse remaining arguments */ 555 if (0 > parse_arg_eq(a, &pt)) { 556 cli_out("%s: Error: Invalid option or malformed expression: %s\n", 557 ARG_CMD(a), ARG_CUR(a)); 558 parse_arg_eq_done(&pt); 559 return(CMD_FAIL); 560 } 561 { 562 char *xfile = NULL, *xdata = NULL; 563 if (xd->xd_file) { 564 xfile = sal_strdup(xd->xd_file); 565 } 566 if (xd->xd_data) { 567 xdata = sal_strdup(xd->xd_data); 568 } 569 parse_arg_eq_done(&pt); 570 xd->xd_file = xfile; 571 xd->xd_data = xdata; 572 } 573 574 if (SOC_IS_XGS12_FABRIC(u)) { 575 tagged = TRUE; 576 min_len = ((xd->hdr_mode == ENCAP_HIGIG) ? 60 : 64); 577 if (xd->hdr_mode == ENCAP_HIGIG) { 578 BCM_PKT_HGHDR_REQUIRE(&xd->pkt_info); 579 } 580 } else { 581 tagged = (xd->xd_vlan != 0); 582 min_len = (tagged ? 68 : 64); 583 } 584 585 #if defined(BCM_XGS3_SWITCH_SUPPORT) 586 if (SOC_IS_XGS3_SWITCH(u)) { 587 if (SOC_PBMP_IS_NULL(xd->pkt_info.tx_pbmp)) { 588 xd->pkt_info.flags |= (BCM_TX_ETHER); /* Mapped mode */ 589 if (xd->ether_pkt) { 590 xd->pkt_info.flags &= (~BCM_TX_HG_READY); 591 } 592 } else { 593 xd->pkt_info.flags &= (~BCM_TX_ETHER); /* Raw mode */ 594 } 595 596 if (xd->hdr_mode == ENCAP_RAW) { 597 if (xd->w0 != 0) { 598 xd->pkt_info.flags |= (BCM_TX_HG_READY); 599 } else { 600 xd->pkt_info.flags &= (~BCM_TX_HG_READY); 601 } 602 } 603 } 604 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 605 606 if (!XD_FILE(xd) && !XD_STRING(xd) && !tagged) { 607 cli_out("%s: Warning: Sending untagged packets from CPU " 608 "not recommended\n", 609 ARG_CMD(a)); 610 } 611 612 if (!XD_FILE(xd) && !XD_STRING(xd) && xd->xd_pkt_len < min_len) { 613 cli_out("%s: Warning: Length %d too small for %s packet (min %d)\n", 614 ARG_CMD(a), 615 xd->xd_pkt_len, 616 tagged ? "tagged" : "untagged", 617 min_len); 618 } 619 620 if (xd->xd_hg_cos > NUM_COS(xd->xd_unit)-1 && 621 xd->xd_hg_cos != 14 && xd->xd_hg_cos != 15 && 622 !SOC_IS_TR_VL(xd->xd_unit)) { 623 cli_out("%s: Error: Invalid COS queue %d, must be < %d\n", ARG_CMD(a), 624 xd->xd_hg_cos, NUM_COS(xd->xd_unit)); 625 return(CMD_FAIL); 626 } 627 628 if (xd->xd_untag) { 629 xd->xd_vlan = 0; 630 } 631 632 return CMD_OK; 633 } 634 635 /* 636 * Function: _tx_first_pbm(pbmp_t pbm) 637 * Purpose: Get the first port in a bitmap. 638 * Parameters: pbm -- the port bitmap 639 * rpbm -- (OUT) port bitmap with only one port set. 640 */ 641 STATIC void 642 _tx_first_pbm(int unit, bcm_pbmp_t pbm, bcm_pbmp_t *rpbm) 643 { 644 soc_port_t p, dport; 645 646 COMPILER_REFERENCE(unit); 647 648 BCM_PBMP_CLEAR(*rpbm); 649 /* coverity[overrun-local] */ 650 DPORT_BCM_PBMP_ITER(unit, pbm, dport, p) { 651 LOG_INFO(BSL_LS_APPL_TX, 652 (BSL_META_U(unit, 653 "First to port %d\n"), p)); 654 /* coverity[overrun-local] */ 655 BCM_PBMP_PORT_ADD(*rpbm, p); 656 return; 657 } 658 659 LOG_INFO(BSL_LS_APPL_TX, 660 (BSL_META_U(unit, 661 "Warning: first pbm null\n"))); 662 } 663 664 /* 665 * Function: int _tx_next_port(pbmp_t *newpbm, pbmp_t allpbm) 666 * Purpose: Get the first port in a bitmap. 667 * Parameters: *newpbm -- the current port bitmap (one port) 668 * set to next port 669 * allpbm -- all ports being iterated over. 670 * Returns: 0 if okay. 1 if reset to first port in allpbm 671 */ 672 STATIC int 673 _tx_next_port(int unit, bcm_pbmp_t *newpbm, bcm_pbmp_t allpbm) 674 { 675 soc_port_t p, dport; 676 soc_port_t np, ndport; 677 int found = FALSE; 678 char pfmt[SOC_PBMP_FMT_LEN]; 679 680 /* coverity[overrun-local] */ 681 DPORT_BCM_PBMP_ITER(unit, *newpbm, ndport, np) { 682 /* coverity[overrun-local] */ 683 DPORT_BCM_PBMP_ITER(unit, allpbm, dport, p) { 684 if (found) { 685 LOG_INFO(BSL_LS_APPL_TX, 686 (BSL_META_U(unit, 687 "Next to port %d\n"), p)); 688 BCM_PBMP_CLEAR(*newpbm); 689 BCM_PBMP_PORT_ADD(*newpbm, p); 690 return 0; 691 } 692 if (np == p) found = TRUE; 693 } 694 } 695 696 /* If we get here, must be resetting. */ 697 _tx_first_pbm(unit, allpbm, newpbm); 698 LOG_INFO(BSL_LS_APPL_TX, 699 (BSL_META_U(unit, 700 "Resetting to pbm %s\n"), SOC_PBMP_FMT(*newpbm, pfmt))); 701 return 1; 702 } 703 704 #define TX_LOAD_MAX 4096 705 706 #ifndef NO_FILEIO 707 708 /* Discard the rest of the line */ 709 STATIC int 710 _discard_line(FILE *fp) 711 { 712 int c; 713 do { 714 if ((c = sal_fgetc(fp)) == EOF) { 715 return c; 716 } 717 } while (c != '\n'); 718 return c; 719 } 720 721 STATIC int 722 tx_load_byte(FILE *fp, uint8 *byte) 723 { 724 int c, d; 725 726 do { 727 if ((c = sal_fgetc(fp)) == EOF) { 728 return -1; 729 } 730 else if (c == '#') { 731 if((c = _discard_line(fp)) == EOF) { 732 return -1; 733 } 734 } 735 } while (!isxdigit(c)); 736 737 do { 738 if ((d = sal_fgetc(fp)) == EOF) { 739 return -1; 740 } 741 else if (d == '#') { 742 if((d = _discard_line(fp)) == EOF) { 743 return -1; 744 } 745 } 746 } while (!isxdigit(d)); 747 748 *byte = (xdigit2i(c) << 4) | xdigit2i(d); 749 750 return 0; 751 } 752 753 STATIC uint8 * 754 tx_load_packet(int unit, char *fname, int *length) 755 { 756 uint8 *p; 757 FILE *fp; 758 int i; 759 760 if ((p = soc_cm_salloc(unit, TX_LOAD_MAX, "tx_packet")) == NULL) 761 return p; 762 763 if ((fp = sal_fopen(fname, "r")) == NULL) { 764 soc_cm_sfree(unit, p); 765 return NULL; 766 } 767 768 for (i = 0; i < TX_LOAD_MAX; i++) { 769 if (tx_load_byte(fp, &p[i]) < 0) 770 break; 771 } 772 773 *length = i; 774 775 sal_fclose(fp); 776 777 return p; 778 } 779 #endif /* NO_FILEIO */ 780 781 /* If data was read from file, extract to XD structure */ 782 STATIC void 783 check_pkt_fields(xd_t *xd) 784 { 785 enet_hdr_t *ep; /* Ethernet packet header */ 786 bcm_pkt_t *pkt_info = &xd->pkt_info; 787 788 ep = (enet_hdr_t *)BCM_PKT_IEEE(pkt_info); 789 790 if (XD_FILE(xd) || XD_STRING(xd)) { /* Loaded from file or string */ 791 /* Also set parameters to file data so incrementing works */ 792 793 ENET_COPY_MACADDR(&ep->en_dhost, xd->xd_mac_dst); 794 ENET_COPY_MACADDR(&ep->en_shost, xd->xd_mac_src); 795 796 if (!ENET_TAGGED(ep)) { 797 cli_out("Warning: Untagged packet read from file for tx.\n"); 798 xd->xd_vlan = VLAN_ID_NONE; 799 } else { 800 xd->xd_vlan = VLAN_CTRL_ID(bcm_ntohs(ep->en_tag_ctrl)); 801 xd->xd_prio = VLAN_CTRL_PRIO(bcm_ntohs(ep->en_tag_ctrl)); 802 } 803 } else { 804 if (xd->xd_vlan) { /* Tagged format */ 805 ep->en_tag_ctrl = bcm_htons(VLAN_CTRL(xd->xd_prio, 0, xd->xd_vlan)); 806 ep->en_tag_len = bcm_htons(xd->xd_pkt_len - ENET_TAGGED_HDR_LEN - ENET_CHECKSUM_LEN); 807 ep->en_tag_tpid = bcm_htons(0x8100); 808 } else { /* Untagged format */ 809 cli_out("Warning: Sending untagged packet.\n"); 810 ep->en_untagged_len = bcm_htons(xd->xd_pkt_len - ENET_UNTAGGED_HDR_LEN - ENET_CHECKSUM_LEN); 811 } 812 ENET_SET_MACADDR(ep->en_dhost, xd->xd_mac_dst); 813 ENET_SET_MACADDR(ep->en_shost, xd->xd_mac_src); 814 } 815 } 816 817 #ifdef BCM_XGS_SUPPORT 818 STATIC int 819 _tx_hghdr_setup(bcm_pkt_t *pkt, int sop) 820 { 821 soc_higig_hdr_t *xgh = (soc_higig_hdr_t *)pkt->_higig; 822 int unit = pkt->unit; 823 uint32 vlan_val; 824 825 sal_memset(xgh, 0, sizeof(pkt->_higig)); 826 soc_higig_field_set(unit, xgh, HG_start, sop); 827 soc_higig_field_set(unit, xgh, HG_hgi, SOC_HIGIG_HGI); 828 soc_higig_field_set(unit, xgh, HG_opcode, pkt->opcode); 829 soc_higig_field_set(unit, xgh, HG_hdr_format, 830 SOC_HIGIG_HDR_DEFAULT); 831 832 vlan_val = BCM_PKT_VLAN_CONTROL(pkt); 833 soc_higig_field_set(unit, xgh, HG_vlan_tag, vlan_val); 834 soc_higig_field_set(unit, xgh, HG_dst_mod, pkt->dest_mod); 835 soc_higig_field_set(unit, xgh, HG_dst_port, pkt->dest_port); 836 soc_higig_field_set(unit, xgh, HG_src_mod, pkt->src_mod); 837 soc_higig_field_set(unit, xgh, HG_src_port, pkt->src_port); 838 soc_higig_field_set(unit, xgh, HG_pfm, pkt->pfm); 839 soc_higig_field_set(unit, xgh, HG_cos, pkt->prio_int); 840 841 return BCM_E_NONE; 842 } 843 844 #if defined(BCM_HIGIG2_SUPPORT) 845 846 STATIC int 847 _tx_hg2hdr_setup(bcm_pkt_t *pkt, int sop, 848 uint32 xd_hg_mgid, /* Higig2 Multicast Group ID */ 849 uint32 xd_hg_lbid, /* Higig2 Load Balancing ID */ 850 uint32 xd_hg_dp /* Higig2 Drop Precendece */ 851 ) 852 { 853 soc_higig2_hdr_t *xgh = (soc_higig2_hdr_t *)pkt->_higig; 854 int unit = pkt->unit, multicast = 0, mc_index_offset = 0, mc_index = 0; 855 uint32 vlan_val; 856 #if defined(BCM_BRADLEY_SUPPORT) 857 int bcast_size, mcast_size, ipmc_size; 858 #endif 859 860 sal_memset(xgh, 0, sizeof(pkt->_higig)); 861 soc_higig2_field_set(unit, xgh, HG_start, sop); 862 soc_higig2_field_set(unit, xgh, HG_hgi, SOC_HIGIG_HGI); 863 soc_higig2_field_set(unit, xgh, HG_opcode, pkt->opcode); 864 soc_higig2_field_set(unit, xgh, HG_hdr_format, 865 SOC_HIGIG_HDR_DEFAULT); 866 867 vlan_val = BCM_PKT_VLAN_CONTROL(pkt); 868 soc_higig2_field_set(unit, xgh, HG_vlan_tag, vlan_val); 869 soc_higig2_field_set(unit, xgh, HG_dst_mod, pkt->dest_mod); 870 soc_higig2_field_set(unit, xgh, HG_dst_port, pkt->dest_port); 871 soc_higig2_field_set(unit, xgh, HG_src_mod, pkt->src_mod); 872 soc_higig2_field_set(unit, xgh, HG_src_port, pkt->src_port); 873 soc_higig2_field_set(unit, xgh, HG_pfm, pkt->pfm); 874 soc_higig2_field_set(unit, xgh, HG_cos, pkt->prio_int); 875 876 multicast = ((pkt->opcode == SOC_HIGIG_OP_CPU) || 877 (pkt->opcode == SOC_HIGIG_OP_UC)) ? 0 : pkt->opcode; 878 if (multicast) { 879 soc_higig2_field_set(unit, xgh, HG_mcst, 1); 880 881 882 mc_index_offset = 0; 883 884 #if defined(BCM_BRADLEY_SUPPORT) 885 /* Higig2 has different ranges for different multicast types */ 886 BCM_IF_ERROR_RETURN 887 (soc_hbx_higig2_mcast_sizes_get(unit, &bcast_size, &mcast_size, 888 &ipmc_size)); 889 switch (multicast) { 890 case SOC_HIGIG_OP_IPMC: 891 mc_index_offset += mcast_size; 892 /* Fall thru */ 893 case SOC_HIGIG_OP_MC: 894 mc_index_offset += bcast_size; 895 /* Fall thru */ 896 case SOC_HIGIG_OP_BC: 897 break; 898 default: 899 /* Unknown opcode */ 900 return BCM_E_PARAM; 901 } 902 #endif 903 mc_index = _BCM_MULTICAST_ID_GET(xd_hg_mgid); 904 soc_higig2_field_set(unit, xgh, HG_mgid, 905 mc_index + mc_index_offset); 906 907 } 908 909 soc_higig2_field_set(unit, xgh, HG_lbid, xd_hg_lbid); 910 soc_higig2_field_set(unit, xgh, HG_dp, xd_hg_dp); 911 912 return BCM_E_NONE; 913 } 914 #endif /* BCM_HIGIG2_SUPPORT */ 915 916 STATIC void 917 add_higig_hdr(xd_t *xd, bcm_pkt_t *pkt_info) 918 { 919 soc_bcm5632_hdr_t *b5632h; /* BCM5632 header */ 920 uint32 temp_raw; 921 uint8 *ptr; 922 uint8 *ext_ptr; 923 924 switch(xd->hdr_mode) { 925 case ENCAP_HIGIG: /* HiGig header */ 926 _tx_hghdr_setup(pkt_info, SOC_HIGIG_START); 927 break; 928 929 #ifdef BCM_HIGIG2_SUPPORT 930 case ENCAP_HIGIG2: /* HiGig2 header */ 931 if (xd->hdr_mode == ENCAP_HIGIG2 && 932 soc_feature(xd->xd_unit, soc_feature_higig2)) { 933 _tx_hg2hdr_setup(pkt_info, SOC_HIGIG2_START, 934 xd->xd_hg_mgid, 935 xd->xd_hg_lbid, 936 xd->xd_hg_dp); 937 } else { 938 cli_out("Warning: Higig2 not supported by device\n"); 939 } 940 break; 941 #endif /* BCM_HIGIG2_SUPPORT */ 942 943 case ENCAP_B5632: /* 5632 header */ 944 b5632h = (soc_bcm5632_hdr_t*)BCM_PKT_HG_HDR(pkt_info); 945 946 sal_memset(b5632h, 0, sizeof (soc_bcm5632_hdr_t)); 947 b5632h->overlay1.s_portid = xd->xd_s_portid; 948 b5632h->overlay1.d_portid = xd->xd_d_portid; 949 b5632h->overlay1.start = xd->xd_start; 950 b5632h->overlay1.length_hi = xd->xd_length >> 8; 951 b5632h->overlay1.length_lo = xd->xd_length & 0xff; 952 break; 953 954 case ENCAP_RAW: /* Raw HIGIG */ 955 ptr = (uint8 *)BCM_PKT_HG_HDR(pkt_info); 956 ext_ptr = (uint8 *)BCM_PKT_EXT_HG_HDR(pkt_info); 957 958 /* Convert to network byte order */ 959 temp_raw = soc_htonl(xd->w0); 960 sal_memcpy(ptr, (void*)&temp_raw, sizeof(uint32)); 961 temp_raw = soc_htonl(xd->w1); 962 sal_memcpy(ptr+4, (void*)&temp_raw, sizeof(uint32)); 963 temp_raw = soc_htonl(xd->w2); 964 sal_memcpy(ptr+8, (void*)&temp_raw, sizeof(uint32)); 965 #ifdef BCM_HIGIG2_SUPPORT 966 if (soc_feature(xd->xd_unit, soc_feature_higig2)) { 967 temp_raw = soc_htonl(xd->w3); 968 sal_memcpy(ptr+12, (void*)&temp_raw, sizeof(uint32)); 969 temp_raw = soc_htonl(xd->w4); 970 sal_memcpy(ext_ptr, (void*)&temp_raw, sizeof(uint32)); 971 } 972 #endif /* BCM_HIGIG2_SUPPORT */ 973 break; 974 975 default: /* Error */ 976 cli_out("Warning: Unknown HG header format: %d\n", xd->hdr_mode); 977 break; 978 } 979 } 980 981 /* Set up the XGS information needed for the DCB */ 982 STATIC void 983 add_xgs_info(xd_t *xd, bcm_pkt_t *pkt) 984 { 985 pkt->dest_mod = xd->xd_hg_dmod; 986 pkt->dest_port = xd->xd_hg_dport; 987 pkt->src_mod = xd->xd_hg_smod; 988 pkt->src_port = xd->xd_hg_sport; 989 pkt->flags &= ~(BCM_TX_SRC_MOD | BCM_TX_SRC_PORT); 990 if (xd->xd_link_down_tx) { 991 pkt->flags |= BCM_TX_LINKDOWN_TRANSMIT; 992 } else { 993 pkt->flags &= ~BCM_TX_LINKDOWN_TRANSMIT; 994 } 995 if (!xd->ether_pkt) { 996 pkt->flags |= BCM_TX_SRC_PORT; 997 pkt->flags |= BCM_TX_SRC_MOD; 998 } 999 pkt->opcode = xd->xd_hg_opcode; 1000 pkt->cos = xd->xd_hg_cos; 1001 pkt->rqe_q_num = xd->xd_rqe_q_num; 1002 pkt->flags &= ~BCM_TX_PRIO_INT; 1003 if (xd->xd_prio_int != XD_PRIO_INT_INVALID) { 1004 pkt->prio_int = xd->xd_prio_int; 1005 pkt->flags |= BCM_TX_PRIO_INT; 1006 } else { 1007 /* For now, internal priority matches COS (or v.v.) */ 1008 pkt->prio_int = xd->xd_hg_cos; 1009 } 1010 pkt->pfm = xd->xd_hg_pfm; 1011 } 1012 1013 /* 1014 * Function: 1015 * setup_higig_tx 1016 * Purpose: 1017 * Setup the hercules packet for tx 1018 * Parameters: 1019 * xd - transmit descriptor 1020 * pkt_data - Raw data to transmit 1021 * Returns: 1022 * BCM_E_XXX 1023 * Notes: 1024 */ 1025 1026 STATIC void 1027 setup_higig_tx(xd_t *xd) 1028 { 1029 bcm_pkt_t *pkt_info = &xd->pkt_info; 1030 1031 pkt_info->unit = xd->xd_unit; 1032 /* Use raw higig header from pkt_info structure */ 1033 if (BCM_PKT_TX_HG_READY(pkt_info)) { 1034 add_xgs_info(xd, pkt_info); 1035 add_higig_hdr(xd, pkt_info); 1036 } else if (SOC_IS_XGS_SWITCH(xd->xd_unit)) { /* Set HG info members */ 1037 add_xgs_info(xd, pkt_info); 1038 if (SOC_IS_XGS3_SWITCH(xd->xd_unit)) { 1039 /* Ethernet mode TX. Remove TX properties */ 1040 pkt_info->flags &= (~(BCM_TX_PKT_PROP_ANY)); 1041 1042 } 1043 } else { 1044 /* Always get cos from higig info structure */ 1045 pkt_info->cos = xd->xd_hg_cos; 1046 } 1047 } 1048 1049 #ifdef BCM_CPU_TX_PROC_SUPPORT 1050 /* 1051 * Function: 1052 * setup_cpu_tx_proc 1053 * Purpose: 1054 * Setup packet for cpu tx proc 1055 * Parameters: 1056 * xd - transmit descriptor 1057 * Returns: 1058 * BCM_E_XXX 1059 * Notes: 1060 */ 1061 STATIC void 1062 setup_cpu_tx_proc(xd_t *xd) 1063 { 1064 bcm_pkt_t *pkt_info = &xd->pkt_info; 1065 1066 pkt_info->unit = xd->xd_unit; 1067 1068 if (xd->xd_ph_destination_type <= SOC_TX_PROC_OP_VLAN_FLOOD) { 1069 xd->pkt_info.flags2 |= BCM_PKT_F2_CPU_TX_PROC; 1070 xd->pkt_info.flags &= (~BCM_TX_ETHER); 1071 pkt_info->txprocmh_destination_type = xd->xd_ph_destination_type; 1072 pkt_info->rx_port = xd->xd_ph_source_port; 1073 } 1074 1075 if (xd->xd_ph_qos_fields_valid) { 1076 pkt_info->txprocmh_qos_fields_valid = xd->xd_ph_qos_fields_valid; 1077 pkt_info->color = xd->xd_ph_dp; 1078 pkt_info->flags &= ~BCM_TX_PRIO_INT; 1079 if (xd->xd_prio_int != XD_PRIO_INT_INVALID) { 1080 pkt_info->prio_int = xd->xd_prio_int; 1081 pkt_info->flags |= BCM_TX_PRIO_INT; 1082 } 1083 1084 pkt_info->flags2 &= ~BCM_PKT_F2_CONG_INT; 1085 if (xd->xd_cong_int != XD_CONG_INT_INVALID) { 1086 pkt_info->txprocmh_congestion_int = xd->xd_cong_int; 1087 pkt_info->flags2 |= BCM_PKT_F2_CONG_INT; 1088 } 1089 } 1090 1091 if (xd->xd_ph_destination_type == SOC_TX_PROC_OP_DGPP) { 1092 pkt_info->txprocmh_destination = xd->xd_ph_destination_port; 1093 } else { 1094 pkt_info->txprocmh_destination = xd->xd_ph_destination; 1095 } 1096 1097 if ((xd->xd_ph_destination_type == SOC_TX_PROC_OP_ECMP_MEMBER) || 1098 (xd->xd_ph_destination_type == SOC_TX_PROC_OP_ECMP)) { 1099 pkt_info->txprocmh_ecmp_group_index = xd->xd_ph_ecmp_group_index; 1100 } 1101 1102 if (xd->xd_ph_destination_type == SOC_TX_PROC_OP_ECMP_MEMBER) { 1103 pkt_info->txprocmh_ecmp_member_index = xd->xd_ph_ecmp_member_index; 1104 } 1105 1106 if (xd->xd_ph_routed_pkt) { 1107 pkt_info->flags |= BCM_PKT_F_ROUTED; 1108 } 1109 1110 if (xd->xd_ph_mcast_lb_index_valid) { 1111 pkt_info->txprocmh_mcast_lb_index_valid = xd->xd_ph_mcast_lb_index_valid; 1112 pkt_info->txprocmh_mcast_lb_index = xd->xd_ph_mcast_lb_index; 1113 } 1114 } 1115 #endif /* BCM_CPU_TX_PROC_SUPPORT */ 1116 1117 #endif /* BCM_XGS_SUPPORT */ 1118 1119 /* parsing string given by user as packet payload */ 1120 STATIC uint8 * 1121 parse_data_packet_payload(int unit, char *packet_data, int *length) 1122 { 1123 uint8 *p; 1124 char tmp, data_iter; 1125 int data_len, i, j, pkt_len, data_base; 1126 1127 /* If string data starts with 0x or 0X, skip it */ 1128 if ((packet_data[0] == '0') 1129 && (packet_data[1] == 'x' || packet_data[1] == 'X')) { 1130 data_base = 2; 1131 } else { 1132 data_base = 0; 1133 } 1134 1135 data_len = strlen(packet_data) - data_base; 1136 pkt_len = (data_len + 1) / 2; 1137 if (pkt_len < UNTAGGED_PACKET_LENGTH) { 1138 pkt_len = UNTAGGED_PACKET_LENGTH; 1139 } 1140 1141 p = soc_cm_salloc(unit, pkt_len, "tx_string_packet"); 1142 if (p == NULL) { 1143 return p; 1144 } 1145 sal_memset(p, 0, pkt_len); 1146 /* Convert char to value */ 1147 i = j = 0; 1148 while (j < data_len) { 1149 data_iter = packet_data[data_base + j]; 1150 if (('0' <= data_iter) && (data_iter <= '9')) { 1151 tmp = data_iter - '0'; 1152 } else if (('a' <= data_iter) && (data_iter <= 'f')) { 1153 tmp = data_iter - 'a' + 10; 1154 } else if (('A' <= data_iter) && (data_iter <= 'F')) { 1155 tmp = data_iter - 'A' + 10; 1156 } else if (data_iter == ' ') { 1157 ++j; 1158 continue; 1159 } else { 1160 soc_cm_sfree(unit, p); 1161 return NULL; 1162 } 1163 1164 /* String input is in 4b unit. Below we're filling in 8b: 1165 offset is /2, and we shift by 4b if the input char is odd */ 1166 p[i / 2] |= tmp << (((i + 1) % 2) * 4); 1167 ++i; 1168 ++j; 1169 } 1170 1171 *length = i / 2 + 4; /* pad for crc */ 1172 return p; 1173 } 1174 1175 STATIC cmd_result_t 1176 do_tx(xd_t *xd) 1177 /* 1178 * Function: do_tx 1179 * Purpose: Perform actual work for a TX operation. 1180 * Parameters: xd - pointer to XD structure already filled in. 1181 * Returns: CMD_xxx 1182 */ 1183 { 1184 uint8 *pkt_data; /* Packet */ 1185 uint8 *payload; /* data - packet payload */ 1186 enet_hdr_t *ep; /* Ethernet packet header */ 1187 bcm_pkt_t *pkt_info = &xd->pkt_info; 1188 int rv = BCM_E_INTERNAL; 1189 int payload_len; 1190 1191 pkt_data = NULL; 1192 1193 /* Allocate the packet; use tx_load if reading from file */ 1194 if (XD_FILE(xd)) { 1195 #ifdef NO_FILEIO 1196 cli_out("no filesystem\n"); 1197 return CMD_FAIL; 1198 #else 1199 if ((pkt_data = tx_load_packet(xd->xd_unit, 1200 xd->xd_file, &xd->xd_pkt_len)) == NULL) { 1201 cli_out("Unable to load packet from file %s\n", xd->xd_file); 1202 return CMD_FAIL; 1203 } 1204 cli_out("Packet from file: %s, length=%d\n", xd->xd_file, xd->xd_pkt_len); 1205 #endif 1206 } else if (XD_STRING(xd)) { 1207 /* use parse_data_packet_payload if reading from user string input */ 1208 pkt_data = parse_data_packet_payload(xd->xd_unit, 1209 xd->xd_data, &xd->xd_pkt_len); 1210 if (pkt_data == NULL) { 1211 cli_out("Unable to allocate memory or Invalid inputs %s\n", xd->xd_data); 1212 return CMD_FAIL; 1213 } 1214 cli_out("Packet from data=<>, length=%d\n", xd->xd_pkt_len); 1215 } 1216 1217 /* Make sure packet allocation size is right size */ 1218 if (pkt_info->pkt_data[0].len != xd->xd_pkt_len) { 1219 soc_cm_sfree(xd->xd_unit, pkt_info->pkt_data[0].data); 1220 if ((pkt_info->pkt_data[0].data = (uint8 *) 1221 soc_cm_salloc(xd->xd_unit, xd->xd_pkt_len, "TX")) == NULL) { 1222 if (pkt_data) { /* free packet buffer */ 1223 soc_cm_sfree(xd->xd_unit, pkt_data); 1224 } 1225 cli_out("Unable to allocate packet memory\n"); 1226 return(CMD_FAIL); 1227 } 1228 pkt_info->pkt_data[0].len = xd->xd_pkt_len; 1229 } 1230 1231 sal_memset(pkt_info->pkt_data[0].data, 0, pkt_info->pkt_data[0].len); 1232 if (pkt_data) { /* Data was read from file. Copy into pkt_info */ 1233 sal_memcpy(pkt_info->pkt_data[0].data, pkt_data, xd->xd_pkt_len); 1234 soc_cm_sfree(xd->xd_unit, pkt_data); 1235 } 1236 1237 /* Setup the packet */ 1238 pkt_info->flags &= ~BCM_TX_CRC_FLD; 1239 pkt_info->flags |= (xd->xd_crc==1 ? BCM_TX_CRC_REGEN : 0) | 1240 (xd->xd_crc==2 ? BCM_TX_CRC_APPEND: 0); 1241 1242 pkt_info->flags &= ~BCM_TX_NO_PAD; 1243 if (xd->xd_pkt_len < (xd->xd_vlan != 0 ? 68 : 64)) { 1244 pkt_info->flags |= BCM_TX_NO_PAD; 1245 } 1246 #if defined(BCM_XGS3_SWITCH_SUPPORT) 1247 pkt_info->flags &= (~(BCM_TX_PURGE)); 1248 if (xd->xd_purge) { 1249 pkt_info->flags |= BCM_TX_PURGE; 1250 } 1251 1252 pkt_info->flags2 &= ~BCM_PKT_F2_MC_QUEUE; 1253 if (xd->xd_mc_qtype) { 1254 pkt_info->flags2 |= BCM_PKT_F2_MC_QUEUE; 1255 } 1256 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 1257 1258 check_pkt_fields(xd); 1259 1260 #ifdef BCM_XGS_SUPPORT 1261 /* Setup special headers and DMA data */ 1262 setup_higig_tx(xd); 1263 #endif /* BCM_XGS_SUPPORT */ 1264 1265 #ifdef BCM_CPU_TX_PROC_SUPPORT 1266 if (soc_feature(xd->xd_unit, soc_feature_cpu_tx_proc)) { 1267 setup_cpu_tx_proc(xd); 1268 } 1269 #endif /* BCM_CPU_TX_PROC_SUPPORT */ 1270 1271 ep = (enet_hdr_t *)(pkt_info->pkt_data[0].data); 1272 1273 payload = &pkt_info->pkt_data[0].data[sizeof(enet_hdr_t)]; 1274 payload_len = pkt_info->pkt_data[0].len - sizeof(enet_hdr_t) - 1275 sizeof(uint32) /* CRC */; 1276 1277 if (xd->xd_ppsm) { /* save base info. setup first port. */ 1278 LOG_INFO(BSL_LS_APPL_TX, 1279 (BSL_META_U(xd->xd_unit, 1280 "Per port source is active\n"))); 1281 xd->xd_ppsm_pbm = pkt_info->tx_pbmp; 1282 _tx_first_pbm(xd->xd_unit, pkt_info->tx_pbmp, &pkt_info->tx_pbmp); 1283 ENET_COPY_MACADDR(xd->xd_mac_src, xd->xd_mac_src_base); 1284 } 1285 1286 #if defined(BCM_TRIUMPH3_SUPPORT) 1287 if(xd->xd_rpl_type) { 1288 pkt_info->flags2 |= BCM_PKT_F2_REPLACEMENT_TYPE; 1289 pkt_info->flags2 |= BCM_PKT_F2_REPLACEMENT_OFFSET; 1290 pkt_info->oam_replacement_type = xd->xd_rpl_type; 1291 pkt_info->oam_replacement_offset = xd->xd_rpl_offset; 1292 if(xd->xd_lm_ctr_index) { 1293 pkt_info->flags2 |= BCM_PKT_F2_LM_COUNTER_INDEX; 1294 pkt_info->oam_lm_counter_index = xd->xd_lm_ctr_index; 1295 } 1296 } 1297 #endif 1298 /* XMIT all the required packets */ 1299 for (xd->xd_cur_cnt = 0; 1300 xd->xd_cur_cnt < xd->xd_tot_cnt; 1301 xd->xd_cur_cnt++) { 1302 1303 if (xd->xd_state != XD_RUNNING) { 1304 break; /* Abort */ 1305 } 1306 1307 /* 1308 * Generate pattern on first time through, or every time if 1309 * pattern is incrementing. 1310 */ 1311 1312 if (xd->xd_mac_dst_inc != 0) { 1313 ENET_SET_MACADDR(ep->en_dhost, xd->xd_mac_dst); 1314 } 1315 if (xd->xd_mac_src_inc != 0) { 1316 ENET_SET_MACADDR(ep->en_shost, xd->xd_mac_src); 1317 } 1318 1319 /* Store pattern */ 1320 if (!XD_FILE(xd) && !XD_STRING(xd) && xd->xd_pat_random) { 1321 packet_random_store(payload, payload_len); 1322 } else if (!XD_FILE(xd) && !XD_STRING(xd) && 1323 (xd->xd_cur_cnt == 0 || xd->xd_pat_inc != 0)) { 1324 xd->xd_pat = 1325 packet_store(payload, payload_len, 1326 xd->xd_pat, xd->xd_pat_inc); 1327 } 1328 1329 #ifdef BCM_INSTRUMENTATION_SUPPORT 1330 if (xd->xd_vis_sport) { 1331 rv = appl_visibility_trace(xd->xd_unit, 1332 xd->xd_vis_options, 1333 xd->xd_vis_sport, 1334 pkt_info); 1335 } else 1336 #endif /* BCM_INSTRUMENTATION_SUPPORT */ 1337 { 1338 rv = bcm_tx(xd->xd_tx_unit, pkt_info, NULL); 1339 } 1340 if (rv != BCM_E_NONE) { 1341 cli_out("bcm_tx failed2: TX Unit %d: %s\n", 1342 xd->xd_tx_unit, bcm_errmsg(rv)); 1343 break; 1344 } 1345 1346 increment_macaddr(xd->xd_mac_dst, xd->xd_mac_dst_inc); 1347 increment_macaddr(xd->xd_mac_src, xd->xd_mac_src_inc); 1348 1349 if (xd->xd_ppsm) { /* per port source mac */ 1350 /* change xd_pbm to next port. reset src mac if at base port */ 1351 if (_tx_next_port(xd->xd_unit, &pkt_info->tx_pbmp, 1352 xd->xd_ppsm_pbm)) { 1353 LOG_INFO(BSL_LS_APPL_TX, 1354 (BSL_META_U(xd->xd_tx_unit, 1355 "resetting mac\n"))); 1356 ENET_COPY_MACADDR(xd->xd_mac_src_base, xd->xd_mac_src); 1357 } 1358 } 1359 } 1360 1361 if (xd->xd_ppsm) { /* Replace original params */ 1362 ENET_COPY_MACADDR(xd->xd_mac_src_base, xd->xd_mac_src); 1363 pkt_info->tx_pbmp = xd->xd_ppsm_pbm; 1364 } 1365 1366 return(rv == BCM_E_NONE ? CMD_OK : CMD_FAIL); 1367 } 1368 1369 STATIC void 1370 do_tx_start(void *xdv) 1371 /* 1372 * Function: do_tx_start 1373 * Purpose: Wrapper function for a tx_start thread. 1374 * Parameters: xdv - pointer to xd structure for the unit under test. 1375 * Returns: Nothing, does not return. 1376 */ 1377 { 1378 cmd_result_t rv; 1379 xd_t *xd = (xd_t *)xdv; 1380 1381 rv = do_tx(xd); 1382 1383 cli_out("TX Completed %s: TX Requested(%d) Tx Sent(%d)\n", 1384 rv == CMD_OK ?"successfully" : "with error", 1385 xd->xd_tot_cnt, xd->xd_cur_cnt); 1386 xd->xd_state = XD_IDLE; 1387 sal_thread_exit(rv == CMD_OK ? 0 : 1); 1388 } 1389 1390 char cmd_rx_usage[] = 1391 "Parameters: <count>\n\t" 1392 "Wait for and received <count> packets from the CMIC. This command\n\t" 1393 "is mostly obsolete, and PacketWatcher should be used.\n"; 1394 1395 cmd_result_t 1396 cmd_rx(int u, args_t *a) 1397 /* 1398 * Function: rx 1399 * Purpose: Perform simple RX 1400 * Parameters: u - unit number 1401 * a - arguments (expect "count"); 1402 * Returns: CMD_XX 1403 */ 1404 { 1405 cmd_result_t rv = CMD_OK; 1406 dv_t *dv; 1407 void *p; /* Packet */ 1408 int cnt, i; 1409 pbmp_t empty_pbm; 1410 1411 if ((1 != ARG_CNT(a)) || !(isint(ARG_CUR(a)))) { 1412 return(CMD_USAGE); 1413 } else if (!sh_check_attached(ARG_CMD(a), u)) { 1414 return(CMD_FAIL); 1415 } else if (pw_running(u)) { 1416 cli_out("%s: Error: Packetwatcher running\n", ARG_CMD(a)); 1417 return(CMD_FAIL); 1418 } 1419 1420 cnt = parse_integer(ARG_GET(a)); 1421 1422 if (!(dv = soc_dma_dv_alloc(u, DV_RX, 1))) { 1423 cli_out("%s: failed to allocate DV\n", ARG_CMD(a)); 1424 return(CMD_FAIL); 1425 } 1426 if (!(p = soc_cm_salloc(u, 10240, "RX"))) { 1427 cli_out("%s: failed to allocate packet memory\n", ARG_CMD(a)); 1428 soc_dma_dv_free(u, dv); 1429 return(CMD_FAIL); 1430 } 1431 1432 SOC_PBMP_CLEAR(empty_pbm); 1433 for (i = 0; i < cnt; i++) { 1434 int result; 1435 1436 soc_dma_dv_reset(DV_RX, dv); 1437 soc_dma_desc_add(dv, (sal_vaddr_t)p, 10240, 1438 empty_pbm, empty_pbm, empty_pbm, 0, NULL); 1439 soc_dma_desc_end_packet(dv); 1440 1441 if (0 > (result = soc_dma_wait(u, dv))) { 1442 cli_out("%s: Dma Failed: %s\n", ARG_CMD(a), soc_errmsg(result)); 1443 rv = CMD_FAIL; 1444 break; 1445 } 1446 } 1447 1448 soc_dma_dv_free(u, dv); 1449 soc_cm_sfree(u, p); 1450 return(rv); 1451 } 1452 1453 cmd_result_t 1454 cmd_esw_tx_count(int u, args_t *a) 1455 /* 1456 * Function: tx_count 1457 * Purpose: Print out status of any currently running TX command. 1458 * Parameters: u - unit number. 1459 * a - arguments, none expected. 1460 * Returns: CMD_OK 1461 */ 1462 { 1463 xd_t *xd; 1464 1465 if (ARG_CNT(a)) { 1466 return(CMD_USAGE); 1467 } 1468 1469 _XD_INIT(u, xd); 1470 cli_out("TX (%sRunning) Transmit Req(%d) Sent(%d)\n", 1471 xd->xd_state == XD_RUNNING ? "" : "Not-", 1472 xd->xd_tot_cnt, xd->xd_cur_cnt); 1473 return(CMD_OK); 1474 } 1475 1476 cmd_result_t 1477 cmd_esw_tx_start(int u, args_t *a) 1478 /* 1479 * Function: tx_start 1480 * Purpose: Start off a background TX thread. 1481 * Parameters: u - unit number 1482 * a - arguments. 1483 * Returns: CMD_XXX 1484 */ 1485 { 1486 cmd_result_t rv; 1487 xd_t *xd; 1488 1489 if (!sh_check_attached(ARG_CMD(a), u)) { 1490 return(CMD_FAIL); 1491 } 1492 1493 _XD_INIT(u, xd); 1494 if (xd->xd_state == XD_RUNNING) { 1495 cli_out("%s: Error: tx command running\n", ARG_CMD(a)); 1496 return(CMD_FAIL); 1497 } 1498 1499 #ifdef BROADCOM_DEBUG 1500 if (ARG_CUR(a) && !sal_strcasecmp(_ARG_CUR(a), "show")) { 1501 bcm_tx_show(u); 1502 return CMD_OK; 1503 } 1504 #endif /* BROADCOM_DEBUG */ 1505 1506 if (CMD_OK != (rv = tx_parse(u, a, xd))) { 1507 return(rv); 1508 } 1509 1510 /* BLOCK_CNTL_C */ 1511 xd->xd_state = XD_RUNNING; /* Say GO */ 1512 1513 if (SAL_THREAD_ERROR == sal_thread_create("TX", SAL_THREAD_STKSZ, 100, 1514 do_tx_start, (void *)xd)) { 1515 cli_out("%s: Error: Failed to create background thread\n",ARG_CMD(a)); 1516 xd->xd_state = XD_IDLE; 1517 rv = CMD_FAIL; 1518 } 1519 /* UN-BLOCK_CNTL_C */ 1520 return(rv); 1521 } 1522 1523 cmd_result_t 1524 cmd_esw_tx_stop(int u, args_t *a) 1525 /* 1526 * Function: tx_stop 1527 * Purpose: Stop a currently running TX command 1528 * Parameters: u - unit number. 1529 * a - arguments (none expected). 1530 * Returns: CMD_OK/CMD_USAGE/CMD_FAIL 1531 */ 1532 { 1533 xd_t *xd; 1534 1535 if (ARG_CNT(a)) { 1536 return(CMD_USAGE); 1537 } else if (!sh_check_attached(ARG_CMD(a), u)) { 1538 return(CMD_FAIL); 1539 } 1540 _XD_INIT(u, xd); 1541 if (XD_RUNNING != xd->xd_state) { 1542 cli_out("%s: TX not currently running\n", ARG_CMD(a)); 1543 return(CMD_FAIL); 1544 } else { 1545 xd->xd_state = XD_STOP; 1546 cli_out("%s: TX termination requested\n", ARG_CMD(a)); 1547 return(CMD_OK); 1548 } 1549 } 1550 1551 cmd_result_t 1552 cmd_esw_tx(int u, args_t *a) 1553 /* 1554 * Function: 1555 * Purpose: 1556 * Parameters: 1557 * Returns: 1558 */ 1559 { 1560 xd_t *xd; 1561 volatile cmd_result_t rv; 1562 jmp_buf ctrl_c; 1563 1564 if (!sh_check_attached(ARG_CMD(a), u)) { 1565 return(CMD_FAIL); 1566 } 1567 _XD_INIT(u, xd); 1568 if (xd->xd_state == XD_RUNNING) { 1569 cli_out("%s: Error: already active\n", ARG_CMD(a)); 1570 return(CMD_FAIL); 1571 } 1572 1573 if (CMD_OK != (rv = tx_parse(u, a, xd))) { 1574 return(rv); 1575 } 1576 1577 #ifndef NO_CTRL_C 1578 if (!setjmp(ctrl_c)) { 1579 #endif 1580 sh_push_ctrl_c(&ctrl_c); 1581 xd->xd_state = XD_RUNNING; /* Say GO */ 1582 rv = do_tx(xd); 1583 #ifndef NO_CTRL_C 1584 } else { 1585 rv = CMD_INTR; 1586 } 1587 #endif 1588 1589 sh_pop_ctrl_c(); 1590 xd->xd_state = XD_IDLE; 1591 1592 return(rv); 1593 } 1594 1595 /**************************************************************** 1596 * 1597 * RX commands 1598 */ 1599 1600 1601 cmd_result_t 1602 cmd_esw_rx_init(int unit, args_t *args) 1603 { 1604 char *ch; 1605 int override_unit; 1606 int rv; 1607 1608 if ((ch = ARG_GET(args)) == NULL) { 1609 cli_out("RXINIT requires unit specification\n"); 1610 return CMD_USAGE; 1611 } 1612 1613 override_unit = strtoul(ch, NULL, 0); 1614 rv = bcm_rx_init(override_unit); 1615 1616 if (rv < 0) { 1617 cli_out("ERROR: bcm_rx_init(%d) returns %d: %s\n", 1618 override_unit, rv, bcm_errmsg(rv)); 1619 return CMD_FAIL; 1620 } 1621 1622 return CMD_OK; 1623 } 1624 1625 1626 char cmd_hdr_mode_usage[] = 1627 "Parameters: [mode]\n" 1628 " With no mode, shows packet header mode of current unit.\n" 1629 " Although the header mode may be set for any device, \n" 1630 " it only has an effect for BCM5670 and related devices\n" 1631 " Supported modes are:\n" 1632 " Ieee -- no encapusulation\n" 1633 " Higig -- Use parsed HiGig header information\n" 1634 #ifdef BCM_HIGIG2_SUPPORT 1635 " Higig2 -- Use parsed HiGig2 header information\n" 1636 #endif /* BCM_HIGIG2_SUPPORT */ 1637 " B5632 -- Use parsed BCM5632 header information\n" 1638 " Raw -- Use 3 words of raw data for the header\n"; 1639 1640 cmd_result_t 1641 cmd_hdr_mode(int unit, args_t *args) 1642 /* 1643 * Function: 1644 * Purpose: 1645 * Parameters: 1646 * Returns: 1647 */ 1648 { 1649 xd_t *xd; 1650 char *arg; 1651 int i = -1; 1652 1653 if (!sh_check_attached(ARG_CMD(args), unit)) { 1654 return(CMD_FAIL); 1655 } 1656 1657 _XD_INIT(unit, xd); 1658 1659 if ((arg = ARG_GET(args)) != NULL) { 1660 for (i = 0; i < ENCAP_COUNT; i++) { 1661 if (!sal_strcasecmp(arg, hdr_modes[i])) { 1662 xd->hdr_mode = i; 1663 break; 1664 } 1665 } 1666 } 1667 1668 if (xd->hdr_mode < 0 || xd->hdr_mode >= ENCAP_COUNT) { 1669 cli_out("Current header mode for unit %d is invalid (%d).\n", 1670 unit, xd->hdr_mode); 1671 } else { 1672 cli_out("Current header mode for unit %d is%s %s (%d).\n", 1673 unit, (i != -1) ? " now" : "", 1674 hdr_modes[xd->hdr_mode], xd->hdr_mode); 1675 } 1676 1677 return (i < ENCAP_COUNT) ? CMD_OK : CMD_USAGE; 1678 } 1679 1680 /* 1681 * Very simple test command for the SOC DMA ROM interface 1682 */ 1683 char cmd_drt_usage[] = 1684 "Parameters: [init|detach|rx|tx]\n" 1685 " init - Calls soc_dma_rom_init() \n" 1686 " detach - Calls soc_dma_rom_detach() \n" 1687 " rx - Calls soc_dma_rom_rx_poll() \n" 1688 " Dumps packet if available \n" 1689 " tx - Simple packet transmit using soc_dma_rom_tx_start() \n"; 1690 1691 1692 cmd_result_t 1693 cmd_drt(int unit, args_t *args) 1694 { 1695 char* arg; 1696 int rv; 1697 1698 if((arg = ARG_GET(args)) == NULL) { 1699 return CMD_USAGE; 1700 } 1701 1702 if(!sal_strcmp(arg, "init")) { 1703 if((rv = soc_dma_rom_init(unit, 1600, 1, 1)) < 0) { 1704 cli_out("soc_dma_rom_init() returned %d: %s\n", 1705 rv, soc_errmsg(rv)); 1706 return CMD_FAIL; 1707 } 1708 } 1709 else if(!sal_strcmp(arg, "detach")) { 1710 if((rv = soc_dma_rom_detach(unit)) < 0) { 1711 cli_out("soc_dma_rom_detach() returnd %d: %s\n", 1712 rv, soc_errmsg(rv)); 1713 return CMD_FAIL; 1714 } 1715 } 1716 else if(!sal_strcmp(arg, "rx")) { 1717 dcb_t* dcb; 1718 1719 if((rv=soc_dma_rom_rx_poll(unit, &dcb)) < 0) { 1720 cli_out("soc_dma_rom_rx_poll() returned %d: %s\n", 1721 rv, soc_errmsg(rv)); 1722 return CMD_FAIL; 1723 } 1724 1725 if(dcb) { 1726 unsigned char* pkt; 1727 int len; 1728 1729 pkt = (unsigned char *)SOC_DCB_ADDR_GET(unit, dcb); 1730 len = SOC_DCB_XFERCOUNT_GET(unit, dcb); 1731 1732 soc_dma_dump_pkt(unit, "rx: ", pkt, len, TRUE); 1733 1734 soc_dma_rom_dcb_free(unit, dcb); 1735 } 1736 else { 1737 cli_out("no packet\n"); 1738 } 1739 } 1740 else if(!sal_strcmp(arg, "tx")) { 1741 unsigned char _pkt[100] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1742 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 1743 0x81, 0x00, 0x00, 0x01, 0x00, 0x00, 1744 }; 1745 dcb_t* dcb; 1746 unsigned char* p; 1747 int polls = 0; 1748 int done; 1749 1750 dcb = soc_dma_rom_dcb_alloc(unit, sizeof(_pkt)); 1751 1752 p = (unsigned char*)SOC_DCB_ADDR_GET(unit, dcb); 1753 sal_memcpy(p, _pkt, sizeof(_pkt)); 1754 1755 SOC_DCB_TX_L2PBM_SET(unit, dcb, PBMP_ALL(unit)); 1756 SOC_DCB_TX_UTPBM_SET(unit, dcb, PBMP_E_ALL(unit)); 1757 1758 #ifdef BCM_XGS_SUPPORT 1759 if (SOC_IS_XGS_SWITCH(unit)) { 1760 SOC_DCB_TX_DESTPORT_SET(unit, dcb, 0); 1761 SOC_DCB_TX_DESTMOD_SET(unit, dcb, 1); 1762 SOC_DCB_TX_OPCODE_SET(unit, dcb, SOC_HIGIG_OP_UC); 1763 } 1764 #endif 1765 1766 if ((rv = soc_dma_rom_tx_start(unit, dcb)) < 0) { 1767 cli_out("soc_dma_rom_tx_start() returned %d: %s\n", 1768 rv, soc_errmsg(rv)); 1769 soc_dma_rom_dcb_free(unit, dcb); 1770 return CMD_FAIL; 1771 } 1772 1773 do { 1774 soc_dma_rom_tx_poll(unit, &done); 1775 polls++; 1776 } while(!done); 1777 1778 cli_out("tx done in %d polls\n", polls); 1779 soc_dma_rom_dcb_free(unit, dcb); 1780 1781 } 1782 else { 1783 return CMD_USAGE; 1784 } 1785 1786 return CMD_OK; 1787 } 1788 1789