openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 }