rpacket.c (69220B)
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 * Packet receive test that uses the BCM api. 8 * 9 * December, 2002: Options added to support RX APIs. 10 * This also adds: 11 * interrupt/non-interrupt handling; 12 * packet stealing; 13 * if stealing, freeing packets with DPC (always with interrupt, 14 * optionally with non-interrupt) or immediately; 15 * 16 * When stealing packets, the system will crash if the rate is 17 * high enough: Over 4K pkts/sec on Mousse, and 6K pkts/sec on BMW. 18 * This does not appear to be related to DPC. 19 * 20 * Current max rates for RX API, no packet stealing: 21 * BMW (8245) on 5690, interrupt: 11.6 K pkts/sec 22 * BMW, non-interrupt: 11.6 K pkts/sec 23 * Mousse, non-interrupt: 10.4 K pkts/sec 24 * 25 * Update on max rates for RX API: 26 */ 27 28 #include <sal/types.h> 29 #include <sal/core/time.h> 30 #include <sal/core/stats.h> 31 #include <sal/appl/sal.h> 32 #include <sal/core/dpc.h> 33 #include <shared/bsl.h> 34 #include <soc/util.h> 35 #include <soc/drv.h> 36 37 #include <appl/diag/system.h> 38 #include <appl/diag/parse.h> 39 #include <appl/diag/shell.h> 40 41 #include <bcm/error.h> 42 #include <bcm/l2.h> 43 #include <bcm/mcast.h> 44 #include <bcm/port.h> 45 #include <bcm/link.h> 46 #include <bcm/field.h> 47 #include <bcm/rx.h> 48 #include <bcm/pkt.h> 49 #include <bcm/stack.h> 50 #include <bcm/vlan.h> 51 52 #include <bcm_int/common/rx.h> 53 #include <bcm_int/common/tx.h> 54 #if defined (BCM_PETRA_SUPPORT) 55 #include <soc/dpp/drv.h> 56 #endif 57 #if defined (BCM_DNX_SUPPORT) 58 #include <src/appl/reference/dnx/appl_ref_rx_init.h> 59 #endif 60 61 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 62 #include <bcm/knet.h> 63 #include <errno.h> 64 #include <stdio.h> 65 #include <unistd.h> 66 #include <arpa/inet.h> 67 #include <sys/socket.h> 68 #include <linux/if_ether.h> 69 #include <linux/if_packet.h> 70 #include <linux/if.h> 71 #include <sys/ioctl.h> 72 #include <sys/poll.h> 73 #include <sys/mman.h> 74 75 #include <sched.h> 76 #include <sal/core/thread.h> 77 #endif 78 79 80 #include "testlist.h" 81 82 #if defined(BCM_FIELD_SUPPORT) || defined(BCM_FE2000_SUPPORT) || defined (BCM_PETRA_SUPPORT) || defined (BCM_DNX_SUPPORT) 83 84 typedef struct p_s { 85 int p_init; /* TRUE --> initialized */ 86 87 /* parameters changed or watched by other threads -- must be volatile */ 88 volatile uint32 p_count_packets; /* Finished test - just drain */ 89 volatile uint32 p_received; 90 volatile uint32 p_drained; 91 volatile uint32 p_time_us; 92 volatile uint32 p_error_num; 93 94 /* internal parameters */ 95 int p_num_test_ports; 96 int p_use_fp_action; 97 int p_port[2]; /* Active port */ 98 int p_time; /* Duration (seconds) */ 99 bcm_port_info_t p_port_info[2]; /* saved port config */ 100 int p_pkts_per_sec; 101 int p_hw_rate; /* use hw rate limiting */ 102 int p_max_q_len; 103 int p_per_cos; /* Run tests with per-cos settings */ 104 int p_burst; 105 uint32 reg_flags; /* Flags used for register */ 106 int p_intr_cb; 107 int p_dump_rx; 108 #if defined(BCM_FIELD_SUPPORT) 109 bcm_field_entry_t p_field_entry[2]; 110 #endif /* BCM_FIELD_SUPPORT */ 111 int p_l_start; /* Length start */ 112 int p_l_end; /* Length end */ 113 int p_l_inc; /* Length increment */ 114 int p_free_buffer; 115 bcm_pkt_t *p_pkt; /* Tx - Packet buffer */ 116 bcm_rx_cfg_t p_rx_cfg; 117 int rx_mode; 118 int p_txrx_unit; 119 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 120 int p_use_socket; 121 int p_sock; 122 int p_netid; 123 int p_filterid; 124 sal_thread_t p_threadid; 125 int p_ringbuf_size; 126 char * p_ringbuf; 127 int p_use_socket_send; 128 #endif 129 int hdr_chk; /* Flag to check EP_TO_CPU header on CMICx */ 130 int diff_len; /* Acceptable difference between s_len and r_len */ 131 int diff_len_chk; /* Flag to check difference between s_len and r_len */ 132 } p_t; 133 134 static sal_mac_addr_t rp_mac_dest = {0x00, 0x11, 0x22, 0x33, 0x44, 0x99}; 135 static sal_mac_addr_t rp_mac_src = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66}; 136 137 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT) 138 int is_force_local = 0; 139 int is_force_fabric = 0; 140 static uint8 rp_ptch_header[2] = {0xd0, 0x00}; 141 static uint8 mypacket[] = { 142 143 144 /* 145 0x0,0x0,0x0,0x0, 0x0,0x1,0x0,0x0, 146 0x0,0x0,0x0,0xe2, 0x81,0x00,0x00,0x00, 147 148 0x90,0x00,*/0x1,0x2, 149 150 151 152 153 /* 0x0,0x0,0x0,0x0, 0x0,0x1,0x0,0x0, 154 0x0,0x0,0x0,0xe2, 0x90,0x00,0x1,0x2, 155 156 0x03,0x4,0x5,0x6, */ 0x7,0x8,0x9,0xa, 157 0xb,0xc,0xd,0xe, 0xf,0x10,0x11,0x12, 158 159 0x13,0x14,0x15,0x16, 0x17,0x18,0x19,0x1a, 160 0x1b,0x1c,0x1d,0x1e, 0x1f,0x20,0x21,0x22, 161 162 0x23,0x24,0x25,0x26, 0x27,0x28,0x29,0x2a, 163 0x2b,0x2c,0x2d,0x2e, 0x2f,0x30,0x31,0x32, 164 165 0x33,0x34,0x35,0x36, 0x37,0x38,0x39,0x3a, 166 0x3b,0x3c,0x3d,0x3e, 0x3f,0x40,0x41,0x42, 167 168 0x43,0x44,0x45,0x46, 0x47,0x48,0x49,0x4a, 169 0x4b,0x4c,0x4d,0x4e, 0x4f,0x50,0x51,0x52, 170 171 172 0x53,0x54,0x55,0x56, 0x57,0x58,0x59,0x5a, 173 0x5b,0x5c,0x5d,0x5e, 0x5f,0x60,0x61,0x62, 174 175 0x63,0x64,0x65,0x66, 0x67,0x68,0x69,0x6a, 176 0x6b,0x6c,0x6d,0x6e, 0x6f,0x70,0x71,0x72, 177 178 0x73,0x74,0x75,0x76, 0x77,0x78,0x79,0x7a, 179 0x7b,0x7c,0x7d,0x7e, 0x7f,0x80,0x81,0x82 }; 180 #endif 181 182 #ifdef BCM_DNX_SUPPORT 183 static uint8 rp_mh_header[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 184 #endif 185 186 187 static p_t *p_control[SOC_MAX_NUM_DEVICES]; 188 189 #define RP_RECEIVER_PRIO 255 /* Priority of rx handler */ 190 #define RP_MAX_PKT_LENGTH 2048 191 #define RP_RX_CHANNEL 1 /* DMA channel */ 192 193 194 #define RP_CHK(rv, f) \ 195 if (BCM_FAILURE((rv))) { \ 196 cli_out("call to %s line %d failed:%d %s\n", #f, __LINE__,\ 197 (rv), bcm_errmsg((rv))); \ 198 } 199 200 201 #define RP_MAX_PPC SOC_DV_PKTS_MAX 202 203 #ifndef DNX_MODULE_HEADER_SIZE 204 /** Define length of Module Header */ 205 #if defined(BCM_DNX_SUPPORT) && !defined(ADAPTER_SERVER_MODE) 206 /** Size of module header on DNX devices, it should be written at the start of the packet */ 207 #define DNX_MODULE_HEADER_SIZE 16 208 #else 209 /** No Module Header on ADAPTER and non DNX*/ 210 #define DNX_MODULE_HEADER_SIZE 0 211 #endif 212 #endif 213 214 #ifdef BCM_DNX_SUPPORT 215 /** Define length PTCH-2 */ 216 #define RP_DNX_HDR_PTCH_TYPE2_LEN 2 217 #define RP_DNX_MAC_ADDR_LEN 6 218 219 /* Helper macro for appending Module Header to ethernet packets */ 220 #define RP_DNX_PKT_MH_HDR_SET(pkt, mh) \ 221 sal_memcpy((pkt)->_pkt_data.data, (mh), DNX_MODULE_HEADER_SIZE) 222 223 /* Helper macro for appending PTCH2 header to ethernet packets with Module Header */ 224 #define RP_DNX_PKT_PTCH_HDR_SET_WITH_MH(pkt, ptch) \ 225 sal_memcpy((pkt)->_pkt_data.data + DNX_MODULE_HEADER_SIZE, (ptch), RP_DNX_HDR_PTCH_TYPE2_LEN) 226 227 /* Helper macro for setting DMAC to ethernet packets with Module Header and PTCH2 header */ 228 #define RP_DNX_PKT_HDR_DMAC_SET_WITH_MH_PTCH(pkt, dmac) \ 229 sal_memcpy((pkt)->_pkt_data.data + DNX_MODULE_HEADER_SIZE + RP_DNX_HDR_PTCH_TYPE2_LEN, (dmac), RP_DNX_MAC_ADDR_LEN) 230 231 /* Helper macro for setting SMAC to ethernet packets with Module Header and PTCH2 header */ 232 #define RP_DNX_PKT_HDR_SMAC_SET_WITH_MH_PTCH(pkt, smac) \ 233 sal_memcpy((pkt)->_pkt_data.data + DNX_MODULE_HEADER_SIZE + RP_DNX_HDR_PTCH_TYPE2_LEN + 6, (smac), RP_DNX_MAC_ADDR_LEN) 234 235 /* Helper macro for setting uint16 to specified position of packet val in network byte order */ 236 #define RP_DNX_HTONS_CVT_SET(pkt, val, posn) \ 237 do { \ 238 uint16 _tmp; \ 239 _tmp = soc_htons(val); \ 240 sal_memcpy((pkt)->_pkt_data.data + (posn), &_tmp, sizeof(uint16)); \ 241 } while (0) 242 243 /* Helper macro for setting TPID to ethernet packets with Module Header and PTCH header */ 244 #define RP_DNX_PKT_HDR_TPID_SET_WITH_MH_PTCH(pkt, tpid) \ 245 RP_DNX_HTONS_CVT_SET(pkt, tpid, DNX_MODULE_HEADER_SIZE + RP_DNX_HDR_PTCH_TYPE2_LEN + RP_DNX_MAC_ADDR_LEN + RP_DNX_MAC_ADDR_LEN) 246 247 /* Helper macro for setting vlan tag to ethernet packets with Module Header and PTCH header */ 248 #define RP_DNX_PKT_HDR_VTAG_CONTROL_SET_WITH_MH_PTCH(pkt, vtag) \ 249 RP_DNX_HTONS_CVT_SET(pkt, vtag, DNX_MODULE_HEADER_SIZE + RP_DNX_HDR_PTCH_TYPE2_LEN + RP_DNX_MAC_ADDR_LEN + RP_DNX_MAC_ADDR_LEN + sizeof(uint16)) 250 251 /* Helper macro for single buffer Ethernet packet with PTCH header(not HiGig). */ 252 #define RP_DNX_PKT_HDR_TAGGED_LEN_SET_WITH_MH_PTCH(pkt, len) \ 253 RP_DNX_HTONS_CVT_SET(pkt, len, DNX_MODULE_HEADER_SIZE + RP_DNX_HDR_PTCH_TYPE2_LEN + RP_DNX_MAC_ADDR_LEN + RP_DNX_MAC_ADDR_LEN + sizeof(uint32)) 254 #endif 255 256 STATIC void 257 debug_dump(int len, uint8 *data) 258 { 259 int i; 260 char tbuf[128]; 261 262 sal_memset(tbuf, 0, 128); 263 for (i = 0; i< len; i++) { 264 sal_sprintf(tbuf+(i % 16)*3, "%02x ", data[i]); 265 if (((i+1) % 16) == 0) { 266 cli_out("%s\n", tbuf); 267 sal_memset(tbuf, 0, 128); 268 } 269 } 270 cli_out("%s\n", tbuf); 271 } 272 273 STATIC void 274 packet_measure(p_t *p, int s_len, int r_len, uint8 *buf, int len_adj) 275 { 276 static sal_usecs_t time_start = 0, hdr_len = 0; 277 sal_usecs_t time_end = 0; 278 279 /* keep accumulating stats */ 280 p->p_received++; 281 /* one packet has been received; track stats */ 282 if (p->p_received == 1) { 283 time_start = sal_time_usecs(); 284 } else { 285 time_end = sal_time_usecs(); 286 /* again overkill to calculate on each packet, but 287 the main test is going to make off with this value 288 at any time, so we have to keep it up to date */ 289 p->p_time_us = (int)(time_end - time_start); 290 } 291 292 if (!p->hdr_chk) { 293 #ifdef BCM_CMICX_SUPPORT 294 if (soc_feature(p->p_txrx_unit, soc_feature_cmicx)) { 295 hdr_len = soc_cmicx_pktdma_header_size_get(p->p_txrx_unit); 296 } 297 #endif 298 p->hdr_chk = 1; 299 } 300 301 if (len_adj) { 302 r_len -= hdr_len; 303 } 304 305 if (p->diff_len_chk && (abs(r_len - s_len) > p->diff_len)) { 306 /* packet error */ 307 p->p_error_num++; 308 if (p->p_error_num == 1) { 309 cli_out("S:%d R:%d\n", s_len, r_len); 310 debug_dump(96, buf); 311 } 312 } 313 } 314 315 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 316 317 318 #define RXRING_FRAME_SIZE (2048) 319 #define MAX_RXRING_FRAMES (1024) 320 321 static int idx = 0; 322 323 324 STATIC void 325 _set_thread_priority(int prio) 326 { 327 struct sched_param param; 328 param.sched_priority = prio; 329 if (sched_setscheduler(0, SCHED_RR, ¶m)) { 330 cli_out("priority set: \n"); 331 } 332 } 333 334 STATIC int 335 knet_stats_get(long unsigned int *ic, long unsigned int *tc) 336 { 337 FILE* f; 338 unsigned int tmp, int_cnt, pkt_cnt0, pkt_cnt1, pkt_cnt2; 339 340 if ((f=fopen("/proc/bcm/knet/stats", "rw" )) == NULL) { 341 *tc = 0; 342 return -1; 343 } 344 (void)fscanf(f, "Device stats (unit %d):\n"\ 345 " Interrupts %10u\n"\ 346 " Tx packets %10u\n"\ 347 " Rx0 packets %10u\n"\ 348 " Rx1 packets %10u\n"\ 349 " Rx2 packets %10u\n"\ 350 " Rx0 pkts/intr %8u\n"\ 351 " Rx1 pkts/intr %8u\n"\ 352 " Rx2 pkts/intr %8u\n", 353 (int *)&tmp, &int_cnt, &tmp, 354 &pkt_cnt0, &pkt_cnt1, &pkt_cnt2, 355 &tmp, &tmp, &tmp); 356 * ic = int_cnt; 357 * tc = pkt_cnt0 + pkt_cnt1 + pkt_cnt2; 358 fclose(f); 359 360 return 0; 361 362 } 363 364 STATIC int 365 knet_stats_clear(void) 366 { 367 FILE* f; 368 369 if ((f=fopen("/proc/bcm/knet/stats", "w+" )) == NULL) { 370 cli_out("fail to open stats for writing\n"); 371 return -1; 372 } 373 fwrite("clear", 5, 1, f); 374 fclose(f); 375 return 0; 376 377 } 378 379 #ifdef FIX_IDX_ORDER 380 381 STATIC int 382 fix_idx(int idx ,volatile p_t* p, int *len) 383 { 384 int max = p-> p_ringbuf_size; 385 int i = (idx+1) % max; 386 387 while (i != idx) { 388 #ifdef PACKET_VERSION 389 volatile struct tpacket2_hdr *head = (volatile struct tpacket2_hdr *) 390 (p->p_ringbuf + i * RXRING_FRAME_SIZE); 391 #else 392 volatile struct tpacket_hdr *head = (volatile struct tpacket_hdr *) 393 (p->p_ringbuf + i * RXRING_FRAME_SIZE); 394 #endif 395 if (head->tp_status & TP_STATUS_USER) { 396 * len = head->tp_len; 397 head->tp_len = 0; 398 head->tp_snaplen = 0; 399 head->tp_status = TP_STATUS_KERNEL; 400 401 return i; 402 } 403 i=(i+1) % max; 404 } 405 return i; 406 } 407 #endif 408 409 STATIC int 410 sock_read_one_pkt (volatile p_t* p, uint8 ** pbuf) 411 { 412 static char sock_buf[RXRING_FRAME_SIZE]; 413 int len = 0; 414 415 if (p->p_ringbuf) { /* ring buffer receive */ 416 417 #ifdef PACKET_VERSION 418 volatile struct tpacket2_hdr *head = (volatile struct tpacket2_hdr *) 419 (p->p_ringbuf + idx * RXRING_FRAME_SIZE); 420 #else 421 volatile struct tpacket_hdr *head = (volatile struct tpacket_hdr *) 422 (p->p_ringbuf + idx * RXRING_FRAME_SIZE); 423 #endif 424 425 * pbuf = (uint8 *)head; 426 427 if (head->tp_status & TP_STATUS_USER) { /* it's our packet */ 428 len = head->tp_len; 429 /* release the ringbuf entry back to the kernel */ 430 head->tp_len = 0; 431 head->tp_snaplen = 0; 432 head->tp_status = TP_STATUS_KERNEL; 433 434 /* next packet */ 435 idx = (idx + 1) % (p->p_ringbuf_size); 436 } else { 437 #ifdef FIX_IDX_ORDER 438 int fixed_idx = fix_idx(idx, p, &len); 439 if (fixed_idx != idx) { 440 idx = (fixed_idx+1) %(p->p_ringbuf_size); 441 442 } 443 #endif 444 } 445 446 } else { /* standard socket receive */ 447 * pbuf = (uint8 *)sock_buf; 448 len = recvfrom(p->p_sock, sock_buf, RXRING_FRAME_SIZE, MSG_DONTWAIT, NULL, NULL); 449 if (len < 0) { 450 len = 0; 451 } 452 } 453 454 return len; 455 } /* sock_read_one_pkt*/ 456 457 458 STATIC void 459 socket_receive(void *arg) 460 { 461 p_t *p = (p_t *)arg; 462 int len = 0; 463 struct pollfd pfd; 464 uint8 * buf; 465 466 _set_thread_priority(50); 467 468 if (p->p_sock <= 0) { 469 cli_out("bad socket %d\n", p->p_sock); 470 return; 471 } 472 473 sal_memset(&pfd, 0, sizeof(pfd)); 474 pfd.fd = p->p_sock; 475 pfd.events = POLLIN /*| POLLERR*/; 476 pfd.revents = 0; 477 478 while (TRUE) { 479 pfd.revents = 0; 480 /* wait for data to arrive*/ 481 len = poll(&pfd, 1, -1); 482 483 if (len == -1) { 484 if (errno != EINTR) { 485 cli_out("poll error: errno %d\n", errno); 486 } 487 continue; 488 } else if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { 489 cli_out("poll exception; revents 0x%x\n", pfd.revents); 490 continue; 491 } else if ((pfd.revents & POLLIN) == 0) { 492 cli_out("poll without data; revents %x\n", pfd.revents); 493 continue; 494 } 495 496 /* pull packet from socket until empty*/ 497 while ((len = sock_read_one_pkt (p, &buf)) > 0) { 498 if (p->p_count_packets) { 499 packet_measure(p, p->p_pkt->_pkt_data.len, len, buf, 0); 500 } else { 501 p->p_drained++; 502 } 503 } /* while packet len > 0 */ 504 505 } /* while processing packets */ 506 507 cli_out("socket_receive thread done.\n"); 508 /* spin forever, waiting to be killed */ 509 for (;;) { 510 } 511 512 } /* socket_receive */ 513 514 515 STATIC int 516 bind_device(int sock, char* dev) 517 { 518 int rv; 519 struct sockaddr_ll addr; 520 struct ifreq req; 521 522 sal_memset(&req, 0, sizeof(req)); 523 sal_strncpy(req.ifr_name, dev, sizeof(req.ifr_name)); 524 if ((rv = ioctl(sock, SIOCGIFINDEX, &req)) < 0) { 525 cli_out("ioctl error %d\n", errno); 526 return rv; 527 } 528 529 if ((rv = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, 530 (void *)&req, sizeof(req))) < 0) { 531 cli_out("bind_device setsockopt error %d\n", errno); 532 return rv; 533 } 534 535 sal_memset(&addr, 0, sizeof(addr)); 536 addr.sll_family = AF_PACKET; 537 addr.sll_protocol = htons(0x8100); 538 addr.sll_ifindex = req.ifr_ifindex; 539 addr.sll_hatype = 0; 540 addr.sll_pkttype = 0; 541 addr.sll_halen = 0; 542 if ((rv = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) { 543 cli_out("bind error %d\n", errno); 544 return rv; 545 } 546 return 0; 547 } 548 549 STATIC int 550 set_promisc_up(int sock, char* dev) 551 { 552 struct ifreq req; 553 sal_strncpy(req.ifr_name, dev, sizeof(req.ifr_name)); 554 555 if (ioctl(sock, SIOCGIFFLAGS, &req)==-1) { 556 cli_out("ioctl error"); 557 return -1; 558 } 559 req.ifr_flags |= (IFF_PROMISC | IFF_UP | IFF_RUNNING); 560 if (ioctl(sock, SIOCSIFFLAGS, &req)==-1) { 561 cli_out("ioctl error"); 562 return -1; 563 } 564 return 0; 565 } 566 STATIC int 567 knetif_setup(int unit, p_t *p) 568 { 569 int rv; 570 bcm_knet_netif_t netif; 571 bcm_knet_filter_t filter; 572 struct tpacket_req req; 573 574 bcm_knet_netif_t_init(&netif); 575 netif.type = BCM_KNET_NETIF_T_TX_CPU_INGRESS; 576 sal_memcpy(netif.mac_addr, rp_mac_dest, 6); 577 578 p->p_netid = 0; 579 rv = bcm_knet_netif_create(unit, &netif); 580 if (BCM_SUCCESS(rv)) { 581 p->p_netid = netif.id; 582 } else { 583 cli_out("bcm_knet_netif_create failed: %d\n", rv); 584 return rv; 585 } 586 587 p->p_filterid = 0; 588 bcm_knet_filter_t_init(&filter); 589 filter.type = BCM_KNET_FILTER_T_RX_PKT; 590 if (p->p_use_socket) { 591 filter.dest_type = BCM_KNET_DEST_T_NETIF; 592 filter.dest_id = p->p_netid; 593 } else { 594 filter.dest_type = BCM_KNET_DEST_T_BCM_RX_API; 595 } 596 rv = bcm_knet_filter_create(unit, &filter); 597 if (BCM_SUCCESS(rv)) { 598 p->p_filterid = filter.id; 599 } else { 600 cli_out("bcm_knet_filter_create:%d\n", rv); 601 return rv; 602 } 603 604 p->p_sock = socket(AF_PACKET, SOCK_RAW, htons(0x8100)); 605 606 set_promisc_up(p->p_sock, "bcm0"); 607 set_promisc_up(p->p_sock, netif.name); 608 609 /* set up ring buffer, if needed */ 610 if ((p->p_use_socket) && (p->p_ringbuf_size > 0)) { 611 int buf_size = p->p_ringbuf_size * RXRING_FRAME_SIZE; 612 #ifdef PACKET_VERSION 613 int tpacket_version = TPACKET_V2; 614 /* set tpacket hdr version. */ 615 if (-1 == setsockopt (p->p_sock, SOL_PACKET, PACKET_VERSION, 616 &tpacket_version, sizeof (int))) { 617 cli_out("set tpacket version failure.\n"); 618 } 619 #endif 620 idx = 0; 621 622 req.tp_block_size = buf_size; 623 req.tp_block_nr = 1; 624 req.tp_frame_size = RXRING_FRAME_SIZE; 625 req.tp_frame_nr = p->p_ringbuf_size; 626 627 if (-1 == setsockopt(p->p_sock, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req))) { 628 cli_out("setsockopt PACKET_RX_RING error\n"); 629 } 630 p->p_ringbuf = (char*)mmap(0, buf_size, PROT_READ|PROT_WRITE, MAP_SHARED, p->p_sock, 0); 631 if (MAP_FAILED == p->p_ringbuf) { 632 cli_out("mmap error\n"); 633 p->p_ringbuf = NULL; 634 p->p_ringbuf_size = 0; 635 } else { 636 memset(p->p_ringbuf, 0, buf_size); 637 } 638 } 639 bind_device(p->p_sock, netif.name); 640 if (p->p_use_socket) { 641 p->p_threadid = sal_thread_create("sock_rx", 8192, 50, socket_receive, p); 642 } 643 return rv; 644 } 645 646 STATIC void 647 knetif_clean(int unit, p_t *p) 648 { 649 if (p->p_threadid != NULL) { 650 sal_thread_destroy(p->p_threadid); 651 p->p_threadid = NULL; 652 } 653 654 if (p->p_ringbuf != NULL) { 655 struct tpacket_req req; 656 int buf_size = p->p_ringbuf_size * RXRING_FRAME_SIZE; 657 sal_memset(&req, 0, sizeof(req)); 658 setsockopt(p->p_sock, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req)); 659 munmap(p->p_ringbuf, buf_size); 660 p->p_ringbuf = NULL; 661 } 662 if (p->p_sock > 0) { 663 struct ifreq req; 664 bcm_knet_netif_t netif; 665 bcm_knet_netif_get(unit, p->p_netid, &netif); 666 667 sal_strncpy(req.ifr_name, netif.name, sizeof(req.ifr_name)); 668 669 if (ioctl(p->p_sock, SIOCGIFFLAGS, &req)==-1) { 670 cli_out("ioctl SIOCGIFFLAGS error"); 671 } 672 req.ifr_flags &= (~(IFF_UP | IFF_RUNNING)); 673 if (ioctl(p->p_sock, SIOCSIFFLAGS, &req)==-1) { 674 cli_out("ioctl SIOCSIFFLAGS error"); 675 } 676 close(p->p_sock); 677 p->p_sock = 0; 678 } 679 if (p->p_filterid > 0) { 680 bcm_knet_filter_destroy(unit, p->p_filterid); 681 p->p_filterid = 0; 682 } 683 684 if (p->p_netid > 0) { 685 bcm_knet_netif_destroy(unit, p->p_netid); 686 p->p_netid = 0; 687 } 688 } 689 690 #endif 691 692 /* 693 * The following function may be called in interrupt context. 694 * Does no packet classification; assume we're to see all pkts. 695 */ 696 697 STATIC bcm_rx_t 698 rpacket_rx_receive(int unit, bcm_pkt_t *pkt, void *vp) 699 { 700 p_t *p = (p_t *)vp; 701 int send_len = p->p_pkt->_pkt_data.len; 702 int len = pkt->tot_len; 703 if (!p->p_count_packets) { 704 /* 705 * Just drain packets. 706 */ 707 p->p_drained++; 708 return BCM_RX_HANDLED; 709 } 710 711 packet_measure(p, send_len, len, (uint8 *)pkt->pkt_data->data, 0); 712 713 if (p->p_free_buffer) { 714 if (p->p_intr_cb) { /* Queue in interrupt context */ 715 bcm_rx_free_enqueue(unit, pkt->_pkt_data.data); 716 } else { 717 bcm_rx_free(unit, pkt->alloc_ptr); 718 } 719 return BCM_RX_HANDLED_OWNED; 720 } 721 722 return BCM_RX_HANDLED; 723 } 724 725 STATIC INLINE int 726 rpacket_register(int unit, p_t *p) 727 { 728 if (SOC_IS_ARAD(unit)) { 729 return _bcm_common_rx_register(unit, "rpkt-rx", rpacket_rx_receive, RP_RECEIVER_PRIO, p, p->reg_flags); 730 731 } else { 732 return bcm_rx_register(unit, "rpkt-rx", rpacket_rx_receive, 733 RP_RECEIVER_PRIO, p, p->reg_flags); 734 } 735 } 736 737 STATIC INLINE int 738 rpacket_unregister(int unit, p_t *p) 739 { 740 if (SOC_IS_ARAD(unit)) { 741 return _bcm_common_rx_unregister(unit, rpacket_rx_receive, RP_RECEIVER_PRIO); 742 } else { 743 return bcm_rx_unregister(unit, rpacket_rx_receive, RP_RECEIVER_PRIO); 744 } 745 } 746 747 STATIC int 748 rpacket_receiver_activate(int unit, p_t *p) 749 { 750 int rv; 751 752 /* Set up common attributes first */ 753 if (bcm_rx_active(unit)) { 754 cli_out("Stopping active RX.\n"); 755 rv = bcm_rx_stop(unit, NULL); 756 if (!BCM_SUCCESS(rv)) { 757 cli_out("Unable to stop RX: %s\n", bcm_errmsg(rv)); 758 return -1; 759 } 760 } 761 762 if (!soc_feature(unit, soc_feature_packet_rate_limit)) { 763 /* Only set the burst size if the unit doesn't have 764 * CPU packet rate limiting feature in HW. Otherwise, 765 * packets are dropped causing the test to fail. 766 */ 767 if (SOC_IS_ARAD(unit) || SOC_IS_DNX(unit)) { 768 rv = _bcm_common_rx_burst_set(unit, p->p_burst); 769 } else { 770 rv = bcm_rx_burst_set(unit, p->p_burst); 771 } 772 if (BCM_FAILURE(rv)) { 773 cli_out("Unable to set RX burst limit: %s\n", 774 bcm_errmsg(rv)); 775 } 776 } 777 778 if (p->p_hw_rate) { 779 if (p->p_per_cos) { 780 if (!SOC_IS_KATANA(unit)) { 781 bcm_rx_cos_rate_set(unit, 0, p->p_pkts_per_sec); 782 bcm_rx_cos_burst_set(unit, 0, p->p_burst); 783 p->p_rx_cfg.global_pps = 0; 784 p->p_rx_cfg.max_burst = 0; 785 } 786 } else { 787 rv = bcm_port_rate_egress_pps_set (unit, CMIC_PORT(unit), 788 p->p_pkts_per_sec, p->p_burst); 789 } 790 } else { 791 bcm_rx_cos_rate_set(unit, BCM_RX_COS_ALL, 0); 792 bcm_rx_cos_burst_set(unit, BCM_RX_COS_ALL, 0); 793 p->p_rx_cfg.global_pps = p->p_pkts_per_sec; 794 p->p_rx_cfg.max_burst = p->p_burst; 795 } 796 if (p->p_max_q_len >= 0) { 797 cli_out("Setting MAX Q length to %d\n", p->p_max_q_len); 798 bcm_rx_cos_max_len_set(unit, BCM_RX_COS_ALL, p->p_max_q_len); 799 } 800 if (SOC_IS_ARAD(unit)) { 801 rv = _bcm_common_rx_start(unit, &p->p_rx_cfg ); 802 } else { 803 rv = bcm_rx_start(unit, &p->p_rx_cfg ); 804 } 805 if (!BCM_SUCCESS(rv)) { 806 cli_out("Unable to Start RX: %s\n", bcm_errmsg(rv)); 807 return -1; 808 } 809 p->reg_flags = BCM_RCO_F_ALL_COS + 810 (p->p_intr_cb ? BCM_RCO_F_INTR : 0); 811 812 return 0; 813 } 814 815 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT) 816 static int 817 rp_dune_port_enable_set (int unit, p_t *p, int enable) 818 { 819 bcm_port_config_t config; 820 pbmp_t tmp_pbmp; 821 int port_idx; 822 soc_port_t port; 823 int rv = BCM_E_NONE; 824 825 /** Disable all other ports */ 826 BCM_PBMP_ASSIGN(tmp_pbmp, PBMP_E_ALL(unit)); 827 /** Remove CPU port*/ 828 BCM_PBMP_REMOVE(tmp_pbmp, PBMP_CMIC(unit)); 829 830 /** Remove special ports that are not included in SOC PBMPCPU */ 831 rv = bcm_port_config_get(unit, &config); 832 RP_CHK(rv, bcm_port_config_get); 833 if (SOC_IS_DNX(unit)) 834 { 835 BCM_PBMP_REMOVE(tmp_pbmp, config.erp); 836 BCM_PBMP_REMOVE(tmp_pbmp, config.oamp); 837 BCM_PBMP_REMOVE(tmp_pbmp, config.olp); 838 BCM_PBMP_REMOVE(tmp_pbmp, config.eventor); 839 BCM_PBMP_REMOVE(tmp_pbmp, config.sat); 840 BCM_PBMP_REMOVE(tmp_pbmp, config.rcy_mirror); 841 } 842 else if (SOC_IS_ARAD(unit)) 843 { 844 BCM_PBMP_REMOVE(tmp_pbmp, config.sat); 845 BCM_PBMP_REMOVE(tmp_pbmp, config.ipsec); 846 } 847 848 /** Remove loopback ports */ 849 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 850 BCM_PBMP_PORT_REMOVE(tmp_pbmp, p->p_port[port_idx]); 851 } 852 853 PBMP_ITER(tmp_pbmp, port) { 854 rv = bcm_port_enable_set(unit, port, enable); 855 RP_CHK(rv, bcm_port_enable_set); 856 } 857 858 return rv; 859 } 860 static int 861 rp_dune_get_ssp_and_cpu_channel(int unit, bcm_pkt_t *pkt, p_t *p) 862 { 863 int rv = BCM_E_NONE; 864 uint32 flags; 865 bcm_port_interface_info_t interface_info; 866 bcm_port_mapping_info_t mapping_info; 867 bcm_port_t port_ndx; 868 bcm_port_t ptch_ssp = 0; 869 bcm_core_t ptch_ssp_core = 0; 870 871 /** Get corresponding core of PTCH.SSP */ 872 rv = bcm_port_get(unit, p->p_port[0], &flags, &interface_info, &mapping_info); 873 RP_CHK(rv, bcm_port_get); 874 875 /* ptch_ssp = mapping_info.pp_port; */ 876 ptch_ssp = p->p_port[0]; 877 ptch_ssp_core = mapping_info.core; 878 879 /** Always set BCM_PKT_F_HGHDR to indicate MH is present*/ 880 p->p_pkt->flags |= BCM_PKT_F_HGHDR; 881 882 /** Get first CPU port with Same core as in TM port*/ 883 BCM_PBMP_ITER(PBMP_CMIC(unit), port_ndx) 884 { 885 rv = bcm_port_get(unit, port_ndx, &flags, &interface_info, &mapping_info); 886 if (rv != BCM_E_NONE) 887 { 888 test_error(unit, "bcm_port_get failed: %s\n", bcm_errmsg(rv)); 889 } 890 if (mapping_info.core == ptch_ssp_core) 891 { 892 p->p_pkt->_dpp_hdr[0] = (uint8)(mapping_info.channel & 0xff); 893 break; 894 } 895 } 896 897 pkt->_dpp_hdr[1] = 0; 898 pkt->_dpp_hdr[2] = 0; 899 pkt->_dpp_hdr[3] = 0; 900 901 /* Set SSP to PTCH */ 902 rp_ptch_header[1] = ptch_ssp; 903 904 return rv; 905 } 906 907 #endif 908 909 STATIC int 910 rpacket_setup(int unit, p_t *p) 911 { 912 int got_port; 913 int rv = BCM_E_UNAVAIL; 914 uint8 *fill_addr; 915 soc_port_t port; 916 int port_idx; 917 pbmp_t gxe_pbm; 918 pbmp_t tmp_pbmp; 919 int speed = 0; 920 int txrx_modid = 0; 921 922 p->p_txrx_unit = unit; 923 p->p_use_fp_action = 0; 924 p->p_num_test_ports = 1; 925 926 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2(unit) || SOC_IS_HELIX4(unit)){ 927 p->p_use_fp_action = 1; 928 p->p_num_test_ports = 2; 929 } 930 931 #ifdef BCM_PETRA_SUPPORT 932 if(SOC_IS_ARAD(unit)) { 933 p->p_num_test_ports = 2; 934 } 935 #endif 936 #ifdef BCM_DNX_SUPPORT 937 if(SOC_IS_DNX(unit)) { 938 p->p_num_test_ports = 2; 939 } 940 #endif 941 942 /* 943 * Pick a port, and redirect the packet back out that port with the 944 * FFP. Single port redirection drops packets on ingress due to the 945 * split horizon check 946 */ 947 948 got_port = FALSE; 949 950 BCM_PBMP_ASSIGN(gxe_pbm, PBMP_GE_ALL(unit)); 951 BCM_PBMP_OR(gxe_pbm, PBMP_XE_ALL(unit)); 952 BCM_PBMP_OR(gxe_pbm, PBMP_CE_ALL(unit)); 953 954 port_idx = 0; 955 PBMP_ITER(gxe_pbm, port) { 956 if (IS_ST_PORT(unit, port) || IS_PON_PORT(unit, port)) { 957 continue; 958 } 959 #ifdef BCM_DNX_SUPPORT 960 if (SOC_IS_DNX(unit)) 961 { 962 rv = bcm_port_linkscan_get(unit, port, &p->p_port_info[port_idx].linkscan); 963 RP_CHK(rv, bcm_port_linkscan_get); 964 if (BCM_SUCCESS(rv)) 965 { 966 rv = bcm_port_linkscan_set(unit, port, BCM_LINKSCAN_MODE_NONE); 967 RP_CHK(rv, bcm_port_linkscan_set); 968 } 969 if (BCM_SUCCESS(rv)) 970 { 971 rv = bcm_port_loopback_get(unit, port, &p->p_port_info[port_idx].loopback); 972 RP_CHK(rv, bcm_port_loopback_get); 973 } 974 } 975 else 976 #endif 977 { 978 rv = bcm_port_info_save(unit, port, &p->p_port_info[port_idx]); 979 RP_CHK(rv, bcm_port_info_save); 980 981 if (BCM_SUCCESS(rv)) { 982 rv = bcm_port_linkscan_set(unit, port, BCM_LINKSCAN_MODE_NONE); 983 RP_CHK(rv, bcm_port_linkscan_set); 984 } 985 #ifdef BCM_PETRA_SUPPORT 986 if ((SOC_IS_ARAD(unit) && SOC_DPP_PP_ENABLE(unit)) || (!SOC_IS_ARAD(unit))) 987 #endif 988 { 989 if (BCM_SUCCESS(rv)) 990 { 991 rv = bcm_port_speed_max(unit, port, &speed); 992 RP_CHK(rv, bcm_port_speed_max); 993 } 994 #ifdef BCM_TOMAHAWK3_SUPPORT 995 if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port) && 996 BCM_SUCCESS(rv)) 997 { 998 bcm_port_resource_t pr; 999 BCM_IF_ERROR_RETURN(bcm_port_resource_get(unit, port, &pr)); 1000 if (pr.speed != speed) { 1001 LOG_ERROR(BSL_LS_BCM_PORT, 1002 (BSL_META_U(unit, 1003 "port speed (%d) does NOT match " 1004 " current speed (%d).\n"), 1005 pr.speed, speed)); 1006 } 1007 pr.speed = speed; 1008 BCM_IF_ERROR_RETURN(bcm_port_resource_speed_set(unit, port, &pr)); 1009 } 1010 else 1011 #endif 1012 { 1013 if (BCM_SUCCESS(rv)) 1014 { 1015 rv = bcm_port_speed_set(unit, port, speed); 1016 RP_CHK(rv, bcm_port_speed_set); 1017 } 1018 } 1019 } 1020 1021 if (BCM_SUCCESS(rv)) { 1022 #if defined(BCM_ESW_SUPPORT) || defined(BCM_FE2000_SUPPORT) 1023 if (SOC_IS_HELIX4(unit)) { 1024 rv = bcm_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_PHY); 1025 } else { 1026 rv = bcm_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_MAC); 1027 } 1028 #endif /* BCM_ESW_SUPPORT || defined(BCM_FE2000_SUPPORT) */ 1029 RP_CHK(rv, bcm_port_loopback_set); 1030 } 1031 if (BCM_SUCCESS(rv)) { 1032 rv = bcm_port_pause_set(unit, port, 0, 0); 1033 RP_CHK(rv, bcm_port_pause_set); 1034 } 1035 } 1036 1037 if ((got_port = BCM_SUCCESS(rv))) { 1038 p->p_port[port_idx++] = port; 1039 1040 if (port_idx >= p->p_num_test_ports) { 1041 break; 1042 } 1043 got_port = BCM_E_NOT_FOUND; 1044 } 1045 } 1046 1047 if (!got_port) { 1048 test_error(unit, "Unable to find suitable XE/GE port.\n"); 1049 return -1; 1050 } 1051 1052 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT) 1053 if (SOC_IS_ARAD(unit) || SOC_IS_DNX(unit)) 1054 { 1055 /* Disable all other ports */ 1056 rv = rp_dune_port_enable_set(unit, p, FALSE); 1057 RP_CHK(rv, rp_dune_port_enable_set); 1058 } 1059 else 1060 #endif 1061 { 1062 /* Disable all other ports (can run with active links plugged in) */ 1063 BCM_PBMP_ASSIGN(tmp_pbmp, PBMP_E_ALL(unit)); 1064 1065 /* Remove CPU port, it's not real ports for phy driver */ 1066 BCM_PBMP_REMOVE(tmp_pbmp, PBMP_CMIC(unit)); 1067 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1068 BCM_PBMP_PORT_REMOVE(tmp_pbmp, p->p_port[port_idx]); 1069 } 1070 1071 PBMP_ITER(tmp_pbmp, port) { 1072 rv = bcm_port_enable_set(unit, port, FALSE); 1073 RP_CHK(rv, bcm_port_enable_set); 1074 } 1075 } 1076 1077 #if defined(BCM_FIELD_SUPPORT) 1078 if (soc_feature(unit, soc_feature_field)) { 1079 if (SOC_IS_ESW(unit)) { 1080 #if defined(BCM_ESW_SUPPORT) || defined(BCM_FE2000_SUPPORT) 1081 bcm_field_qset_t qset; 1082 bcm_field_group_t fg; 1083 bcm_field_entry_t fent[2]; 1084 int stat_id = -1; 1085 bcm_field_stat_t stat_type = bcmFieldStatPackets; 1086 1087 BCM_FIELD_QSET_INIT(qset); 1088 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyInPort); 1089 1090 rv = bcm_field_group_create(unit, qset, BCM_FIELD_GROUP_PRIO_ANY, &fg); 1091 1092 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1093 if (BCM_SUCCESS(rv)) { 1094 rv = bcm_field_entry_create(unit, fg, &fent[port_idx]); 1095 } 1096 1097 if (BCM_SUCCESS(rv)) { 1098 p->p_field_entry[port_idx] = fent[port_idx]; 1099 1100 rv = bcm_field_qualify_InPort(unit, fent[port_idx], 1101 p->p_port[port_idx], 1102 BCM_FIELD_EXACT_MATCH_MASK); 1103 } 1104 } 1105 1106 if (BCM_SUCCESS(rv)) { 1107 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1108 rv = bcm_field_stat_create(unit, fg, 1, &stat_type, &stat_id); 1109 RP_CHK(rv, bcm_field_stat_create); 1110 1111 rv = bcm_field_entry_stat_attach(unit, fent[port_idx], stat_id); 1112 RP_CHK(rv, bcm_field_entry_stat_attach); 1113 stat_id = -1; 1114 } 1115 } 1116 1117 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1118 if (p->p_use_fp_action) { 1119 if (port_idx == 1) { 1120 if (BCM_SUCCESS(rv)) { 1121 rv = bcm_field_action_add(unit, fent[port_idx], 1122 bcmFieldActionCopyToCpu, 1123 0, 0); 1124 RP_CHK(rv, bcm_field_action_add); 1125 } 1126 #ifdef BCM_TOMAHAWK_SUPPORT 1127 if (SOC_IS_TOMAHAWKX(unit) && BCM_SUCCESS(rv)) { 1128 rv = bcm_field_action_add(unit, fent[port_idx], 1129 bcmFieldActionDrop, 1130 0, 0); 1131 RP_CHK(rv, bcm_field_action_add); 1132 } 1133 #endif /* BCM_TOMAHAWK_SUPPORT */ 1134 } 1135 } else { 1136 if (BCM_SUCCESS(rv)) { 1137 rv = bcm_field_action_add(unit, fent[port_idx], 1138 bcmFieldActionCopyToCpu, 1139 0, 0); 1140 RP_CHK(rv, bcm_field_action_add); 1141 } 1142 } 1143 if (BCM_SUCCESS(rv)) { 1144 1145 int port = p->p_port[port_idx]; 1146 if (p->p_use_fp_action) { 1147 if (port_idx == 0) { 1148 rv = bcm_field_action_add(unit, fent[port_idx], 1149 bcmFieldActionRedirect, 1150 0, port); 1151 RP_CHK(rv, bcm_field_action_add); 1152 1153 rv = bcm_field_action_add(unit, fent[port_idx], 1154 bcmFieldActionMirrorEgress, 1155 0, p->p_port[1]); 1156 RP_CHK(rv, bcm_field_action_add); 1157 1158 } 1159 } else { 1160 rv = bcm_field_action_add(unit, fent[port_idx], 1161 bcmFieldActionRedirect, 1162 0, port); 1163 RP_CHK(rv, bcm_field_action_add); 1164 } 1165 } 1166 } 1167 #endif /* BCM_ESW_SUPPORT || BCM_FE2000_SUPPORT */ 1168 } else { 1169 } 1170 } 1171 1172 #endif /* BCM_FIELD_SUPPORT */ 1173 if (BCM_FAILURE(rv)) { 1174 test_error(unit, "Unable to configure filter: %s\n", bcm_errmsg(rv)); 1175 return -1; 1176 } 1177 1178 #ifdef BCM_DNX_SUPPORT 1179 if (SOC_IS_DNX(unit)) 1180 { 1181 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1182 /* coverity [returned_value] */ 1183 rv = bcm_port_learn_set(unit, p->p_port[port_idx], BCM_PORT_LEARN_FWD); 1184 RP_CHK(rv, bcm_port_learn_set); 1185 } 1186 } 1187 else 1188 #endif 1189 { 1190 /* Disable learning on that port */ 1191 #ifdef BCM_PETRA_SUPPORT 1192 if ((SOC_IS_ARAD(unit) && SOC_DPP_PP_ENABLE(unit)) || (!SOC_IS_ARAD(unit))) 1193 #endif 1194 { 1195 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1196 /* coverity [returned_value] */ 1197 rv = bcm_port_learn_set(unit, p->p_port[port_idx], BCM_PORT_LEARN_FWD); 1198 RP_CHK(rv, bcm_port_learn_set); 1199 } 1200 } 1201 } 1202 1203 /* Create Maximum size packet requested */ 1204 BCM_IF_ERROR_RETURN(bcm_pkt_alloc(p->p_txrx_unit , p->p_l_end, 0, &(p->p_pkt))); 1205 if (p->p_pkt == NULL) { 1206 test_error(unit, "Failed to allocate Tx packet\n"); 1207 return -1; 1208 } 1209 1210 p->p_pkt->flags = BCM_TX_CRC_REGEN; 1211 1212 #ifdef BCM_PETRA_SUPPORT 1213 if (SOC_IS_ARAD(unit)) 1214 { 1215 rv = rp_dune_get_ssp_and_cpu_channel(unit, p->p_pkt, p); 1216 RP_CHK(rv, rp_dune_get_ssp_and_cpu_channel); 1217 1218 p->p_pkt->flags |= BCM_TX_CRC_APPEND; 1219 1220 /* Fill in buffer */ 1221 SOC_DPP_PKT_PTCH_HDR_SET(p->p_pkt, rp_ptch_header); 1222 SOC_DPP_PKT_HDR_DMAC_SET_WITH_PTCH(p->p_pkt, rp_mac_dest); 1223 SOC_DPP_PKT_HDR_SMAC_SET_WITH_PTCH(p->p_pkt, rp_mac_src); 1224 SOC_DPP_PKT_HDR_TPID_SET_WITH_PTCH(p->p_pkt, ENET_DEFAULT_TPID); 1225 SOC_DPP_PKT_HDR_VTAG_CONTROL_SET_WITH_PTCH(p->p_pkt, VLAN_CTRL(0, 0, 1)); 1226 /* Fill address starts at PTCH(2) + DMAC(6) + SMAC(6) + VTAG(4) */ 1227 fill_addr = BCM_PKT_DMAC(p->p_pkt) + 2 + 6 + 6 + 4; 1228 1229 sal_memcpy(fill_addr, mypacket, p->p_l_end - (fill_addr - BCM_PKT_DMAC(p->p_pkt))); 1230 } 1231 else 1232 #endif 1233 #ifdef BCM_DNX_SUPPORT 1234 if (SOC_IS_DNX(unit)) { 1235 rv = rp_dune_get_ssp_and_cpu_channel(unit, p->p_pkt, p); 1236 RP_CHK(rv, rp_dune_get_ssp_and_cpu_channel); 1237 1238 /** Disable visibility resume which lower down PPS/BPS */ 1239 p->p_pkt->flags |= BCM_TX_NO_VISIBILITY_RESUME; 1240 1241 /* Fill in buffer */ 1242 RP_DNX_PKT_MH_HDR_SET(p->p_pkt, rp_mh_header); 1243 RP_DNX_PKT_PTCH_HDR_SET_WITH_MH(p->p_pkt, rp_ptch_header); 1244 RP_DNX_PKT_HDR_DMAC_SET_WITH_MH_PTCH(p->p_pkt, rp_mac_dest); 1245 RP_DNX_PKT_HDR_SMAC_SET_WITH_MH_PTCH(p->p_pkt, rp_mac_src); 1246 RP_DNX_PKT_HDR_TPID_SET_WITH_MH_PTCH(p->p_pkt, ENET_DEFAULT_TPID); 1247 RP_DNX_PKT_HDR_VTAG_CONTROL_SET_WITH_MH_PTCH(p->p_pkt, VLAN_CTRL(0, 0, 1)); 1248 /* Fill address starts at MH(16) + PTCH(2) + DMAC(6) + SMAC(6) + VTAG(4) */ 1249 fill_addr = BCM_PKT_DMAC(p->p_pkt) + DNX_MODULE_HEADER_SIZE + RP_DNX_HDR_PTCH_TYPE2_LEN + RP_DNX_MAC_ADDR_LEN + RP_DNX_MAC_ADDR_LEN + sizeof(uint32); 1250 sal_memcpy(fill_addr, mypacket, p->p_l_end - (fill_addr - BCM_PKT_DMAC(p->p_pkt))); 1251 } 1252 else 1253 #endif 1254 { 1255 /* Fill in buffer */ 1256 BCM_PKT_HDR_DMAC_SET(p->p_pkt, rp_mac_dest); 1257 BCM_PKT_HDR_SMAC_SET(p->p_pkt, rp_mac_src); 1258 BCM_PKT_HDR_TPID_SET(p->p_pkt, ENET_DEFAULT_TPID); 1259 BCM_PKT_HDR_VTAG_CONTROL_SET(p->p_pkt, VLAN_CTRL(0, 0, 1)); 1260 /* Fill address starts 2 * MAC + TPID + VTAG */ 1261 fill_addr = BCM_PKT_DMAC(p->p_pkt) + 6 + 6 + 2 + 2; 1262 sal_memset(fill_addr, 0xff, p->p_l_end - 1263 (fill_addr - BCM_PKT_DMAC(p->p_pkt))); 1264 } 1265 1266 /* Set the dest port for the packet 1267 * For all devices, the packet will target the first port 1268 */ 1269 BCM_PKT_PORT_SET(p->p_pkt, p->p_port[0], FALSE, FALSE); 1270 p->p_pkt->dest_mod = txrx_modid; 1271 p->p_pkt->opcode = BCM_PKT_OPCODE_UC; 1272 1273 /* Set up the proper configuration */ 1274 rv = rpacket_receiver_activate(p->p_txrx_unit, p); 1275 if (!BCM_SUCCESS(rv)) { 1276 test_error(unit, "Could not setup receiver\n"); 1277 return -1; 1278 } 1279 1280 return 0; 1281 } 1282 1283 /* 1284 * Function: 1285 * rpacket_storm_start 1286 * Purpose: 1287 * Start packet storm in switch to serve as packet generator 1288 * Parameters: 1289 * u - unit #. 1290 * p - pointer to test parameters 1291 * l - length of packet to send 1292 * Returns: 1293 * 0 on success, -1 on failure 1294 * Notes: 1295 */ 1296 1297 int 1298 rpacket_storm_start (int unit, p_t *p, int l) 1299 { 1300 int rv = 0; 1301 int tx_pkt_idx; 1302 int tx_pkt_cnt = 1; 1303 1304 #if defined(BCM_FIELD_SUPPORT) 1305 if (soc_feature(unit, soc_feature_field)) { 1306 int port_idx = 0; 1307 if (SOC_IS_ESW(unit)) { 1308 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1309 rv = bcm_field_entry_install(unit, p->p_field_entry[port_idx]); 1310 RP_CHK(rv, bcm_field_entry_install); 1311 } 1312 } else { 1313 } 1314 } 1315 #endif 1316 1317 if (BCM_FAILURE(rv)) { 1318 test_error(unit, "Unable to install filter: %s\n", bcm_errmsg(rv)); 1319 return rv; 1320 } 1321 1322 /* determine num packets needed to test this architecture */ 1323 1324 /* set up test ports */ 1325 1326 /* Send packet(s) to kick off packet storm */ 1327 #ifdef BCM_PETRA_SUPPORT 1328 if (SOC_IS_ARAD(unit)) 1329 { 1330 /** include 2 bytes PTCH */ 1331 BCM_PKT_TX_LEN_SET(p->p_pkt, (l + 2)); 1332 } 1333 else 1334 #endif 1335 #ifdef BCM_DNX_SUPPORT 1336 if (SOC_IS_DNX(unit)) 1337 { 1338 /** exclude 16bytes MH and 2 bytes PTCH */ 1339 BCM_PKT_TX_LEN_SET(p->p_pkt, (l + DNX_MODULE_HEADER_SIZE + 2)); 1340 } 1341 else 1342 #endif 1343 { 1344 BCM_PKT_TX_LEN_SET(p->p_pkt, l); 1345 } 1346 #ifdef BCM_PETRA_SUPPORT 1347 if (SOC_IS_ARAD(unit)) { 1348 int port_idx; 1349 SOC_DPP_PKT_HDR_TAGGED_LEN_SET_WITH_PTCH(p->p_pkt, l); /* Set length */ 1350 if (SOC_IS_ARADPLUS_AND_BELOW(unit)) { 1351 uint32 reg_val = 0; 1352 READ_IPT_FORCE_LOCAL_OR_FABRICr(unit, ®_val); 1353 is_force_fabric = soc_reg_field_get(unit, IPT_FORCE_LOCAL_OR_FABRICr, reg_val, FORCE_FABRICf); 1354 is_force_local = soc_reg_field_get(unit, IPT_FORCE_LOCAL_OR_FABRICr, reg_val, FORCE_LOCALf); 1355 soc_reg_field_set(unit, IPT_FORCE_LOCAL_OR_FABRICr, ®_val, FORCE_FABRICf, 0); 1356 soc_reg_field_set(unit, IPT_FORCE_LOCAL_OR_FABRICr, ®_val, FORCE_LOCALf, 1); 1357 WRITE_IPT_FORCE_LOCAL_OR_FABRICr(unit, reg_val); 1358 } 1359 /** Set Loopback to make packet storm */ 1360 for (port_idx = 0; port_idx < p->p_num_test_ports; port_idx++) 1361 { 1362 rv = bcm_port_loopback_set(unit, p->p_port[port_idx], BCM_PORT_LOOPBACK_MAC); 1363 RP_CHK(rv, bcm_port_loopback_set); 1364 } 1365 } 1366 else 1367 #endif 1368 #ifdef BCM_DNX_SUPPORT 1369 if (SOC_IS_DNX(unit)) { 1370 int port_idx; 1371 /** Set Loopback to make packet storm */ 1372 for (port_idx = 0; port_idx < p->p_num_test_ports; port_idx++) 1373 { 1374 rv = bcm_port_loopback_set(unit, p->p_port[port_idx], BCM_PORT_LOOPBACK_MAC); 1375 RP_CHK(rv, bcm_port_loopback_set); 1376 } 1377 } 1378 else 1379 #endif 1380 { 1381 BCM_PKT_HDR_TAGGED_LEN_SET(p->p_pkt, l); /* Set length */ 1382 } 1383 1384 for (tx_pkt_idx = 0; tx_pkt_idx < tx_pkt_cnt; tx_pkt_idx++) { 1385 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1386 if (SOC_KNET_MODE(unit) && p->p_use_socket_send) { 1387 rv = send (p->p_sock, p->p_pkt->_pkt_data.data, l, 0); 1388 if (rv < 0) { 1389 cli_out("Send to socket %d returned len %d errno %d\n", 1390 p->p_sock, rv, errno); 1391 rv = BCM_E_FAIL; 1392 } 1393 } else 1394 #endif 1395 { 1396 rv = bcm_tx(p->p_txrx_unit, p->p_pkt, NULL); 1397 } 1398 } 1399 1400 return rv; 1401 } /* rpacket_storm_start */ 1402 1403 /* 1404 * Function: 1405 * rpacket_storm_stop 1406 * Purpose: 1407 * Stop packet storm; clear out remaining packets 1408 * Parameters: 1409 * u - unit #. 1410 * p - pointer to test parameters 1411 * Returns: 1412 * 0 on success, -1 on failure 1413 * Notes: 1414 */ 1415 int 1416 rpacket_storm_stop (int unit, p_t *p) 1417 { 1418 int rv = 0; 1419 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT) 1420 int port_index; 1421 #endif 1422 1423 /* 1424 * Stop the packets from flowing. 1425 */ 1426 #if defined(BCM_FIELD_SUPPORT) 1427 if (soc_feature(unit, soc_feature_field)) { 1428 int port_idx = 0; 1429 if (SOC_IS_ESW(unit)) { 1430 for (port_idx=0; port_idx < p->p_num_test_ports; port_idx++) { 1431 rv = bcm_field_entry_remove(unit, p->p_field_entry[port_idx]); 1432 RP_CHK(rv, bcm_field_entry_remove); 1433 } 1434 } else { 1435 } 1436 } 1437 #endif 1438 if (BCM_FAILURE(rv)) { 1439 test_error(unit, "Unable to remove filter: %s\n", bcm_errmsg(rv)); 1440 return rv; 1441 } 1442 1443 #ifdef BCM_PETRA_SUPPORT 1444 if (SOC_IS_ARADPLUS_AND_BELOW(unit)) { 1445 uint32 reg_val = 0; 1446 READ_IPT_FORCE_LOCAL_OR_FABRICr(unit, ®_val); 1447 soc_reg_field_set(unit, IPT_FORCE_LOCAL_OR_FABRICr, ®_val, FORCE_FABRICf, is_force_fabric); 1448 soc_reg_field_set(unit, IPT_FORCE_LOCAL_OR_FABRICr, ®_val, FORCE_LOCALf, is_force_local); 1449 WRITE_IPT_FORCE_LOCAL_OR_FABRICr(unit, reg_val); 1450 } 1451 /** Clear Loopback to stop packet storm */ 1452 for (port_index = 0; port_index < p->p_num_test_ports; port_index++) 1453 { 1454 rv = bcm_port_loopback_set(unit, p->p_port[port_index], BCM_PORT_LOOPBACK_NONE); 1455 RP_CHK(rv, bcm_port_loopback_set); 1456 } 1457 #endif 1458 #ifdef BCM_DNX_SUPPORT 1459 if (SOC_IS_DNX(unit)) { 1460 /** Clear Loopback to stop packet storm */ 1461 for (port_index = 0; port_index < p->p_num_test_ports; port_index++) 1462 { 1463 rv = bcm_port_loopback_set(unit, p->p_port[port_index], BCM_PORT_LOOPBACK_NONE); 1464 RP_CHK(rv, bcm_port_loopback_set); 1465 } 1466 } 1467 #endif 1468 1469 return rv; 1470 } /* rpacket_storm_stop */ 1471 1472 /* 1473 * Function: 1474 * rpacket_test 1475 * Purpose: 1476 * Test packet reception interface. 1477 * Parameters: 1478 * u - unit #. 1479 * a - pointer to arguments. 1480 * pa - ignored cookie. 1481 * Returns: 1482 * 0 on success, -1 on failure 1483 * Notes: 1484 * There remains an issue when stealing packets that the 1485 * system will crash when the rate is high enough. This has 1486 * been experimentally determined to be between 4-5K pkts/sec 1487 * on Mousse (8240) and 6-7K pkts/sec on BMW (8245). 1488 */ 1489 1490 int 1491 rpacket_test(int unit, args_t *a, void *pa) 1492 { 1493 p_t *p = (p_t *)pa; 1494 int l, rv = BCM_E_UNAVAIL; 1495 int test_rv = 0; 1496 int use_socket = 0; 1497 int ringbuf_size = 0; 1498 sal_cpu_stats_t cpu_start; 1499 sal_cpu_stats_t cpu_end; 1500 1501 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1502 long unsigned int knet_pkt=0; 1503 long unsigned int knet_ic =0; 1504 #endif 1505 soc_control_t *soc = SOC_CONTROL(unit); 1506 int desc_intr_count = 0; 1507 int chain_intr_count = 0; 1508 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1509 if (SOC_KNET_MODE(unit)) { 1510 use_socket = p->p_use_socket; 1511 ringbuf_size = p->p_ringbuf_size ; 1512 } 1513 #endif 1514 /* coverity[dead_error_condition] */ 1515 cli_out("\n" 1516 "Rate: %d/%d (%s). %s %s. %s %d PPC. Packets%s freed.\n", 1517 p->p_pkts_per_sec, 1518 p->p_burst, 1519 p->p_hw_rate ? "HW" : "SW", 1520 "IF:", 1521 use_socket ? 1522 (ringbuf_size ? "ring" : "socket") : 1523 "bcm_rx", 1524 (use_socket) ? "" : ((p->p_intr_cb) ? "Intr CB." : "Task CB."), 1525 p->p_rx_cfg.pkts_per_chain, 1526 p->p_free_buffer ? "" : " not" 1527 ); 1528 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1529 if (SOC_KNET_MODE(unit)) { 1530 cli_out("\n" 1531 " Packet | Rate | Total | | CPU %% | Knet tot Knet Rate |\n" 1532 " Len | Pkt/s | MB/s | packets | Time | Idle /user /kern | packets | Pkt/s |Interrupts\n" 1533 " --------+-----------+-------------+-----------+---------+-------------------+----------+----------+----------\n"); 1534 } else 1535 #endif 1536 { 1537 cli_out("\n" 1538 " Packet | Rate | Total | | CPU %% | Interrupts\n" 1539 " Len | Pkt/s | MB/s | packets | Time | Idle /user /kern | Desc_Intr|Chain_Intr\n" 1540 " --------+-----------+-------------+-----------+---------+-------------------+----------+----------\n"); 1541 } 1542 1543 if (!use_socket) { 1544 /* Register the callback handler */ 1545 rv = rpacket_register(p->p_txrx_unit, p); 1546 if (BCM_FAILURE(rv)) { 1547 test_error(unit, "Unable to register handler, %s\n", 1548 bcm_errmsg(rv)); 1549 test_rv = -1; 1550 goto done; 1551 } 1552 } 1553 1554 for (l = p->p_l_start; l <= p->p_l_end; l += p->p_l_inc) { 1555 1556 if (SOC_IS_KATANA(unit) && p->p_hw_rate) { 1557 bcm_port_rate_egress_set(unit, CMIC_PORT(unit), 1558 p->p_pkts_per_sec * l / 125, p->p_burst * l /125); 1559 } 1560 1561 rv = rpacket_storm_start (unit, p, l); 1562 if (BCM_FAILURE(rv)) { 1563 test_error(unit, "Failed to start packet storm: %s\n", bcm_errmsg(rv)); 1564 test_rv = -1; 1565 goto done; 1566 } 1567 1568 /* Start clean */ 1569 p->p_received = 0; 1570 p->p_drained = 0; 1571 p->p_time_us = 0; 1572 p->p_error_num = 0; 1573 1574 /* measure rx packets over known interval*/ 1575 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1576 if (SOC_KNET_MODE(unit)) { 1577 knet_stats_clear(); 1578 } 1579 #endif 1580 sal_cpu_stats_get (&cpu_start); 1581 desc_intr_count = soc->stat.intr_desc; 1582 chain_intr_count = soc->stat.intr_chain; 1583 p->p_count_packets = TRUE; 1584 sal_sleep(p->p_time); 1585 p->p_count_packets = FALSE; 1586 desc_intr_count = soc->stat.intr_desc - desc_intr_count; 1587 chain_intr_count = soc->stat.intr_chain - chain_intr_count; 1588 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1589 if (SOC_KNET_MODE(unit)) { 1590 knet_stats_get(&knet_ic, &knet_pkt); 1591 } 1592 #endif 1593 sal_cpu_stats_get (&cpu_end); 1594 1595 rv = rpacket_storm_stop (unit, p); 1596 if (BCM_FAILURE(rv)) { 1597 test_error(unit, "Failed to stop packet storm: %s\n", bcm_errmsg(rv)); 1598 test_rv = -1; 1599 goto done; 1600 } 1601 1602 /* display test results */ 1603 { 1604 int td, bps, pps, idle, user,kernel ; 1605 int idle_diff, user_diff, kernel_diff, total_diff; 1606 1607 td = (p->p_time_us + 500UL) / 1000UL; /* round to ms */ 1608 if (td == 0) { /* avoid divide by zero */ 1609 td = 1; 1610 } 1611 if (p->p_received == 0) { 1612 pps = bps = 0; 1613 } else { 1614 pps = (1000UL * p->p_received) / td; 1615 bps = (p->p_received * l) / td; 1616 } 1617 1618 COMPILER_64_SUB_64(cpu_end.total, cpu_start.total); 1619 total_diff = (int)(u64_L(cpu_end.total)); 1620 COMPILER_64_SUB_64(cpu_end.idle, cpu_start.idle); 1621 idle_diff = (int)(u64_L(cpu_end.idle)); 1622 COMPILER_64_SUB_64(cpu_end.user, cpu_start.user); 1623 user_diff = (int)(u64_L(cpu_end.user)); 1624 COMPILER_64_SUB_64(cpu_end.kernel, cpu_start.kernel); 1625 kernel_diff = (int)(u64_L(cpu_end.kernel)); 1626 1627 if (total_diff != 0) { 1628 idle = idle_diff * 10000UL / total_diff; 1629 user = user_diff * 10000UL / total_diff; 1630 kernel = kernel_diff * 10000UL / total_diff; 1631 } else { 1632 idle = 0; 1633 user = 0; 1634 kernel = 0; 1635 } 1636 1637 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1638 if (SOC_KNET_MODE(unit)) { 1639 cli_out(" %5u | %8u | %5u.%03u | %8u | %3u.%03u | %2u.%02u/%2u.%02u/%2u.%02u | %8lu | %8u | %8lu ", 1640 l, 1641 (int)pps, 1642 (int)(bps / 1000), (int)(bps % 1000), 1643 p->p_received, 1644 td / 1000, td % 1000, 1645 idle / 100, idle % 100, 1646 user / 100, user % 100, 1647 kernel / 100, kernel % 100, 1648 knet_pkt, (td < p->p_time*1000) ? (int)(knet_pkt/p->p_time): (int)((knet_pkt * 1000) / td), knet_ic); 1649 } else 1650 #endif 1651 { 1652 cli_out(" %5u | %8u | %5u.%03u | %8u | %3u.%03u | %2u.%02u/%2u.%02u/%2u.%02u | %8u | %8u ", 1653 l, 1654 (int)pps, 1655 (int)(bps / 1000), (int)(bps % 1000), 1656 p->p_received, 1657 td / 1000, td % 1000, 1658 idle / 100, idle % 100, 1659 user / 100, user % 100, 1660 kernel / 100, kernel % 100, 1661 desc_intr_count, chain_intr_count); 1662 } 1663 1664 if (p->p_error_num > 0) { 1665 cli_out(" e:%d \n", p->p_error_num); 1666 } else { 1667 cli_out("\n"); 1668 } 1669 } 1670 /* Sleep a bit to let current backlog of packets drain */ 1671 sal_sleep(2); 1672 1673 } 1674 1675 if (!use_socket) { 1676 /* Unregister the handler, let discard take over */ 1677 rv = rpacket_unregister(p->p_txrx_unit, p); 1678 if (BCM_FAILURE(rv)) { 1679 test_error(unit, "Unable to unregister handler, %s\n", 1680 bcm_errmsg(rv)); 1681 test_rv = -1; 1682 goto done; 1683 } 1684 } 1685 1686 done: 1687 if (p->p_dump_rx) { 1688 #ifdef BROADCOM_DEBUG 1689 bcm_rx_show(unit); 1690 #endif /* BROADCOM_DEBUG */ 1691 } 1692 return test_rv; 1693 } 1694 1695 1696 STATIC int 1697 rpacket_receiver_deactivate(int unit, p_t *p) 1698 { 1699 #ifdef BCM_DNX_SUPPORT 1700 int rv; 1701 if(SOC_IS_DNX(unit)) { 1702 if (bcm_rx_active(unit)) { 1703 cli_out("Stopping active RX.\n"); 1704 rv = bcm_rx_stop(unit, NULL); 1705 if (!BCM_SUCCESS(rv)) { 1706 cli_out("Unable to stop RX: %s\n", bcm_errmsg(rv)); 1707 return -1; 1708 } 1709 } 1710 1711 rv = dnx_rx_appl_active(unit); 1712 if (!BCM_SUCCESS(rv)) { 1713 cli_out("Unable to active RX: %s\n", bcm_errmsg(rv)); 1714 return -1; 1715 } 1716 } 1717 #endif 1718 return 0; 1719 } 1720 1721 1722 1723 /*ARGSUSED*/ 1724 int 1725 rpacket_done(int unit, void *pa) 1726 /* 1727 * Function: rpacket_done 1728 * Purpose: Clean up after rpacket test. 1729 * Parameters: unit - unit # 1730 * pa - cookie (as returned by rpacket_init(); 1731 * Returns: 0 - OK 1732 * -1 - failed 1733 */ 1734 { 1735 p_t *p = p_control[unit]; 1736 int rv; 1737 int port_idx; 1738 1739 if (p == NULL) { 1740 return 0; 1741 } 1742 1743 if (p->p_pkt != NULL) { 1744 bcm_pkt_free(unit, p->p_pkt); 1745 p->p_pkt = NULL; 1746 } 1747 1748 rv = rpacket_receiver_deactivate(p->p_txrx_unit, p); 1749 if (BCM_FAILURE(rv)) { 1750 test_error(unit, "Unable to deactivate receiver.\n"); 1751 return -1; 1752 } 1753 1754 #ifdef BCM_DNX_SUPPORT 1755 if (SOC_IS_DNX(unit)) 1756 { 1757 /* Restore port */ 1758 for (port_idx = 0; port_idx < p->p_num_test_ports; port_idx++) 1759 { 1760 rv = bcm_port_linkscan_set(unit, p->p_port[port_idx], p->p_port_info[port_idx].linkscan); 1761 RP_CHK(rv, bcm_port_loopback_set); 1762 rv = bcm_port_loopback_set(unit, p->p_port[port_idx], p->p_port_info[port_idx].loopback); 1763 RP_CHK(rv, bcm_port_loopback_set); 1764 } 1765 1766 /* Enable all other ports */ 1767 rv = rp_dune_port_enable_set(unit, p, TRUE); 1768 RP_CHK(rv, rp_dune_port_enable_set); 1769 } 1770 else 1771 #endif 1772 #ifdef BCM_PETRA_SUPPORT 1773 if (SOC_IS_JERICHO(unit)) 1774 { 1775 int ms; 1776 /* Restore port */ 1777 for (port_idx = 0; port_idx < p->p_num_test_ports; port_idx++) { 1778 /* If the Master mode is not changed, remove phy_master attributes from action_mask */ 1779 ms = 0; 1780 if ((rv = bcm_port_master_get(unit, p->p_port[port_idx], &ms)) != BCM_E_NONE) { 1781 cli_out("rpacket_done: port %s: could not get port Master mode: %s\n", 1782 SOC_PORT_NAME(unit, p->p_port[port_idx]), 1783 bcm_errmsg(rv)); 1784 return -1; 1785 } 1786 if (ms == p->p_port_info[port_idx].phy_master) { 1787 p->p_port_info[port_idx].action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 1788 } 1789 1790 rv = bcm_port_info_restore(unit, p->p_port[port_idx], 1791 &p->p_port_info[port_idx]); 1792 if (BCM_FAILURE(rv)) { 1793 test_error(unit, "Unable to restore port %d: %s\n", 1794 p->p_port[port_idx], bcm_errmsg(rv)); 1795 return -1; 1796 } 1797 } 1798 /* Enable all other ports */ 1799 rv = rp_dune_port_enable_set(unit, p, TRUE); 1800 RP_CHK(rv, rp_dune_port_enable_set); 1801 } 1802 else if (SOC_IS_ARADPLUS_AND_BELOW(unit)) 1803 { 1804 /* Restore port */ 1805 for (port_idx = 0; port_idx < p->p_num_test_ports; port_idx++) 1806 { 1807 rv = bcm_port_info_restore(unit, p->p_port[port_idx], 1808 &p->p_port_info[port_idx]); 1809 if (BCM_FAILURE(rv)) { 1810 test_error(unit, "Unable to restore port %d: %s\n", 1811 p->p_port[port_idx], bcm_errmsg(rv)); 1812 return -1; 1813 } 1814 } 1815 /* Enable all other ports */ 1816 rv = rp_dune_port_enable_set(unit, p, TRUE); 1817 RP_CHK(rv, rp_dune_port_enable_set); 1818 } 1819 else 1820 #endif 1821 { 1822 int ms; 1823 /* Restore port */ 1824 for (port_idx = 0; port_idx < p->p_num_test_ports; port_idx++) { 1825 /* If the Master mode is not changed, remove phy_master attributes from action_mask */ 1826 ms = 0; 1827 if ((rv = bcm_port_master_get(unit, p->p_port[port_idx], &ms)) != BCM_E_NONE) { 1828 cli_out("rpacket_done: port %s: could not get port Master mode: %s\n", 1829 SOC_PORT_NAME(unit, p->p_port[port_idx]), 1830 bcm_errmsg(rv)); 1831 return -1; 1832 } 1833 if (ms == p->p_port_info[port_idx].phy_master) { 1834 p->p_port_info[port_idx].action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 1835 } 1836 1837 rv = bcm_port_info_restore(unit, p->p_port[port_idx], 1838 &p->p_port_info[port_idx]); 1839 if (BCM_FAILURE(rv)) { 1840 test_error(unit, "Unable to restore port %d: %s\n", 1841 p->p_port[port_idx], bcm_errmsg(rv)); 1842 return -1; 1843 } 1844 } 1845 1846 } 1847 1848 /* 1849 * Try to remove filter, ignore error since we don't know how far 1850 * we got in initialization. 1851 */ 1852 #if defined(BCM_FIELD_SUPPORT) 1853 if (soc_feature(unit, soc_feature_field)) { 1854 int i = 0; 1855 if (SOC_IS_ESW(unit)) { 1856 for (i = 0; i < p->p_num_test_ports; i++) { 1857 rv = bcm_field_entry_remove(unit, p->p_field_entry[i]); 1858 RP_CHK(rv, bcm_field_entry_remove); 1859 rv = bcm_field_entry_destroy(unit, p->p_field_entry[i]); 1860 RP_CHK(rv, bcm_field_entry_destroy); 1861 } 1862 } else { 1863 } 1864 } 1865 #endif 1866 1867 1868 /* 1869 * Don't free the p_control entry, 1870 * keep it around to save argument state 1871 */ 1872 1873 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1874 if (SOC_KNET_MODE(unit)) { 1875 knetif_clean(unit, p); 1876 } 1877 #endif 1878 return 0; 1879 } 1880 1881 char rpacket_usage[] = 1882 "Receive Packet Test Usage:\n" 1883 #ifndef COMPILER_STRING_CONST_LIMIT 1884 " Time=<value> : Specify the test duration for each packet length. (default=2)\n" 1885 " LengthStart=<value> : Specify the start pakcet length. (default=64)\n" 1886 " LengthEnd=<value> : Specify the end pakcet length. (default=1522)\n" 1887 " LengthInc=<value> : Specify the increasing step of pakcet length. (default=64)\n" 1888 " FreeBuffer=<value> : Indicate if packet buffer will be freed. (default=FALSE)\n" 1889 " QLen=<value> : Specify Max number of packets permitted in cos queue. (default=200)\n" 1890 " PERCos=<value> : Indicate if test is running with per-cos settings. (default=FALSE)\n" 1891 " Rate=<value> : Specify packets per second for a cos queue. (default=0)\n" 1892 " Burst=<value> : Specify packets to be received in a single burst. (default=100)\n" 1893 " HWrate=<value> : Indicate if hw rate limiting is used. (default=FALSE)\n" 1894 " PktsPerChain=<value> : Specify number of packets per DMA chain. (default=16)\n" 1895 " Chains=<value> : Specify number of chains (DVs) set up.. (default=4)\n" 1896 " useINTR=<value> : Indicate if packets are received in interrupt context. (default=TRUE)\n" 1897 " DumpRX=<value> : Indicate if to show packet rx setting information. (default=FALSE)\n" 1898 " RxMode=<value> : Indicate if rx mode is set via flags (parse received packets). (default=FALSE)\n" 1899 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1900 " SOCKet=<value> : Indicate if socket is used for packet rx. (default=FALSE)\n" 1901 " RingBuf=<value> : Specify ring buffer size for socket. (default=0)\n" 1902 " SocketTx=<value> : Indicate if socket is used for packet tx. (default=FALSE)\n" 1903 #endif 1904 #endif 1905 ; 1906 1907 /* 1908 * Function: 1909 * rpacket_init 1910 * Purpose: 1911 * Initialize the rpacket test. 1912 * Parameters: 1913 * u - unit # 1914 * a - pointer to args 1915 * pa - Pointer to cookie 1916 * Returns: 1917 * 0 - success, -1 - failed. 1918 */ 1919 1920 int 1921 rpacket_init(int u, args_t *a, void **pa) 1922 { 1923 p_t *p = p_control[u]; 1924 parse_table_t pt; 1925 1926 1927 if (p == NULL) { 1928 p = sal_alloc(sizeof(p_t), "rpacket"); 1929 if (p == NULL) { 1930 test_error(u, "ERROR: cannot allocate memory\n"); 1931 return -1; 1932 } 1933 sal_memset(p, 0, sizeof(p_t)); 1934 p_control[u] = p; 1935 } 1936 1937 if (!p->p_init) { /* Init defaults first time */ 1938 p->hdr_chk = 0; 1939 p->diff_len = 4; 1940 p->diff_len_chk = 1; 1941 p->p_l_start = 64; 1942 p->p_l_end = 1522; 1943 p->p_l_inc = 64; 1944 p->p_time = 2; 1945 1946 p->p_pkts_per_sec = 0; 1947 p->p_max_q_len = -1; 1948 p->p_per_cos = FALSE; 1949 p->p_burst = 100; 1950 p->p_hw_rate = FALSE; 1951 1952 p->p_intr_cb = TRUE; 1953 p->p_dump_rx = FALSE; 1954 p->p_count_packets = FALSE; 1955 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 1956 if (SOC_KNET_MODE(u)) { 1957 p->p_use_socket = FALSE; 1958 p->p_use_socket_send = FALSE; 1959 } 1960 #endif 1961 /* Init the RX cfg here. Not much exposed */ 1962 p->p_rx_cfg.pkt_size = 8 * 1024; 1963 #if defined(BCM_ESW_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DNX_SUPPORT) 1964 p->p_rx_cfg.pkts_per_chain = 16; 1965 #endif /* BCM_ESW_SUPPORT */ 1966 #ifdef BCM_FE2000_SUPPORT 1967 p->p_rx_cfg.pkts_per_chain = 16; 1968 #endif /* BCM_FE2000_SUPPORT */ 1969 p->p_rx_cfg.global_pps = p->p_pkts_per_sec; 1970 p->p_rx_cfg.max_burst = p->p_burst; 1971 p->p_rx_cfg.chan_cfg[1].chains = 4; 1972 p->p_rx_cfg.chan_cfg[1].flags = 0; 1973 p->p_rx_cfg.chan_cfg[1].cos_bmp = 0xff; 1974 p->rx_mode = 0; 1975 /* Not initializing alloc/free functions */ 1976 p->p_init = TRUE; 1977 } 1978 1979 parse_table_init(u, &pt); 1980 parse_table_add(&pt, "Time", PQ_DFL|PQ_INT, 0, &p->p_time, 0); 1981 parse_table_add(&pt, "LengthStart", PQ_DFL|PQ_INT, 0, &p->p_l_start, 0); 1982 parse_table_add(&pt, "LengthEnd", PQ_DFL|PQ_INT, 0, &p->p_l_end, 0); 1983 parse_table_add(&pt, "LengthInc", PQ_DFL|PQ_INT, 0, &p->p_l_inc, 0); 1984 parse_table_add(&pt, "FreeBuffer", PQ_DFL|PQ_BOOL, 0, &p->p_free_buffer, 1985 0); 1986 1987 parse_table_add(&pt, "QLen", PQ_DFL|PQ_INT, 0, &p->p_max_q_len, 0); 1988 parse_table_add(&pt, "PERCos", PQ_DFL|PQ_INT, 0, &p->p_per_cos, 0); 1989 parse_table_add(&pt, "Rate", PQ_DFL|PQ_INT, 0, &p->p_pkts_per_sec, 0); 1990 parse_table_add(&pt, "Burst", PQ_DFL|PQ_INT, 0, &p->p_burst, 0); 1991 parse_table_add(&pt, "HWrate", PQ_DFL|PQ_INT, 0, &p->p_hw_rate, 0); 1992 1993 parse_table_add(&pt, "PktsPerChain", PQ_DFL|PQ_INT, 0, 1994 &p->p_rx_cfg.pkts_per_chain, 0); 1995 1996 parse_table_add(&pt, "Chains", PQ_DFL|PQ_INT, 0, 1997 &p->p_rx_cfg.chan_cfg[1].chains, 0); 1998 parse_table_add(&pt, "useINTR", PQ_DFL|PQ_BOOL, 0, &p->p_intr_cb, 0); 1999 parse_table_add(&pt, "DumpRX", PQ_DFL|PQ_BOOL, 0, &p->p_dump_rx, 0); 2000 parse_table_add(&pt, "RxMode", PQ_DFL|PQ_INT, 0, &p->rx_mode, 0); 2001 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 2002 parse_table_add(&pt, "SOCKet", PQ_DFL|PQ_INT, 0, &p->p_use_socket, 0); 2003 parse_table_add(&pt, "RingBuf", PQ_DFL|PQ_INT, 0, &p->p_ringbuf_size, 0); 2004 parse_table_add(&pt, "SocketTx", PQ_DFL|PQ_INT, 0, &p->p_use_socket_send, 0); 2005 #endif 2006 2007 if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) { 2008 test_error(u, "%s: Invalid option: %s\n", 2009 ARG_CMD(a), ARG_CUR(a) ? ARG_CUR(a) : "*"); 2010 cli_out("%s\n", rpacket_usage); 2011 parse_arg_eq_done(&pt); 2012 return -1; 2013 } 2014 parse_arg_eq_done(&pt); 2015 2016 if (p->p_time < 1) { 2017 test_error(u, "%s: Invalid duration: %d (must be 1 <= time)\n", 2018 ARG_CMD(a), p->p_time); 2019 return -1; 2020 } 2021 2022 if (p->p_per_cos) { 2023 p->p_hw_rate = 1; 2024 } 2025 2026 if (p->p_rx_cfg.pkts_per_chain > RP_MAX_PPC) { 2027 cli_out("Too many pkts/chain (%d). Setting to max (%d)\n", 2028 p->p_rx_cfg.pkts_per_chain, RP_MAX_PPC); 2029 p->p_rx_cfg.pkts_per_chain = RP_MAX_PPC; 2030 } 2031 if (p->rx_mode) { 2032 p->p_rx_cfg.flags |= BCM_RX_F_PKT_UNPARSED; 2033 } 2034 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 2035 if (SOC_KNET_MODE(u)) { 2036 if (!p->p_use_socket) { 2037 p->p_ringbuf_size = 0; 2038 } 2039 p->p_ringbuf = NULL; 2040 if (p->p_ringbuf_size > MAX_RXRING_FRAMES) { 2041 p->p_ringbuf_size = MAX_RXRING_FRAMES; 2042 } 2043 if (p->p_ringbuf_size > 0) { 2044 p->p_use_socket = TRUE; /* ringbuf implies raw socket */ 2045 } else { 2046 p->p_ringbuf_size = 0; 2047 } 2048 } else { 2049 if (p->p_use_socket) { 2050 cli_out("KNET not online, please insert the kernel module firstly.\n"); 2051 return -1; 2052 } 2053 } 2054 #endif 2055 2056 #ifdef BCM_DNX_SUPPORT 2057 if (SOC_IS_DNX(u)) 2058 { 2059 if (soc_feature(u, soc_feature_no_ep_to_cpu)) 2060 { 2061 /** Set to 1 to avoid to check length of EP_TO_CPU header on DNX */ 2062 p->hdr_chk = 1; 2063 } 2064 p->diff_len += DNX_MODULE_HEADER_SIZE; 2065 p->diff_len += 2; 2066 /** Bypass length check */ 2067 p->diff_len_chk = 0; 2068 } 2069 2070 #endif 2071 #ifdef BCM_PETRA_SUPPORT 2072 if (SOC_IS_ARAD(u)) 2073 { 2074 /** Set to 1 to avoid to check length of EP_TO_CPU header on DNX */ 2075 p->hdr_chk = 1; 2076 p->diff_len += 2; 2077 } 2078 #endif 2079 2080 if (rpacket_setup(u, p) < 0) { 2081 (void)rpacket_done(u, p); 2082 return -1; 2083 } 2084 2085 *pa = (void *)p; 2086 2087 2088 #if (defined(INCLUDE_KNET) && defined(LINUX) && (!defined(__KERNEL__))) 2089 if (SOC_KNET_MODE(u)) { 2090 (void)knetif_setup(u, p); 2091 } 2092 #endif 2093 return 0; 2094 } 2095 2096 #endif /* BCM_FIELD_SUPPORT || BCM_FE2000_SUPPORT || BCM_PETRA_SUPPORT || BCM_DNX_SUPPORT */