pcidappl.c (20362B)
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 * The PCID application handler. 8 * 9 * Requires: 10 * All modules 11 * 12 * Provides: 13 * User interface, initialization, main() 14 */ 15 16 #include <shared/bsl.h> 17 #include <shared/bslext.h> 18 19 #include <unistd.h> 20 #include <stdlib.h> 21 #include <ctype.h> 22 23 #include <sys/types.h> 24 #include <sys/socket.h> 25 #include <sys/time.h> 26 #include <soc/mem.h> 27 #include <soc/hash.h> 28 #include <soc/cmext.h> 29 30 #include <soc/cmic.h> 31 #ifdef BCM_CMICM_SUPPORT 32 #include <soc/cmicm.h> 33 #endif 34 35 #include <soc/drv.h> 36 #if defined(BCM_PETRA_SUPPORT) 37 #include <soc/dpp/drv.h> 38 #endif 39 #if defined(BCM_DFE_SUPPORT) 40 #include <soc/dfe/cmn/dfe_drv.h> 41 #endif 42 #if defined(BCM_DNX_SUPPORT) 43 #include <soc/dnx/drv.h> 44 #endif 45 #if defined(BCM_DNXF_SUPPORT) 46 #include <soc/dnxf/cmn/dnxf_drv.h> 47 #endif 48 #ifdef BCM_PETRA_SUPPORT 49 #include <soc/dpp/mbcm.h> 50 #endif 51 #include <soc/devids.h> 52 #include <soc/chip.h> 53 #include <soc/mcm/driver.h> /* soc_base_driver_table */ 54 #include <soc/debug.h> 55 #include <sal/appl/io.h> 56 57 #include <bde/pli/verinet.h> 58 #include <bde/pli/plibde.h> 59 60 #include <sal/core/boot.h> 61 #include <sal/appl/config.h> 62 63 #include "pcid.h" 64 #include "mem.h" 65 #include "cmicsim.h" 66 #include "dma.h" 67 #include "pli.h" 68 #include "socintf.h" 69 #include "chipsim.h" 70 #ifdef BCM_CMICX_SUPPORT 71 #include "cmicx.h" 72 #endif /* BCM_CMICX_SUPPORT */ 73 74 #define I2C_ROM_FILE "soc_i2c.img" 75 76 #ifdef BCM_ISM_SUPPORT 77 extern uint8 ism_init; 78 #endif 79 80 /* used to be static */ 81 pcid_info_t pcid_info; 82 83 ibde_t *bde = NULL; 84 85 int 86 bde_create(void) 87 { 88 return plibde_create(&bde); 89 } 90 91 static void 92 usage(void) 93 { 94 #ifdef __STRICT_ANSI__ 95 fprintf(stderr, 96 "Usage: pcid <chip>\n"); 97 #else 98 fprintf(stderr, 99 "Usage: pcid [-ha] [-p port] [-vPxdilkc] [-G N] [-B N] " 100 "[-W 64] [-D N] [-R N] <chip>\n"); 101 fprintf(stderr, 102 " <chip> Chip to emulate, e.g. BCM56504_B0\n"); 103 fprintf(stderr, 104 " -h Show help\n"); 105 fprintf(stderr, 106 " -a List all supported chips \n"); 107 fprintf(stderr, 108 " -v Verbose mode\n"); 109 fprintf(stderr, 110 " -p port Specify which port to start PCID server on\n"); 111 fprintf(stderr, 112 " -P Include PLI register R/W in verbose mode\n"); 113 fprintf(stderr, 114 " -x Exit when first client disconnects\n"); 115 fprintf(stderr, 116 " -d Run in verinet debug mode\n"); 117 fprintf(stderr, 118 " -i Dump code for headless I2C ROM contents into\n"); 119 fprintf(stderr, 120 " the file %s\n", I2C_ROM_FILE); 121 fprintf(stderr, 122 " -l Loops back packets transmitted out\n"); 123 fprintf(stderr, 124 " -k Take packet input using the file method\n"); 125 fprintf(stderr, 126 " -c Simulate counter activity (inefficiently!)\n"); 127 fprintf(stderr, 128 " -G N Simulate GBP size of N megabytes\n"); 129 fprintf(stderr, 130 " -B N Simulate GBP with N banks (2 or 4)\n"); 131 fprintf(stderr, 132 " -W 64 Simulate GBP width of 64 bits (-G still\n" 133 " specifies size as if it were 128 bits wide)\n"); 134 fprintf(stderr, 135 " -D N Override PCI device ID to N; e.g. 0x5616\n"); 136 fprintf(stderr, 137 " -R N Override PCI revision ID to N; e.g. 3\n"); 138 fprintf(stderr, 139 " -C N Set device config to N; e.g. 1\n"); 140 #endif 141 exit(1); 142 } 143 144 static int 145 pcid_out_hook(bsl_meta_t *meta, const char *format, va_list args) 146 { 147 return vprintf(format, args); 148 } 149 150 static int 151 pcid_check_hook(bsl_packed_meta_t meta_pack) 152 { 153 int source, severity; 154 155 source = BSL_SOURCE_GET(meta_pack); 156 severity = BSL_SEVERITY_GET(meta_pack); 157 158 if (severity <= bslSeverityWarn) { 159 return 1; 160 } 161 if (source == bslSourceShell) { 162 return 1; 163 } 164 if (source == bslSourceCommon) { 165 if (severity <= bslSeverityVerbose && pcid_info.opt_verbose) { 166 return 1; 167 } 168 } 169 if (source == bslSourceVerinet && pcid_info.opt_debug) { 170 if (severity <= bslSeverityInfo) { 171 return 1; 172 } 173 if (severity <= bslSeverityVerbose && pcid_info.opt_verbose) { 174 return 1; 175 } 176 } 177 return 0; 178 } 179 180 static void 181 pcid_info_init(pcid_info_t *pcid_info) 182 { 183 bsl_config_t bsl_config; 184 185 bsl_config_t_init(&bsl_config); 186 bsl_config.out_hook = pcid_out_hook; 187 bsl_config.check_hook = pcid_check_hook; 188 bsl_init(&bsl_config); 189 190 sal_memset(pcid_info, 0, sizeof(pcid_info_t)); 191 pcid_info->opt_gbp_banks = 2; 192 pcid_info->opt_gbp_mb = 32; 193 pcid_info->opt_gbp_wid = 128; 194 195 pcid_info->single_mode = 0; 196 197 if ((pcid_info->pkt_mutex = sal_mutex_create("pkt_mutex")) == NULL) { 198 printf("sal_mutex_create -pkt_mutex failed\n"); 199 exit(1); 200 } 201 soc_cm_init(); 202 } 203 204 static void 205 pcid_clean_regsfile(uint16 pci_dev_id, uint16 pci_rev_id) 206 { 207 soc_reg_t reg; 208 int disable_ipic; 209 210 disable_ipic = 0; 211 switch (pci_dev_id) { 212 case 0x5691: /* 5690 variations */ 213 case 0x5693: 214 case 0x5696: /* 5695 variations */ 215 case 0x5698: 216 disable_ipic = 1; 217 break; 218 /* 5665 variations? */ 219 } 220 221 if (disable_ipic) { 222 /* 223 * Convert all IPIC registers to _INVALID_REGISTER. 224 * soc_internal_write_reg will then complain about them. 225 */ 226 227 for (reg = 0; reg < NUM_SOC_REG; reg++) { 228 if (!SOC_REG_IS_VALID(0, reg)) { 229 continue; 230 } 231 if (SOC_REG_INFO(0, reg).block[0] == SOC_BLK_IPIC) { 232 SOC_REG_INFO(0, reg).block[0] = 0; 233 SOC_REG_INFO(0, reg).regtype = soc_invalidreg; 234 SOC_REG_INFO(0, reg).numels = -1; 235 SOC_REG_INFO(0, reg).offset = 0; 236 SOC_REG_INFO(0, reg).flags = 0; 237 SOC_REG_INFO(0, reg).nFields = 0; 238 SOC_REG_INFO(0, reg).fields = NULL; 239 SOC_REG_INFO(0, reg).ctr_idx = -1; 240 } 241 } 242 } 243 } 244 245 void 246 pcid_schan_cb_set(pcid_info_t *pcid_info, _pcid_schan_f f) 247 { 248 pcid_info->schan_cb = f; 249 } 250 251 void 252 pcid_reset_cb_set(pcid_info_t *pcid_info, _pcid_reset_f f) 253 { 254 pcid_info->reset_cb = f; 255 } 256 257 258 /* main function */ 259 int 260 main(int argc, char *argv[]) 261 { 262 int i, chip, found; 263 char *s; 264 #ifndef __STRICT_ANSI__ 265 extern char *optarg; 266 #endif 267 struct timeval tmout; 268 uint16 pci_dev_id, pci_ven_id; 269 uint8 pci_rev_id; 270 int max_command_errors = 100; 271 int command_errors = 0; 272 int len; 273 char *config_file, *config_temp; 274 int chan; 275 276 pcid_info_init(&pcid_info); 277 278 if ((config_file = getenv("BCM_CONFIG_FILE")) != NULL) { 279 len = sal_strlen(config_file); 280 if ((config_temp = sal_alloc(len+5, NULL)) != NULL) { 281 /* coverity[secure_coding] */ 282 sal_strcpy(config_temp, config_file); 283 /* coverity[secure_coding] */ 284 sal_strcpy(&config_temp[len], ".tmp"); 285 sal_config_file_set(config_file, config_temp); 286 /* coverity[tainted_data] */ 287 sal_free(config_temp); 288 } 289 } 290 291 if (sal_core_init() < 0) { 292 printf("sal_core_init failed\n"); 293 exit(1); 294 } 295 296 if (sal_appl_init() < 0) { 297 printf("sal_appl_init failed\n"); 298 exit(1); 299 } 300 301 /* 302 * Get default port from SOC_TARGET_PORT, if available 303 */ 304 305 if ((s = getenv("SOC_TARGET_PORT")) != NULL) { 306 pcid_info.opt_port = strtol(s, 0, 0); 307 } 308 309 #ifndef __STRICT_ANSI__ 310 while ((i = getopt(argc, argv, "havxdilkcG:W:B:Pp:D:R:C:")) >= 0) 311 switch (i) { 312 case 'h': 313 usage(); 314 break; 315 case 'a': 316 fprintf(stderr, "List of supported chips:\n"); 317 for (i = 0; i < SOC_CHIP_TYPES_COUNT; i++) { 318 fprintf(stderr, "pcid: %s\n", soc_chip_type_names[i]); 319 } 320 exit(1); 321 break; 322 case 'v': 323 pcid_info.opt_verbose = 1; 324 break; 325 case 'x': 326 pcid_info.opt_exit = 1; 327 break; 328 case 'd': 329 pcid_info.opt_debug = 1; 330 break; 331 case 'i': 332 pcid_info.opt_i2crom = 1; 333 break; 334 case 'l': 335 pcid_info.opt_pktloop = 1; 336 pcid_info.tx_cb = _pcid_loop_tx_cb; 337 break; 338 case 'k': 339 pcid_info.opt_pktfile = 1; 340 break; 341 case 'c': 342 pcid_info.opt_counter = 1; 343 break; 344 case 'G': 345 pcid_info.opt_gbp_mb = strtol(optarg, 0, 0); 346 break; 347 case 'B': 348 pcid_info.opt_gbp_banks = strtol(optarg, 0, 0); 349 break; 350 case 'P': 351 pcid_info.opt_pli_verbose = 1; 352 break; 353 case 'p': 354 pcid_info.opt_port = strtol(optarg, 0, 0); 355 break; 356 case 'D': 357 pcid_info.opt_override_devid = strtol(optarg, 0, 0); 358 break; 359 case 'R': 360 pcid_info.opt_override_revid = strtol(optarg, 0, 0); 361 break; 362 case 'W': 363 pcid_info.opt_gbp_wid = strtol(optarg, 0, 0); 364 break; 365 default: 366 printf("pcid: unknown option '%c'\n", i); 367 usage(); 368 break; 369 } 370 371 /* 372 * Check arguments: user must specify a port to bind to. 373 */ 374 375 if (optind != argc - 1) { 376 usage(); 377 } 378 379 /* 380 * Coverity 381 * 382 * Coverity complains that the variable optind is tainted, since it 383 * may take the true path in the above conditional, which means 384 * optind != (argc - 1) and thus is unbounded. Coverity 385 * fails to realize that usage() ends with exit(), so no true 386 * test of the conditional may proceed with processing. If the 387 * conditional is false, then the variable is bounded and not tainted. 388 */ 389 /* coverity[var_assign_var] : FALSE */ 390 pcid_info.opt_chip_name = argv[optind]; 391 #else 392 if (argc != 2) { 393 usage(); 394 } else { 395 pcid_info.opt_chip_name = argv[1]; 396 } 397 #endif /*__STRICT_ANSI__*/ 398 399 found = 0; 400 401 for (i = 0; i < SOC_CHIP_TYPES_COUNT; i++) { 402 if (sal_strcasecmp(pcid_info.opt_chip_name, soc_chip_type_names[i]) == 0) { 403 found = 1; 404 pcid_info.opt_chip = i; 405 chip = soc_chip_type_to_index(pcid_info.opt_chip); 406 break; 407 } 408 /* Allow specifying chip by number only, e.g. 5690 or 56504 */ 409 if (isdigit((unsigned)pcid_info.opt_chip_name[0]) && 410 atoi(pcid_info.opt_chip_name) == 411 atoi(&soc_chip_type_names[i][3])) { 412 found = 1; 413 pcid_info.opt_chip = i; 414 chip = soc_chip_type_to_index(pcid_info.opt_chip); 415 break; 416 } 417 } 418 419 if (!found) { 420 fprintf(stderr, 421 "pcid: Unrecognized chip type '%s'\n", 422 pcid_info.opt_chip_name); 423 fprintf(stderr, "pcid: Valid chip types are:\n"); 424 for (i = 0; i < SOC_CHIP_TYPES_COUNT; i++) { 425 fprintf(stderr, "pcid: %s\n", soc_chip_type_names[i]); 426 } 427 exit(1); 428 } 429 430 /* 431 * Set initial contents of PCI configuration space. 432 */ 433 434 /*look up in driver table or configure pci for chips without driver (SKUs)*/ 435 switch (pcid_info.opt_chip) 436 { 437 case SOC_CHIP_BCM88755_B0: 438 pci_ven_id = BROADCOM_VENDOR_ID; 439 pci_dev_id = BCM88755_DEVICE_ID; 440 pci_rev_id = BCM88755_B0_REV_ID; 441 break; 442 default: 443 /*look up in driver table*/ 444 chip = soc_chip_type_to_index(pcid_info.opt_chip); 445 pci_ven_id = soc_base_driver_table[chip]->pci_vendor; 446 pci_dev_id = soc_base_driver_table[chip]->pci_device; 447 pci_rev_id = soc_base_driver_table[chip]->pci_revision; 448 } 449 450 451 if (pci_dev_id == 0x0) { 452 fprintf(stderr, 453 "pcid: Not compiled with support for '%s'\n", 454 pcid_info.opt_chip_name); 455 exit(1); 456 } 457 458 /* From here on, we want the effective ID's */ 459 if (pcid_info.opt_override_devid) { 460 pci_dev_id = pcid_info.opt_override_devid; 461 } 462 if (pcid_info.opt_override_revid) { 463 pci_rev_id = pcid_info.opt_override_revid; 464 } 465 466 soc_internal_pcic_init(&pcid_info, pci_dev_id, 467 pci_ven_id, pci_rev_id, 0xcd600000); 468 469 /* 470 * Init driver so soc_feature and other functions can be used. 471 */ 472 473 soc_cm_device_create(pci_dev_id, pci_rev_id, NULL); 474 475 SOC_CONTROL(0) = sal_alloc(sizeof (soc_control_t), "soc_control_t"); 476 memset(SOC_CONTROL(0), 0, sizeof (soc_control_t)); 477 SOC_PERSIST(0) = sal_alloc(sizeof (soc_persist_t), "soc_persist_t"); 478 memset(SOC_PERSIST(0), 0, sizeof (soc_persist_t)); 479 480 #if defined(BCM_PETRA_SUPPORT) 481 if (SOC_CONTROL(0)->chip_driver == NULL && SOC_IS_DPP_TYPE(pci_dev_id)) { 482 SOC_CONTROL(0)->chip_driver = soc_dpp_chip_driver_find(pci_dev_id, pci_rev_id); 483 } 484 #endif 485 #if defined(BCM_DNX_SUPPORT) 486 if (SOC_CONTROL(0)->chip_driver == NULL && SOC_IS_DNX_TYPE(pci_dev_id)) { 487 soc_dnx_chip_driver_find(0, pci_dev_id, pci_rev_id, &(SOC_CONTROL(0)->chip_driver)); 488 } 489 #endif 490 #if defined(BCM_DFE_SUPPORT) 491 if (SOC_CONTROL(0)->chip_driver == NULL && SOC_IS_DFE_TYPE(pci_dev_id)) { 492 SOC_CONTROL(0)->chip_driver = soc_dfe_chip_driver_find(0, pci_dev_id, pci_rev_id); 493 } 494 #endif 495 #if defined(BCM_DNXF_SUPPORT) 496 if (SOC_CONTROL(0)->chip_driver == NULL && SOC_IS_DNXF_TYPE(pci_dev_id)) { 497 SOC_CONTROL(0)->chip_driver = soc_dnxf_chip_driver_find(0, pci_dev_id, pci_rev_id); 498 } 499 #endif 500 #if defined(BCM_ESW_SUPPORT) 501 if (SOC_CONTROL(0)->chip_driver == NULL) { 502 SOC_CONTROL(0)->chip_driver = soc_chip_driver_find(pci_dev_id, pci_rev_id); 503 } 504 #endif 505 assert(SOC_CONTROL(0)->chip_driver != NULL); 506 507 PCIC(&pcid_info, 0x14) = SOC_CONTROL(0)->chip_driver->cmicd_base; 508 509 if (soc_base_driver_table[chip]->init) { 510 (soc_base_driver_table[chip]->init)(); 511 } 512 513 /* this sets up the SOC_IS_* macros, amongst other things */ 514 #if defined(BCM_PETRA_SUPPORT) 515 if(SOC_IS_DPP_TYPE(pci_dev_id)) { 516 soc_dpp_chip_type_set(0, CMDEV(0).dev.info->dev_id); 517 if ((i = soc_dpp_defines_init(0)) != SOC_E_NONE) { 518 return i; 519 } 520 mbcm_dpp_init(0); 521 soc_dpp_info_config(0); 522 } else 523 #endif 524 #if defined(BCM_DNX_SUPPORT) 525 if(SOC_IS_DNX_TYPE(pci_dev_id)) { 526 soc_dnx_chip_type_set(0, CMDEV(0).dev.info->dev_id); 527 soc_dnx_info_config(0); 528 } else 529 #endif 530 #if defined(BCM_DFE_SUPPORT) 531 if(SOC_IS_DFE_TYPE(pci_dev_id)) { 532 soc_dfe_chip_type_set(0, CMDEV(0).dev.info->dev_id); 533 soc_dfe_info_config(0, pci_dev_id); 534 } else 535 #endif 536 #if defined(BCM_DNXF_SUPPORT) 537 if(SOC_IS_DNXF_TYPE(pci_dev_id)) { 538 soc_dnxf_chip_type_set(0, CMDEV(0).dev.info->dev_id); 539 soc_dnxf_info_config(0, pci_dev_id); 540 } else 541 #endif 542 { 543 #ifdef BCM_XGS_SWITCH_SUPPORT 544 soc_info_config(0, SOC_CONTROL(0)); 545 #endif 546 } 547 548 /* set up soc_feature macro */ 549 soc_feature_init(0); 550 551 /* Record the SBUS address version, now that features are enabled */ 552 pcid_info.sbus_addr_version = 553 soc_feature(pcid_info.unit, soc_feature_new_sbus_format) ? 554 SBUS_ADDR_VERSION_2 : SBUS_ADDR_VERSION_1; 555 556 557 #ifdef BCM_CMICX_SUPPORT 558 /* initialize the cmicx sim if we have a cmicx chip */ 559 if (soc_feature(pcid_info.unit, soc_feature_cmicx)) { 560 if (cmicx_init()==FALSE) { 561 return 1; 562 } 563 } 564 #endif /* BCM_CMICX_SUPPORT */ 565 566 #ifdef BCM_CMICM_SUPPORT 567 pcid_info.cmicm = soc_feature(pcid_info.unit, soc_feature_cmicm) ? CMC0 : -1; 568 #if defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT) 569 if (soc_feature(pcid_info.unit, soc_feature_cmicx) && 570 (SOC_IS_DNX(pcid_info.unit) || SOC_IS_DNXF(pcid_info.unit))) { 571 /* Use CMICM simulation instead of CMICX simulation */ 572 pcid_info.cmicm = CMC0; 573 } 574 #endif /* BCM_DNX_SUPPORT || BCM_DNXF_SUPPORT */ 575 #endif 576 577 #if defined(BCM_ESW_SUPPORT) 578 #if (!defined(BCM_PETRA_SUPPORT)) && (!defined(BCM_DFE_SUPPORT)) 579 /* initialize dcb operations */ 580 soc_dcb_unit_init(0); 581 #endif /* (!defined(BCM_PETRA_SUPPORT)) && (!defined(BCM_DFE_SUPPORT)) */ 582 #endif /* defined(BCM_ESW_SUPPORT) */ 583 /* 584 * Initialize memory index_maxes. 585 */ 586 for (i = 0; i < NUM_SOC_MEM; i++) { 587 if (SOC_MEM_IS_VALID(0, i)) { 588 SOC_PERSIST(0)->memState[i].index_max = 589 SOC_MEM_INFO(0, i).index_max; 590 } else { 591 SOC_PERSIST(0)->memState[i].index_max = -1; 592 } 593 } 594 595 /* 596 * Perform any needed run-time cleanup of regsfile. 597 */ 598 599 pcid_clean_regsfile(pci_dev_id, pci_rev_id); 600 601 if (pcid_info.opt_port == 0) { 602 fprintf(stderr, "pcid: Must specify port number using -p or set\n"); 603 fprintf(stderr, " it in SOC_TARGET_PORT environment variable\n"); 604 605 exit(1); 606 } 607 608 pli_reset_service(&pcid_info); 609 610 pcid_info.sockfd = pcid_setup_socket(pcid_info.opt_port); 611 612 do { 613 pcid_info.opt_rpc_error = 0; /* reset the error condition */ 614 printf("%s: Emulating %s, listening on port %d\n", 615 argv[0], 616 soc_cm_get_device_name(pci_dev_id, pci_rev_id), 617 pcid_info.opt_port); 618 619 pcid_info.newsockfd = pcid_wait_for_cnxn(pcid_info.sockfd); 620 621 if (pcid_info.opt_i2crom) { 622 if ((pcid_info.i2crom_fp = fopen(I2C_ROM_FILE, "w")) == 0) { 623 perror("unable to open I2C ROM output file"); 624 } 625 } 626 627 printf("%s: Client connected\n", argv[0]); 628 629 /* 630 * Queue initial events 631 */ 632 633 event_init(); 634 635 if (pcid_info.opt_pktfile) { 636 event_enqueue(&pcid_info, pcid_check_packet_input, 637 sal_time_usecs() + PACKET_CHECK_INTERVAL); 638 } 639 640 if (pcid_info.opt_counter) { 641 event_enqueue(&pcid_info, pcid_counter_activity, 642 sal_time_usecs() + COUNTER_ACT_INTERVAL); 643 } 644 645 #ifdef BCM_ISM_SUPPORT 646 ism_init = 0; 647 #endif 648 649 650 /* 651 * Event/request loop 652 */ 653 654 for (;;) { 655 event_t *ev; 656 int usec; /* Signed */ 657 sal_usecs_t now; 658 659 now = sal_time_usecs(); 660 661 if ((ev = event_peek()) != NULL) { 662 usec = SAL_USECS_SUB(ev->abs_time, now); 663 } else { 664 /* if we have a cmicx chip, we need a different (faster) timeout for the sim */ 665 if (soc_feature(pcid_info.unit, soc_feature_cmicx)) { 666 usec = 10; 667 } 668 else { 669 usec = 100000; 670 } 671 } 672 673 tmout.tv_sec = 0; 674 tmout.tv_usec = (usec > 0 ? usec : 0); 675 676 if ((pcid_process_request(&pcid_info, 677 pcid_info.newsockfd, &tmout) == PR_ERROR) || 678 (pcid_info.opt_rpc_error /* RPC error with client */)) { 679 if (++command_errors > max_command_errors) { 680 pcid_info.opt_exit = 1; 681 } 682 break; 683 } 684 685 686 #ifdef BCM_CMICX_SUPPORT 687 /* if we have a cmicx chip, update the cmicx sim */ 688 if (soc_feature(pcid_info.unit, soc_feature_cmicx) && 689 !(SOC_IS_DNX(pcid_info.unit) || SOC_IS_DNXF(pcid_info.unit))) { 690 cmicx_update(&pcid_info); 691 } else 692 #endif /* BCM_CMICX_SUPPORT */ 693 { 694 for (chan = 0; chan < N_DMA_CHAN; chan++) { 695 #ifdef BCM_CMICM_SUPPORT 696 if (pcid_info.cmicm >= CMC0) { 697 pcid_dma_cmicm_rx_check(&pcid_info, chan); 698 } else 699 #endif 700 { 701 pcid_dma_rx_check(&pcid_info, chan); 702 } 703 } 704 } 705 706 event_process_through(now); 707 } 708 709 if (pcid_info.i2crom_fp) { 710 /* Write data end marker */ 711 fputc(0xff, pcid_info.i2crom_fp); 712 fputc(0xff, pcid_info.i2crom_fp); 713 fputc(0x00, pcid_info.i2crom_fp); 714 fclose(pcid_info.i2crom_fp); 715 } 716 717 /* Stop DMA on all channels to prevent the PCI polling on old DMA 718 * when client connects again. 719 */ 720 pcid_dma_stop_all(&pcid_info); 721 722 pcid_close_cnxn(pcid_info.newsockfd); 723 724 printf("%s: Client disconnected.\n", argv[0]); 725 } while (!pcid_info.opt_exit); 726 727 pcid_close_cnxn(pcid_info.sockfd); 728 exit(0); 729 }