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

cancun.c (38327B)


      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  * File: cih.c
      8  * Purpose: CANCUN operation handler
      9  */
     10 
     11 #ifndef NO_SAL_APPL
     12 
     13 #include <sal/types.h>
     14 #include <sal/core/libc.h>
     15 #include <sal/appl/sal.h>
     16 #include <sal/appl/io.h>
     17 #include <shared/bsl.h>
     18 #include <appl/diag/shell.h>
     19 #include <appl/diag/system.h>
     20 #include <soc/drv.h>
     21 #include <soc/esw/cancun.h>
     22 
     23 /*
     24  * Local variable declares
     25  */
     26 char cmd_cancun_usage[] =
     27     "Parameters: [stat|list|load|debug|help] <args...>\n"
     28 #ifndef COMPILER_STRING_CONST_LIMIT
     29     "  CANCUN operations including information display and file loading. The\n"
     30     "  supported operations are:\n"
     31     "\t stat\t - Display currently loaded CANCUN information\n"
     32     "\t list\t - List all CANCUN loadable files in current file system\n"
     33     "\t load\t - Load a particular CANCUN loadable file\n"
     34     "\t debug\t - Debug commands (TBD)\n"
     35     "\t help\t - Display this usage page\n"
     36     "\n"
     37     "  Arguments for each operation:\n"
     38     "  - list: [(none)|<filename>]\n"
     39     "\t (none) - If there is no argument after this operation, it displays all\n"
     40     "\t the available files and directories under CANCUN file repository\n"
     41     "\t directory in current file system\n"
     42     "\t <filename> - If a specific filename is entered, which should include\n"
     43     "\t the path related to CANCUN file repository directory, this command\n"
     44     "\t displays the information of this file only\n"
     45     "\n"
     46     "  - load: <filename> <file type> <file format>\n"
     47     "\t <filename> - If there is no argument after this operation, it will \n"
     48     "\t load all the default CANCUN files. If this file is in packaged format\n"
     49     "\t , no addition arguments are needed because software can extract them\n"
     50     "\t from the file itself.\n"
     51     "\t <file type> - For a non-packaged format file, this argument is needed\n"
     52     "\t Currently supported file type includes [cih|cmh|cch]\n"
     53     "\t <file format> - For a non-packaged format file, this argument is needed\n"
     54     "\t Currently supported file format includes [pio|dma]\n"
     55 #endif
     56     ;
     57 
     58 static const char* soc_cancun_file_type_string[CANCUN_SOC_FILE_TYPE_NUM] =
     59                    CANCUN_FILE_TYPE_NAMES_INITIALIZER;
     60 
     61 static const char* soc_cancun_file_format_string[CANCUN_SOC_FILE_FORMAT_NUM] =
     62                    CANCUN_FILE_FORMAT_NAMES_INITIALIZER;
     63 
     64 static const char* soc_cancun_load_status_string[CANCUN_SOC_FILE_LOAD_STATUS_NUM] =
     65                    CANCUN_FILE_LOAD_STATUS_INITIALIZER;
     66 
     67 /*
     68  * Local function declares
     69  */
     70 cmd_result_t _cmd_cancun_status(int unit);
     71 int _cmd_cancun_file_load(int unit, char* filename, uint32 file_type,
     72                           uint32 file_format, soc_cancun_t *cc);
     73 int _cancun_file_buffer_load(char *filename, uint8 **buf, long *buf_len);
     74 int _cancun_file_info_print(soc_cancun_file_t *ccf, int row_mode);
     75 void _cancun_sdk_version_string_get(char* ver_string, uint32 ver);
     76 void _cancun_version_string_get(char* ver_string, uint32 ver);
     77 void _soc_cancun_default_filename(int unit, char *filename, int file_type);
     78 int _soc_cancun_dest_entry_print(soc_cancun_dest_entry_t *dest_entry);
     79 void _cancun_revision_print(uint32 ver);
     80 
     81 /*
     82  * Function:   cmd_cancun
     83  * Purpose:    Process all the CANCUN file and status operations
     84  * Parameters: unit - unit
     85  *             a - args, each of the files to be displayed.
     86  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE
     87  */
     88 cmd_result_t
     89 cmd_cancun(int unit, args_t *a)
     90 {
     91     char *c;
     92 #ifndef NO_FILEIO
     93     char filename[CANCUN_FILENAME_SIZE] = {0};
     94     uint32 file_type = CANCUN_SOC_FILE_TYPE_UNKNOWN;
     95     uint32 file_format = CANCUN_SOC_FILE_FORMAT_UNKNOWN;
     96 #endif /* NO_FILEIO */
     97 
     98     soc_cancun_t* cc;
     99     uint32* p = NULL;
    100     int rv = 0;
    101 
    102     if (!sh_check_attached("cancun", unit)) {
    103         return(CMD_FAIL);
    104     }
    105 
    106     if (!soc_feature(unit, soc_feature_cancun)) {
    107         return (CMD_NFND);
    108     }
    109 
    110     c = ARG_GET(a);
    111     if(!c) {
    112         return (CMD_USAGE);
    113     } else if(!sal_strcasecmp(c, "help")) {
    114         return (CMD_USAGE);
    115     }
    116 
    117     rv = soc_cancun_status_get(unit, &cc);
    118     if(rv != 0) {
    119         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    120             "can't get CANCUN status. (%s)\n"), soc_errmsg(rv)));
    121         return(CMD_FAIL);
    122     }
    123 
    124     /* Operation: stat */
    125     if (!sal_strcasecmp(c, "stat")) {
    126         rv = (int)_cmd_cancun_status(unit);
    127 
    128     /* Operation: load */
    129     } else if (!sal_strcasecmp(c, "load")) {
    130 #ifndef NO_FILEIO
    131         /* Arguments check */
    132         c = ARG_GET(a);
    133         if(!c) {
    134             /* TBA: Load all default CANCUN files */
    135             return (CMD_USAGE);
    136         } else if(sal_strlen(c) > CANCUN_FILENAME_SIZE) {
    137             LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    138                 "input filename is longer than limit %d\n"),
    139                 CANCUN_FILENAME_SIZE));
    140             return (CMD_FAIL);
    141         } else {
    142             if (!sal_strcasecmp(c, "cih")) {
    143                 file_type = CANCUN_SOC_FILE_TYPE_CIH;
    144             } else if (!sal_strcasecmp(c, "cmh")) {
    145                 file_type = CANCUN_SOC_FILE_TYPE_CMH;
    146             } else if (!sal_strcasecmp(c, "cch")) {
    147                 file_type = CANCUN_SOC_FILE_TYPE_CCH;
    148             } else if (!sal_strcasecmp(c, "ceh")) {
    149                 file_type = CANCUN_SOC_FILE_TYPE_CEH;
    150             } else if (!sal_strcasecmp(c, "cfh")) {
    151                 if (soc_feature(unit,soc_feature_flex_flow)) {
    152                     file_type = CANCUN_SOC_FILE_TYPE_CFH;
    153                 } else {
    154                     LOG_DEBUG(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    155                     "Flow initialization mode is disabled for flow module.\n"
    156                     )));
    157                     return (CMD_OK);
    158                 }
    159             } else {
    160                 sal_strncpy(filename, c, CANCUN_FILENAME_SIZE-1);
    161             }
    162 
    163             c = ARG_GET(a);
    164             if(c) {
    165                 if (!sal_strcasecmp(c, "pio")) {
    166                     file_format = CANCUN_SOC_FILE_FORMAT_PIO;
    167                 } else if (!sal_strcasecmp(c, "pack")) {
    168                     file_format = CANCUN_SOC_FILE_FORMAT_PACK;
    169                 } else {
    170                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    171                          "%s is not a supported file format\n"), c));
    172                     return (CMD_FAIL);
    173                 }
    174             } else if(file_type != CANCUN_SOC_FILE_TYPE_UNKNOWN) {
    175                 LOG_INFO(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    176                      "Loading default CANCUN %s files\n"),
    177                      soc_cancun_file_type_string[file_type]));
    178                 _soc_cancun_default_filename(unit, filename, file_type);
    179             }
    180         }
    181 
    182         rv = _cmd_cancun_file_load(unit, filename, file_type, file_format, cc);
    183 #else
    184         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit, "No file system\n")));
    185 #endif /* NO_FILEIO */
    186     /* Operation: list */
    187     } else if (!sal_strcasecmp(c, "list")) {
    188 #ifndef NO_FILEIO
    189         SAL_DIR *dir, *dir2;
    190         struct sal_dirent *d;
    191         char *filename;
    192         uint8 *buf = NULL;
    193         long buf_len = 0;
    194         soc_cancun_file_t ccf;
    195 
    196         dir = sal_opendir(".");
    197         if (dir) {
    198             cli_out("   %-50s %-7s %-8s %-11s  %s\n", "FILE", "TYPE", "FORMAT",
    199                     "VER", "VALID");
    200             while ((d = sal_readdir(dir)) != NULL) {
    201                 filename = d->d_name;
    202                 if (!sal_strcasecmp(filename, ".") ||
    203                     !sal_strcasecmp(filename, "..")) {
    204                     continue;
    205                 }
    206 
    207                 dir2 = sal_opendir(filename);
    208                 if (dir2) {
    209                     /* Skip directories */
    210                     cli_out(" D %s\n", filename);
    211                     sal_closedir(dir2);
    212                 } else {
    213                     rv = _cancun_file_buffer_load(filename, &buf, &buf_len);
    214                     if (rv == SOC_E_NONE && buf != NULL) {
    215                         rv = soc_cancun_file_info_get(unit, &ccf, filename, buf, buf_len);
    216                         if (rv == SOC_E_NONE) {
    217                             _cancun_file_info_print(&ccf, 1);
    218                         }
    219                     } else {
    220                         if(buf != NULL) {
    221                             sal_free(buf);
    222                         }
    223                     }
    224                 }
    225             }
    226             sal_closedir(dir);
    227         }
    228 #else
    229         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit, "No file system\n")));
    230         return (CMD_FAIL);
    231 #endif /* NO_FILEIO */
    232     /* Operation: scan */
    233     } else if (!sal_strcasecmp(c, "scan")) {
    234         c = ARG_GET(a);
    235         if (!c || !sal_strcasecmp(c, "cmh")) {
    236             rv = soc_cancun_access_scan(unit, CANCUN_SOC_FILE_TYPE_CMH);
    237             cli_out("CMH access scan %s\n", (rv == SOC_E_NONE)? "PASS": "FAIL");
    238         }
    239         if (!c || !sal_strcasecmp(c, "cch")) {
    240             rv = soc_cancun_access_scan(unit, CANCUN_SOC_FILE_TYPE_CCH);
    241             cli_out("CCH access scan %s\n", (rv == SOC_E_NONE)? "PASS": "FAIL");
    242         }
    243 
    244     /* Operation: debug */
    245     } else if (!sal_strcasecmp(c, "debug")) {
    246 
    247         /* Arguments check */
    248         c = ARG_GET(a);
    249         if(!c) {
    250             /* TBA: Display default debug info */
    251         } else {
    252             if (!sal_strcasecmp(c, "cmh")) {
    253                 soc_cancun_cmh_t* cmh = cc->cmh;
    254                 soc_cancun_hash_table_t* hash_table_header;
    255                 uint32 i, entry_num;
    256 
    257                 if(cmh == NULL) {
    258                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    259                          "CANCUN CMH is not initialized\n")));
    260                     return (CMD_FAIL);
    261                 } else if (cmh->status != SOC_CANCUN_LOAD_STATUS_LOADED) {
    262                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    263                          "CANCUN CMH is not loaded\n")));
    264                     return (CMD_FAIL);
    265                 }
    266                 hash_table_header = (soc_cancun_hash_table_t*) cmh->cmh_table;
    267 
    268                 cli_out("%s: CMH debug information:\n", ARG_CMD(a));
    269                 cli_out("%s: CMH hash table\n", ARG_CMD(a));
    270                 cli_out("\tpA = %d\n", hash_table_header->pa);
    271                 cli_out("\tpB = %d\n", hash_table_header->pb);
    272                 cli_out("\tpC = %d\n", hash_table_header->pc);
    273                 cli_out("\tpD = %d\n", hash_table_header->pd);
    274                 cli_out("\tsize = %d\n", hash_table_header->table_size);
    275                 cli_out("\tList = \n\n");
    276                 soc_cancun_cmh_list (unit, &p);
    277                 if(p) {
    278                     entry_num = *p++;
    279                     cli_out("\t%-40s %-40s %-3s\n", "MEM","FIELD", "APP");
    280                     for(i = 0; i < entry_num; i++) {
    281                         cli_out("\t%-40s %-40s %-3d\n",
    282                                 (*p >= NUM_SOC_MEM)? SOC_REG_NAME(unit, *p):
    283                                                      SOC_MEM_NAME(unit, *p),
    284                                 *(p+1) < NUM_SOC_FIELD ? SOC_FIELD_NAME(unit, *(p+1)): "",
    285                                 *(p+2));
    286                         p += 3;
    287                     }
    288                 }
    289 #if 0
    290                 cli_out("\tRaw data = \n");
    291                 p = &hash_table_header->table_entry;
    292                 if(p) {
    293                     for(i = 0; i < hash_table_header->table_size; i++) {
    294                         if((i % 10) == 0) {
    295                             cli_out("\n");
    296                         }
    297                         cli_out("%08X ", *p++);
    298                     }
    299                 }
    300                 cli_out("\n");
    301 #endif
    302             } else if (!sal_strcasecmp(c, "cch")) {
    303                 soc_cancun_cch_t* cch = cc->cch;
    304                 soc_cancun_hash_table_t* hash_table_header;
    305                 uint32 i, j, mem_num, fld_num, list_buf[CANCUN_LIST_BUF_LEN];
    306 
    307                 if(cch == NULL) {
    308                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    309                          "CANCUN CCH is not initialized\n")));
    310                     return (CMD_FAIL);
    311                 } else if (cch->status != SOC_CANCUN_LOAD_STATUS_LOADED) {
    312                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    313                          "CANCUN CCH is not loaded\n")));
    314                     return (CMD_FAIL);
    315                 }
    316                 hash_table_header = (soc_cancun_hash_table_t*) cch->cch_table;
    317 
    318                 cli_out("%s: CCH debug information:\n", ARG_CMD(a));
    319                 cli_out("%s: CCH hash table\n", ARG_CMD(a));
    320                 cli_out("\tpA = %d\n", hash_table_header->pa);
    321                 cli_out("\tpB = %d\n", hash_table_header->pb);
    322                 cli_out("\tpC = %d\n", hash_table_header->pc);
    323                 cli_out("\tpD = %d\n", hash_table_header->pd);
    324                 cli_out("\tsize = %d\n", hash_table_header->table_size);
    325                 cli_out("\tCCH Coverage List = \n");
    326                 soc_cancun_cch_list (unit, list_buf, CANCUN_LIST_BUF_LEN);
    327                 p = list_buf;
    328                 mem_num = *p++;
    329                 for(i = 0; i < mem_num; i++) {
    330                     cli_out("\t%-20s\n", SOC_REG_NAME(unit, *p++));
    331                     fld_num = *p++;
    332                     for(j = 0; j < fld_num; j++) {
    333                         cli_out("\t |- %-20s\n", SOC_FIELD_NAME(unit, *p++));
    334                     }
    335                 }
    336 #if 0
    337                 cli_out("\tRaw data = \n");
    338                 p = &hash_table_header->table_entry;
    339                 if(p) {
    340                     for(i = 0; i < hash_table_header->table_size; i++) {
    341                         if((i % 10) == 0) {
    342                             cli_out("\n");
    343                         }
    344                         cli_out("%08X ", *p++);
    345                     }
    346                 }
    347                 cli_out("\n");
    348 #endif
    349             } else if (!sal_strcasecmp(c, "app")) {
    350                 int src_app = 0;
    351                 uint64 value;
    352                 int rv = 0;
    353 
    354                 COMPILER_64_ZERO(value);
    355 
    356                 c = ARG_GET(a);
    357                 if (!c || !isint(c)) {
    358                 LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    359                     "%s is not app\n"), c));
    360                     return (CMD_FAIL);
    361                 } else {
    362                     src_app = parse_integer(c);
    363                 }
    364 
    365                 c = ARG_GET(a);
    366                 if (!c || !isint(c)) {
    367                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    368                         "%s is not value\n"), c));
    369                     return (CMD_FAIL);
    370                 } else {
    371                     value = parse_uint64(c);
    372                 }
    373 
    374                 rv = soc_cancun_cch_app_set(unit, src_app, value);
    375                 if (rv != 0){
    376                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    377                         "CANCUN CCH APP(%d) CFG failed (%s)\n"), src_app, soc_errmsg(rv)));
    378                     return (CMD_FAIL);
    379                 };
    380             } else if (!sal_strcasecmp(c, "branch_id")) {
    381                 int cancun_type = 0;
    382                 int rv = 0;
    383                 soc_cancun_file_branch_id_e branch_id = 0;
    384 
    385                 c = ARG_GET(a);
    386                 if (!c || !isint(c)) {
    387                 LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    388                     "%s is not CANCUN type\n"), c));
    389                     return (CMD_FAIL);
    390                 } else {
    391                     cancun_type = parse_integer(c);
    392                 }
    393                 rv = soc_cancun_branch_id_get(unit, cancun_type, &branch_id);
    394                 if (rv != SOC_E_NONE){
    395                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    396                         "CANCUN (%s) branch_id get failed (%s)\n"),
    397                         soc_cancun_file_type_string[cancun_type], soc_errmsg(rv)));
    398                     return (CMD_FAIL);
    399                 } else {
    400                     cli_out("CANCUN (%s), branch_id(%d)\n",
    401                         soc_cancun_file_type_string[cancun_type], branch_id);
    402                 };
    403             } else if (!sal_strcasecmp(c, "udf")) {
    404                 uint8 stg;
    405                 uint32 srcapp = 0;
    406                 uint32 max_stages = 0;
    407                 uint32 stage_idx = 0;
    408                 soc_cancun_udf_stage_info_t stage_info_arr[10];
    409                 uint32 *hfe_prof_ptr_arr[2];
    410                 uint32 hfe_prof_ptr_arr_len[2] = {0};
    411                 int rv = 0;
    412 
    413                 c = ARG_GET(a);
    414                 if (!c || !isint(c)) {
    415                 LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    416                     "%s is not udf srcapp\n"), c));
    417                     return (CMD_FAIL);
    418                 } else {
    419                     srcapp = parse_integer(c);
    420                 }
    421                 c = ARG_GET(a);
    422                 if (!c || !isint(c)) {
    423                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    424                         "%s is not value\n"), c));
    425                     return (CMD_FAIL);
    426                 } else {
    427                     max_stages = parse_integer(c);
    428                 }
    429 
    430                 rv = soc_cancun_udf_abstr_type_info_get(unit, srcapp & 0xff,
    431                                                 (srcapp >> 16) & 0xff,
    432                                                 0, NULL, NULL,
    433                                                 &max_stages,
    434                                                 hfe_prof_ptr_arr_len);
    435                 if (rv == SOC_E_NONE){
    436                     for (stg = 0; stg < max_stages; stg++) {
    437                         hfe_prof_ptr_arr[stg] = NULL;
    438                         hfe_prof_ptr_arr[stg] =
    439                              sal_alloc(sizeof(uint32) * hfe_prof_ptr_arr_len[stg],
    440                                        "UDF Hfe Prof Ptr Alloc.");
    441                     }
    442 
    443                     rv = soc_cancun_udf_abstr_type_info_get(unit, srcapp & 0xff,
    444                         (srcapp >> 16) & 0xff, max_stages, hfe_prof_ptr_arr,
    445                          stage_info_arr, NULL, NULL);
    446                     if (rv != SOC_E_NONE){
    447                        for (stg = 0; stg < max_stages; stg++) {
    448                            sal_free(hfe_prof_ptr_arr[stg]);
    449                        }
    450                     }
    451                 }
    452                 if (rv != SOC_E_NONE){
    453                     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    454                         "CANCUN udf stage info get failed (%s)\n"),
    455                         soc_errmsg(rv)));
    456                     return (CMD_FAIL);
    457                 } else {
    458                     cli_out("CANCUN udf stage info:\n");
    459                     cli_out("size,policy_mem,hfe_profile_ptr, start_pos,flags\n");
    460                     for (stage_idx = 0; stage_idx < max_stages; stage_idx++) {
    461                         cli_out("%d,%s,%d,%d,%d\n",
    462                             stage_info_arr[stage_idx].size,
    463                             SOC_MEM_NAME(unit, stage_info_arr[stage_idx].policy_mem),
    464                             stage_info_arr[stage_idx].hfe_profile_ptr[0],
    465                             stage_info_arr[stage_idx].start_pos,
    466                             stage_info_arr[stage_idx].flags);
    467                     }
    468 
    469                     for (stg = 0; stg < max_stages; stg++) {
    470                         sal_free(hfe_prof_ptr_arr[stg]);
    471                     }
    472                 };
    473             } else {
    474                 LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    475                      "%s is not a supported input\n"), c));
    476                 return (CMD_FAIL);
    477             }
    478         }
    479     } else {
    480         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    481             "Unknown operation %s\n"), c));
    482         return(CMD_USAGE);
    483     }
    484 
    485     return (CMD_OK);
    486 }
    487 
    488 /*
    489  * Function:   _cmd_cancun_status
    490  * Purpose:    Get the CANCUN control structure of current unit and display
    491  * Parameters: unit - unit
    492  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE
    493  */
    494 cmd_result_t _cmd_cancun_status(int unit) {
    495     soc_cancun_t *cc;
    496     char ver_string[CANCUN_VERSION_LEN_MAX];
    497     char sdk_ver_string[CANCUN_VERSION_LEN_MAX];
    498 
    499     (void)soc_cancun_status_get(unit, &cc);
    500 
    501     if(cc == NULL) {
    502         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META(
    503             "CANCUN is not initialized\n")));
    504         return CMD_FAIL;
    505     }
    506 
    507     cli_out("UNIT%d CANCUN: ", cc->unit);
    508     if(cc->flags & SOC_CANCUN_FLAG_VERSIONS_MATCH) {
    509         cli_out("%08X", cc->version);
    510     }
    511     if(cc->flags & SOC_CANCUN_FLAG_DEBUG_MODE) {
    512         cli_out("\nDebug Mode: \t%s\n",
    513                 (cc->flags & SOC_CANCUN_FLAG_DEBUG_MODE)? "ON": "OFF");
    514         cli_out("Skip Validity:  %s\n",
    515                 (cc->flags & SOC_CANCUN_FLAG_SKIP_VALIDITY)? "ON": "OFF");
    516         if (soc_feature(unit,soc_feature_flex_flow)) {
    517             cli_out("Default Load:   %s%s%s%s%s\n",
    518                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CIH)? "CIH ": "",
    519                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CMH)? "CMH ": "",
    520                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CCH)? "CCH ": "",
    521                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CEH)? "CEH ": "",
    522                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CFH)? "CFH ": "");
    523         } else {
    524             cli_out("Default Load:   %s%s%s%s\n",
    525                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CIH)? "CIH ": "",
    526                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CMH)? "CMH ": "",
    527                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CCH)? "CCH ": "",
    528                    (cc->flags & SOC_CANCUN_FLAG_LOAD_DEFAULT_CEH)? "CEH ": "");
    529         }
    530 
    531         cli_out("REGFILE Ver:    %s\n", SOC_ORIGIN(unit));
    532     }
    533 
    534     if(cc->cih) {
    535         _cancun_version_string_get(ver_string, cc->cih->version);
    536 
    537         cli_out("\n\tCIH: %s\n",
    538                 soc_cancun_load_status_string[cc->cih->status]);
    539         if(cc->cih->status != CANCUN_SOC_FILE_LOAD_NONE) {
    540             cli_out("\tVer: %s\n", ver_string);
    541             _cancun_revision_print(cc->cih->version);
    542         }
    543         if(cc->cih->file.status != CANCUN_SOC_FILE_LOAD_NONE) {
    544             if(cc->flags & SOC_CANCUN_FLAG_DEBUG_MODE) {
    545                 cli_out("\t\t-Last Attempt-\n");
    546                 _cancun_file_info_print(&cc->cih->file, 0);
    547             }
    548         }
    549     }
    550 
    551     if(cc->cmh) {
    552         _cancun_version_string_get(ver_string, cc->cmh->version);
    553         _cancun_sdk_version_string_get(sdk_ver_string, cc->cmh->sdk_version);
    554 
    555         cli_out("\n\tCMH: %s\n",
    556                 soc_cancun_load_status_string[cc->cmh->status]);
    557         if(cc->cmh->status != CANCUN_SOC_FILE_LOAD_NONE) {
    558             cli_out("\tVer: %s\n", ver_string);
    559             _cancun_revision_print(cc->cmh->version);
    560             cli_out("\tSDK Ver: %s\n", sdk_ver_string);
    561         }
    562         if(cc->cmh->file.status != CANCUN_SOC_FILE_LOAD_NONE) {
    563             if(cc->flags & SOC_CANCUN_FLAG_DEBUG_MODE) {
    564                 cli_out("\t\t-Last Attempt-\n");
    565                 _cancun_file_info_print(&cc->cmh->file, 0);
    566             }
    567         }
    568     }
    569 
    570     if(cc->cch) {
    571         _cancun_version_string_get(ver_string, cc->cch->version);
    572         _cancun_sdk_version_string_get(sdk_ver_string, cc->cch->sdk_version);
    573 
    574         cli_out("\n\tCCH: %s\n",
    575                 soc_cancun_load_status_string[cc->cch->status]);
    576         if(cc->cch->status != CANCUN_SOC_FILE_LOAD_NONE) {
    577             cli_out("\tVer: %s\n", ver_string);
    578             _cancun_revision_print(cc->cch->version);
    579             cli_out("\tSDK Ver: %s\n", sdk_ver_string);
    580         }
    581         if(cc->cch->file.status != CANCUN_SOC_FILE_LOAD_NONE) {
    582             if(cc->flags & SOC_CANCUN_FLAG_DEBUG_MODE) {
    583                 cli_out("\t\t-Last Attempt-\n");
    584                 _cancun_file_info_print(&cc->cch->file, 0);
    585             }
    586         }
    587     }
    588    
    589     if(cc->ceh) {
    590         _cancun_version_string_get(ver_string, cc->ceh->version);
    591         _cancun_sdk_version_string_get(sdk_ver_string, cc->ceh->sdk_version);
    592 
    593         cli_out("\n\tCEH: %s\n",
    594                 soc_cancun_load_status_string[cc->ceh->status]);
    595         if(cc->ceh->status != CANCUN_SOC_FILE_LOAD_NONE) {
    596             cli_out("\tVer: %s\n", ver_string);
    597             _cancun_revision_print(cc->ceh->version);
    598             cli_out("\tSDK Ver: %s\n", sdk_ver_string);
    599         }
    600         if(cc->ceh->file.status != CANCUN_SOC_FILE_LOAD_NONE) {
    601             if(cc->flags & SOC_CANCUN_FLAG_DEBUG_MODE) {
    602                 cli_out("\t\t-Last Attempt-\n");
    603                 _cancun_file_info_print(&cc->ceh->file, 0);
    604             }
    605         }
    606     }
    607 
    608     if((soc_feature(unit,soc_feature_flex_flow)) &&
    609        (cc->flow_db)) {
    610         _cancun_version_string_get(ver_string, cc->flow_db->version);
    611 
    612         cli_out("\n\tCFH: %s\n",
    613                 soc_cancun_load_status_string[cc->flow_db->status]);
    614         if(cc->flow_db->status != CANCUN_SOC_FILE_LOAD_NONE) {
    615             cli_out("\tVer: %s\n", ver_string);
    616             _cancun_revision_print(cc->flow_db->version);
    617         }
    618         if(cc->flow_db->file.status != CANCUN_SOC_FILE_LOAD_NONE) {
    619             if(cc->flags & SOC_CANCUN_FLAG_DEBUG_MODE) {
    620                 cli_out("\t\t-Last Attempt-\n");
    621                 _cancun_file_info_print(&cc->flow_db->file, 0);
    622             }
    623         }
    624     }
    625 
    626     cli_out("\n");
    627 
    628     return CMD_OK;
    629 }
    630 
    631 /*
    632  * Function:   _cancun_file_info_print
    633  * Purpose:    Print CANCUN loadable file information
    634  * Parameters: ccf      - (IN) Pointer to a CANCUN file structure
    635  *             row_mode - (IN) Option to print information in brief row mode
    636  * Returns:
    637  */
    638 int _cancun_file_info_print(soc_cancun_file_t *ccf, int row_mode) {
    639     char ver_string[CANCUN_VERSION_LEN_MAX];
    640 
    641     if(ccf == NULL) return SOC_E_INTERNAL;
    642 
    643     _cancun_version_string_get(ver_string, ccf->header.version);
    644 
    645     if(row_mode) {
    646         cli_out("   %-50s %-7s %-8s %-11s  %s\n", ccf->filename,
    647                 soc_cancun_file_type_string[ccf->type],
    648                 soc_cancun_file_format_string[ccf->format],
    649                 ver_string,
    650                 (ccf->valid == 1)? "YES":"");
    651     } else {
    652         cli_out("\t\tFile:\t%s\n", ccf->filename);
    653         cli_out("\t\tVer:\t%s\n", ver_string);
    654         cli_out("\t\tType:\t%s\n",
    655                 soc_cancun_file_type_string[ccf->type]);
    656         cli_out("\t\tFormat:\t%s\n",
    657                 soc_cancun_file_format_string[ccf->format]);
    658         cli_out("\t\tLength:\t%dB\n", ccf->header.file_length * 4);
    659         cli_out("\t\tValid:\t%s\n", (ccf->valid)? "YES": "NO");
    660         cli_out("\t\tStatus:\t%s\n", soc_cancun_load_status_string[ccf->status]);
    661     }
    662 
    663     return SOC_E_NONE;
    664 }
    665 
    666 /*
    667  * Function:   _cmd_cancun_file_load
    668  * Purpose:    Load a CANCUN loadable file
    669  * Parameters:
    670  *             unit        - (IN) Device unit number
    671  *             filename    - (IN) Pointer to filename string
    672  *             file_type   - (IN) User input file type
    673  *             file_format - (IN) User input file format
    674  *             cc          - (OUT) Pointer to CANCUN control structure
    675  * Returns:
    676  */
    677 int _cmd_cancun_file_load(int unit, char* filename, uint32 file_type,
    678                           uint32 file_format, soc_cancun_t *cc) {
    679     int rv = SOC_E_NONE;
    680 #ifndef NO_FILEIO
    681     uint8 *file_buf = NULL;
    682     long file_len = 0;
    683     int filename_len;
    684     soc_cancun_file_t *ccf = NULL;
    685 
    686     /* filename length check */
    687     filename_len = sal_strlen(filename);
    688     if(filename_len > CANCUN_FILENAME_SIZE-1) {
    689         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    690             "input filename is too long (%d)\n"), filename_len));
    691         return SOC_E_PARAM;
    692     }
    693 
    694     /* open file and read into buffer */
    695     rv = _cancun_file_buffer_load(filename, &file_buf, &file_len);
    696     if(rv != SOC_E_NONE) {
    697         if(file_buf != NULL) {
    698             sal_free(file_buf);
    699         }
    700         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    701             "Fail to open/load file %s. (%s)\n"), filename, soc_errmsg(rv)));
    702         return (rv);
    703     }
    704 
    705     /* calling SOC API: soc_cancun_file_load */
    706     rv = soc_cancun_file_load(unit, file_buf, file_len, &file_type,
    707                               &file_format);
    708     if(rv != SOC_E_NONE) {
    709         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
    710             "Fail to load file %s. (%s)\n"), filename, soc_errmsg(rv)));
    711         goto _end__cmd_cancun_file_load;
    712     }
    713 
    714     /* can't update filename inside API so we have to take it here */
    715     if(file_type == CANCUN_SOC_FILE_TYPE_CIH) {
    716         ccf = &cc->cih->file;
    717     } else if (file_type == CANCUN_SOC_FILE_TYPE_CMH){
    718         ccf = &cc->cmh->file;
    719     } else if (file_type == CANCUN_SOC_FILE_TYPE_CCH){
    720         ccf = &cc->cch->file;
    721     } else if (file_type == CANCUN_SOC_FILE_TYPE_CEH){
    722         ccf = &cc->ceh->file;
    723     } else if (file_type == CANCUN_SOC_FILE_TYPE_CFH){
    724         ccf = &cc->flow_db->file;
    725     }
    726 
    727     if(ccf) {
    728         sal_strncpy(ccf->filename, filename, filename_len);
    729     }
    730 
    731 _end__cmd_cancun_file_load:
    732     if(file_buf) {
    733         sal_free(file_buf);
    734     }
    735 #else
    736     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit, "No file system\n")));
    737     return (CMD_FAIL);
    738 #endif /* NO_FILEIO */
    739 
    740     return (rv);
    741 }
    742 
    743 /*
    744  * Function:   _cancun_file_buffer_load
    745  * Purpose:    Allocate a buffer and load a CANCUN into it
    746  * Parameters:
    747  *             filename    - (IN) Pointer to filename string
    748  *             buf         - (OUT) Allocated buffer to hold file content
    749  *             buf_len     - (IN) Required buffer length in byte
    750  * Returns:
    751  */
    752 int _cancun_file_buffer_load(char *filename, uint8 **buf, long *buf_len) {
    753     int rv = SOC_E_NONE;
    754 
    755 #ifndef NO_FILEIO
    756     FILE *fp = NULL;
    757     fp = sal_fopen(filename, "rb");
    758     if (!fp) {
    759         rv = SOC_E_PARAM;
    760         goto _end__cancun_file_buffer_load;
    761     }
    762 
    763     if(sal_fseek(fp, 0L, SEEK_END) != 0) {
    764         rv = SOC_E_INTERNAL;
    765         goto _end__cancun_file_buffer_load;
    766     }
    767     *buf_len = ftell(fp);
    768     if(sal_fseek(fp, 0L, SEEK_SET) != 0) {
    769         rv = SOC_E_INTERNAL;
    770         goto _end__cancun_file_buffer_load;
    771     }
    772 
    773     *buf = (uint8*)sal_alloc(*buf_len, "soc_cancun_file_buf");
    774     if(*buf != NULL) {
    775         if(sal_fread(*buf, *buf_len, 1, fp) <= 0) {
    776             sal_free(buf);
    777             rv = SOC_E_INTERNAL;
    778             goto _end__cancun_file_buffer_load;
    779         }
    780     } else {
    781         rv = SOC_E_MEMORY;
    782     }
    783 
    784 _end__cancun_file_buffer_load:
    785     if(fp) {
    786         sal_fclose(fp);
    787     }
    788 #else
    789     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META("No file system\n")));
    790     return CMD_FAIL;
    791 #endif /* NO_FILEIO */
    792 
    793     return rv;
    794 }
    795 
    796 /*
    797  * Function:   _cancun_sdk_version_string_get
    798  * Purpose:    Convert and format SDK release version from uint32 to string
    799  * Parameters:
    800  *             sdk_ver_string - (OUT) Pointer to version string, end by '\0'
    801  *             ver            - (IN) Input CANCUN version number
    802  * Returns:
    803  *
    804  * Note:
    805  *      Input version format: 0XAABBCCDD
    806  *      AA: SDK release MAJOR version
    807  *      BB: SDK release MINOR version
    808  *      CC: SDK release BUILD version
    809  *      DD: Reserved
    810  */
    811 void _cancun_sdk_version_string_get(char* ver_string, uint32 ver) {
    812     char *p = ver_string;
    813     char buf_str[10];
    814     uint32 num;
    815     
    816     sal_memset(ver_string, 0, CANCUN_VERSION_LEN_MAX);
    817     
    818     num = (ver >> CANCUN_SDK_VERSION_OFFSET_MAJOR) & 0xFF;
    819     sal_itoa(buf_str, num, 10, 0, 2);
    820     sal_strcat(p, buf_str);
    821     sal_strcat(p, ".");
    822     
    823     num = (ver >> CANCUN_SDK_VERSION_OFFSET_MINOR) & 0xFF;
    824     sal_itoa(buf_str, num, 10, 0, 2);
    825     sal_strcat(p, buf_str);
    826     sal_strcat(p, ".");
    827     
    828     num = (ver >> CANCUN_SDK_VERSION_OFFSET_BUILD) & 0xFF;
    829     sal_itoa(buf_str, num, 10, 0, 2);
    830     sal_strcat(p, buf_str);
    831     
    832     sal_strcat(p, "\0");
    833 }
    834 
    835 /*
    836  * Function:   _cancun_version_string_get
    837  * Purpose:    Convert and format CANCUN version from uint32 to string
    838  * Parameters:
    839  *             ver_string  - (OUT) Pointer to version string, end by '\0'
    840  *             ver         - (IN) Input CANCUN version number
    841  * Returns:
    842  *
    843  * Note:
    844  *      Input version format: 0XAAEBCCDD
    845  *      AA : branch ID
    846  *      E  : revision
    847  *       B : major version
    848  *      CC:  minor version
    849  *      DD:  patch version
    850  */
    851 void _cancun_version_string_get(char* ver_string, uint32 ver) {
    852     char *p = ver_string;
    853     char buf_str[10];
    854     uint32 num;
    855 
    856     sal_memset(ver_string, 0, CANCUN_VERSION_LEN_MAX);
    857 
    858     num = (ver >> CANCUN_VERSION_OFFSET_BRANCH_ID) & 0xF;
    859     if (num == CANCUN_FILE_BRANCH_ID_DEF) {
    860         /* disaply nothing for default */
    861     } else if (num == CANCUN_FILE_BRANCH_ID_HGoE) {
    862         sal_strcat(p, "HGoE.");
    863     }
    864     else if (num == CANCUN_FILE_BRANCH_ID_GSH) {
    865         sal_strcat(p, "GSH.");
    866     } else {
    867         sal_strcat(p, "UNKONWN.");
    868     }
    869 
    870     num = (ver >> CANCUN_VERSION_OFFSET_MAJOR) & 0xF;
    871     sal_itoa(buf_str, num, 10, 0, 2);
    872     sal_strcat(p, buf_str);
    873     sal_strcat(p, ".");
    874 
    875     num = (ver >> CANCUN_VERSION_OFFSET_MINOR) & 0xFF;
    876     sal_itoa(buf_str, num, 10, 0, 2);
    877     sal_strcat(p, buf_str);
    878     sal_strcat(p, ".");
    879 
    880     num = (ver >> CANCUN_VERSION_OFFSET_PATCH) & 0xFF;
    881     sal_itoa(buf_str, num, 10, 0, 2);
    882     sal_strcat(p, buf_str);
    883 
    884     sal_strcat(p, "\0");
    885 }
    886 
    887 /*
    888  * Function:   _cancun_revision_print
    889  * Purpose:    Print revision based on CANCUN version
    890  * Parameters:
    891  *             ver         - (IN) Input CANCUN version number
    892  * Returns:
    893  *
    894  *      Input version format: 0XAAEBCCDD
    895  *      AA : branch ID
    896  *      E  : revision
    897  *       B : major version
    898  *      CC:  minor version
    899  *      DD:  patch version
    900 
    901  */
    902 void _cancun_revision_print(uint32 ver) {
    903     int revision =  (ver >> CANCUN_VERSION_OFFSET_REVISION) & 0xF;
    904 
    905     if (revision) {
    906         cli_out("\tRev: %d\n", revision);
    907     }
    908 }
    909 
    910 void _soc_cancun_default_filename(int unit, char *filename, int file_type) {
    911 #ifndef NO_FILEIO
    912 #define _SOC_CANCUN_DEFAULT_PATHS_NUM   (7)
    913 
    914     soc_cancun_t* cc;
    915     char *p = filename;
    916     int i, filepath_len;
    917     FILE *fp = NULL;
    918     char filepath[CANCUN_FILENAME_SIZE] = {0};
    919     char paths[_SOC_CANCUN_DEFAULT_PATHS_NUM][80] = \
    920                 {"../../rc/flex/", "../rc/flex", "rc/flex/", "flex/",
    921                  "../../../rc/flex/","../../../../rc/flex/", ""};
    922     int chipname_len = 0;
    923 
    924     if(soc_cancun_status_get(unit, &cc) != SOC_E_NONE) {
    925         return;
    926     }
    927 
    928     sal_strncpy(p, soc_chip_type_names[SOC_DRIVER(unit)->type], CANCUN_FILENAME_SIZE-1);
    929     sal_strcat(p, "_");
    930     sal_strcat(p, soc_cancun_file_type_string[file_type]);
    931     sal_strcat(p, ".pkg");
    932 
    933     do {
    934         *p = sal_tolower(*p);
    935     } while(*++p);
    936 
    937     filepath_len = sal_strlen(cc->default_path);
    938     chipname_len = sal_strlen(soc_chip_type_names[SOC_DRIVER(unit)->type]);
    939     if(filepath_len == 0) {
    940     /* searching default file path if not available */
    941         for(i = 0; i < _SOC_CANCUN_DEFAULT_PATHS_NUM; i++) {
    942             sal_strncpy(filepath, paths[i], CANCUN_FILENAME_SIZE-1);
    943             sal_strncat(filepath, filename, chipname_len);
    944             sal_strncat(filepath, "/default/", 9);
    945             sal_strncat(filepath, filename, CANCUN_FILENAME_SIZE-1);
    946             fp = sal_fopen(filepath, "rb");
    947             if (fp) {
    948                 sal_fclose(fp);
    949                 sal_getcwd(cc->default_path, CANCUN_FILENAME_SIZE-1);
    950                 sal_strcat(cc->default_path, paths[i]);
    951                 sal_strncat(cc->default_path, filename, chipname_len);
    952                 sal_strncat(cc->default_path, "/default/", 9);
    953                 break;
    954             }
    955         }
    956     } else {
    957         p = cc->default_path + filepath_len - 1;
    958         if(*p != '/') {
    959             sal_strcat(cc->default_path, "/");
    960         }
    961     }
    962 
    963     sal_strncpy(filepath, cc->default_path, CANCUN_FILENAME_SIZE-1);
    964     sal_strncat(filepath, filename, CANCUN_FILENAME_SIZE-1);
    965     sal_strncpy(filename, filepath, CANCUN_FILENAME_SIZE-1);
    966 
    967     return;
    968 #else
    969     LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit, "No file system\n")));
    970 #endif /* NO_FILEIO */
    971 }
    972 
    973 int _soc_cancun_dest_entry_print(soc_cancun_dest_entry_t *dest_entry) {
    974 
    975     int i, dest_mem;
    976 
    977     if(dest_entry == NULL) return SOC_E_INTERNAL;
    978 
    979     cli_out("CANCUN destination entry:\n");
    980     cli_out("\tIndex #: %d\n", dest_entry->dest_index_num);
    981     cli_out("\tField #: %d\n", dest_entry->dest_field_num);
    982 
    983     if(dest_entry->dest_index_num > 0) {
    984         cli_out("\tDestination Table Indices:\n");
    985         for(i = 0; i < dest_entry->dest_index_num; i++) {
    986             dest_mem = dest_entry->dest_mems[i];
    987             cli_out("\t\t%s: %d\n",
    988                     (dest_mem >= NUM_SOC_MEM)? SOC_REG_NAME(unit, dest_mem):
    989                                                SOC_MEM_NAME(unit, dest_mem),
    990                     dest_entry->dest_values[i]);
    991         }
    992     } else {
    993         cli_out("\tDestination Table, Field Values:\n");
    994         dest_mem = dest_entry->dest_mems[0];
    995         cli_out("\t\t%s\n",
    996                 (dest_mem >= NUM_SOC_MEM)? SOC_REG_NAME(unit, dest_mem):
    997                                            SOC_MEM_NAME(unit, dest_mem));
    998         for(i = 0; i < dest_entry->dest_field_num; i++) {
    999             cli_out("\t\t |- %s = %d\n",
   1000                     SOC_FIELD_NAME(unit, dest_entry->dest_fields[0]),
   1001                     dest_entry->dest_values[i]);
   1002         }
   1003     }
   1004 
   1005     return SOC_E_NONE;
   1006 }
   1007 
   1008 /*
   1009  * Function:   soc_cancun_generic_load
   1010  * Purpose:    Load cancun based on type
   1011  * Parameters:
   1012  *             unit        - (IN) Device unit number
   1013  *             cancun_type   - (IN)cancun_file_type
   1014  * Returns:
   1015  */
   1016 int soc_cancun_generic_load(int unit, uint32 cancun_type) {
   1017     int rv = SOC_E_NONE;
   1018 
   1019     if ((cancun_type < CANCUN_SOC_FILE_TYPE_CIH) ||
   1020         (cancun_type > CANCUN_SOC_FILE_TYPE_CEH)) {
   1021         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
   1022             "Unsupported cancun type\n")));
   1023         return SOC_E_PARAM;
   1024     }
   1025 
   1026 #ifndef NO_FILEIO
   1027     {
   1028         char filename[CANCUN_FILENAME_SIZE] = {0};
   1029         uint32 file_format = CANCUN_SOC_FILE_FORMAT_UNKNOWN;
   1030 
   1031         soc_cancun_t* cc;
   1032         rv = soc_cancun_status_get(unit, &cc);
   1033         if(rv != SOC_E_NONE) {
   1034             LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit,
   1035                 "can't get CANCUN status. (%s)\n"), soc_errmsg(rv)));
   1036             return rv;
   1037         }
   1038 
   1039         _soc_cancun_default_filename(unit, filename, cancun_type);
   1040 
   1041         rv = _cmd_cancun_file_load(unit, filename, cancun_type, file_format, cc);
   1042     }
   1043 #else
   1044     {
   1045         LOG_ERROR(BSL_LS_SOC_CANCUN, (BSL_META_U(unit, "No file system\n")));
   1046 
   1047         return SOC_E_UNAVAIL;
   1048     }
   1049 #endif
   1050 
   1051     return rv;
   1052 }
   1053 
   1054 #endif /* NO_SAL_APPL */