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

cmicx_schan.c (24827B)


      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  * S-Channel (internal command bus) support
      8  */
      9 
     10 #include <shared/bsl.h>
     11 #include <sal/core/libc.h>
     12 #include <sal/core/boot.h>
     13 #include <soc/debug.h>
     14 #include <soc/cm.h>
     15 #include <soc/error.h>
     16 #include <sal/core/sync.h>
     17 #include <soc/util.h>
     18 #include <soc/cmic.h>
     19 
     20 #ifdef BCM_CMICX_SUPPORT
     21 #include <soc/cmicx.h>
     22 #include <soc/intr_cmicx.h>
     23 #include <soc/schanmsg_internal.h>
     24 
     25 #ifdef BCM_SAND_SUPPORT
     26 #include <soc/sand/sand_aux_access.h>
     27 #endif
     28 
     29 #define SOC_SCHAN_POLL_WAIT_TIMEOUT 100
     30 
     31 
     32 typedef struct intr_data_s {
     33     sal_sem_t   schanIntr;
     34     int         ch;
     35 }intr_data_t;
     36 
     37 typedef struct soc_cmicx_schan_s {
     38     sal_spinlock_t   lock;
     39     int              timeout;
     40     int              ch_map;
     41     intr_data_t      intr[CMIC_SCHAN_NUM_MAX];
     42 }soc_cmicx_schan_t;
     43 
     44 
     45 STATIC soc_cmicx_schan_t _soc_cmicx_schan[SOC_MAX_NUM_DEVICES];
     46 
     47 #if defined BCM_DNX_SUPPORT && defined DNX_EMULATION_1_CORE
     48 STATIC int _adjust_2nd_core_sbus_access(schan_header_t *header, uint32 blk)
     49 {
     50     switch(header->v4.opcode) {
     51       case READ_REGISTER_CMD_MSG:
     52         /* No need for header->v4.opcode = READ_REGISTER_ACK_MSG; as a register is read */
     53         break;
     54       case READ_MEMORY_CMD_MSG:
     55         /* No need for header->v4.opcode = READ_MEMORY_ACK_MSG; as a memory is read*/
     56         break;
     57       /* writes that are not really performed do not require setting a returned opcode */
     58       default:
     59         header->v4.err = 0;
     60         return TRUE;
     61     }
     62     header->v4.dst_blk = blk >> 4;
     63     header->v4.acc_type = (blk & 0xf) << 1;
     64     return FALSE;
     65 }
     66 
     67 #define SET_V4_HEADER_DST_BLK_TYPE(blk_value_) \
     68     exit_now = _adjust_2nd_core_sbus_access(header, blk_value_); \
     69     break;
     70 
     71 #endif /* defined BCM_DNX_SUPPORT && defined DNX_EMULATION_1_CORE */
     72 
     73 
     74 /*******************************************
     75 * @function _soc_cmicx_schan_reset
     76 * purposeResets the CMICX S-Channel interface.
     77 *
     78 * @param unit [in] unit #
     79 * @param cmc [in] cmc number 0
     80 * @param ch [in] channel number 0-4
     81 *
     82 * @returns SOC_E_BUSY
     83 * @returns SOC_E_NONE
     84 *
     85 * @end
     86  */
     87 
     88 STATIC void
     89 _soc_cmicx_schan_reset(int unit, int cmc, int ch)
     90 {
     91     uint32 val;
     92 
     93     COMPILER_REFERENCE(cmc);
     94 
     95     val = soc_pci_read(unit, CMIC_COMMON_POOL_SCHAN_CHx_CTRL(ch));
     96     /* Toggle S-Channel abort bit in CMIC_SCHAN_CTRL register */
     97     soc_pci_write(unit, CMIC_COMMON_POOL_SCHAN_CHx_CTRL(ch),
     98                                        val | SC_CHx_SCHAN_ABORT);
     99     SDK_CONFIG_MEMORY_BARRIER;
    100     soc_pci_write(unit, CMIC_COMMON_POOL_SCHAN_CHx_CTRL(ch), val);
    101     SDK_CONFIG_MEMORY_BARRIER;
    102 
    103     if (SAL_BOOT_QUICKTURN) {
    104         /* Give Quickturn at least 2 cycles */
    105         sal_usleep(10 * MILLISECOND_USEC);
    106     }
    107 }
    108 
    109 
    110 /*******************************************
    111 * @function _soc_cmicx_schan_get
    112 * purpose get idle channel
    113 *
    114 * @param unit [in] unit #
    115 * @param ch [out] channel number 0-4
    116 *
    117 * @returns SOC_E_BUSY
    118 * @returns SOC_E_NONE
    119 *
    120 * @end
    121  */
    122 STATIC int _soc_cmicx_schan_get(int unit, int *ch)
    123 {
    124     int i;
    125     int rv = SOC_E_BUSY;
    126 
    127     soc_timeout_t to;
    128 
    129     soc_timeout_init(&to,  _soc_cmicx_schan[unit].timeout, 100);
    130 
    131     do {
    132        sal_spinlock_lock(_soc_cmicx_schan[unit].lock);
    133        for ( i = 0; i < CMIC_SCHAN_NUM_MAX; i++) {
    134            if (_soc_cmicx_schan[unit].ch_map & 0x01 << i) {
    135                rv = SOC_E_NONE;
    136                *ch = i;
    137                _soc_cmicx_schan[unit].ch_map &= ~(0x01 << i);
    138                break;
    139            }
    140        }
    141        sal_spinlock_unlock(_soc_cmicx_schan[unit].lock);
    142        if (rv == SOC_E_NONE)
    143           break;
    144 
    145     } while (!soc_timeout_check(&to));
    146     return rv;
    147 }
    148 
    149 
    150 /*******************************************
    151 * @function _soc_cmicx_schan_put
    152 * purpose get idle channel
    153 *
    154 * @param unit [in] unit #
    155 * @param ch [in] channel number 0-4
    156 *
    157 * @returns SOC_E_PARAM
    158 * @returns SOC_E_NONE
    159 
    160 *
    161 * @end
    162  */
    163 STATIC int _soc_cmicx_schan_put(int unit, int ch)
    164 {
    165    int rv = SOC_E_NONE;
    166 
    167    if ((ch < 0) || (ch > CMIC_SCHAN_NUM_MAX -1)) {
    168        rv = SOC_E_PARAM;
    169        return rv;
    170    }
    171    sal_spinlock_lock(_soc_cmicx_schan[unit].lock);
    172    _soc_cmicx_schan[unit].ch_map |= (0x01 << ch);
    173    sal_spinlock_unlock(_soc_cmicx_schan[unit].lock);
    174 
    175    return rv;
    176 }
    177 
    178 /*******************************************
    179 * @function _soc_cmicx_schan_cmic_err_handle
    180 * purpose Handle schan cimicx error
    181 *
    182 * @param unit [in] unit
    183 * @param schanCtrl [in] schan control word
    184 * @param ch [in] channel
    185 *
    186 * @returns SOC_E_XXX
    187 * @returns SOC_E_NONE
    188 *
    189 * @end
    190  */
    191 
    192 STATIC int
    193 _soc_cmicx_schan_err_handle(int unit, int schanCtrl, int ch)
    194 {
    195     int rv = SOC_E_NONE;
    196     uint32 schan_err = 0;
    197 
    198     if (schanCtrl & SC_CHx_MSG_NAK) {
    199         LOG_VERBOSE(BSL_LS_SOC_SCHAN,
    200                    (BSL_META_U(unit,
    201                    "NAK received from SCHAN.\n")));
    202         rv = SOC_E_FAIL;
    203     }
    204 
    205     if (schanCtrl & SC_CHx_MSG_SER_CHECK_FAIL) {
    206         LOG_ERROR(BSL_LS_SOC_SCHAN, (BSL_META_U(unit,
    207                   "SER Parity Check Error.\n")));
    208         rv = SOC_E_FAIL;
    209     }
    210 
    211     if (soc_feature(unit, soc_feature_schan_hw_timeout)) {
    212         if (schanCtrl & SC_CHx_MSG_TIMEOUT_TST) {
    213             LOG_ERROR(BSL_LS_SOC_SCHAN, (BSL_META_U(unit,
    214                       "Hardware Timeout Error.\n")));
    215             rv = SOC_E_TIMEOUT;
    216         }
    217     }
    218 
    219     if (soc_feature(unit, soc_feature_schan_err_check)) {
    220 
    221         if (schanCtrl & SC_CHx_MSG_SCHAN_ERR) {
    222             uint32 err_code, data_len, src_port, dst_port, op_code;
    223 
    224             schan_err = soc_pci_read(unit, CMIC_COMMON_POOL_SCHAN_CHx_ERR(ch));
    225 
    226             rv = SOC_E_FAIL;
    227 
    228             if (schan_err & SC_CHx_SCHAN_ERR_ERR_BIT) {
    229                 rv = SOC_E_TIMEOUT;
    230                 LOG_ERROR(BSL_LS_SOC_SCHAN, (BSL_META_U(unit,
    231                     "  block timeout: ERRBIT received in CMIC_SCHAN_ERR.\n")));
    232             }
    233 
    234             if (schan_err & SC_CHx_SCHAN_ERR_NACK_BIT) {
    235                 LOG_ERROR(BSL_LS_SOC_SCHAN, (BSL_META_U(unit,
    236                     "  NACK received in CMIC_SCHAN_ERR.\n")));
    237             }
    238 
    239             /* dump error data */
    240             err_code = soc_reg_field_get(unit, CMIC_COMMON_POOL_SCHAN_CH0_ERRr, schan_err, ERR_CODEf);
    241             data_len = soc_reg_field_get(unit, CMIC_COMMON_POOL_SCHAN_CH0_ERRr, schan_err, DATA_LENf);
    242             src_port = soc_reg_field_get(unit, CMIC_COMMON_POOL_SCHAN_CH0_ERRr, schan_err, SRC_PORTf);
    243             dst_port = soc_reg_field_get(unit, CMIC_COMMON_POOL_SCHAN_CH0_ERRr, schan_err, DST_PORTf);
    244             op_code = soc_reg_field_get(unit, CMIC_COMMON_POOL_SCHAN_CH0_ERRr, schan_err, OP_CODEf);
    245 
    246             LOG_ERROR(BSL_LS_SOC_SCHAN, (BSL_META_U(unit,"CMIC_SCHAN_ERR data dump: "
    247                     "err_code=%u, data_len=%u, src_port=%u, dst_port=%u, op_code=%u\n"),
    248                     err_code, data_len, src_port, dst_port, op_code));
    249         }
    250 
    251         soc_pci_write(unit, CMIC_COMMON_POOL_SCHAN_CHx_CTRL(ch), SC_CHx_MSG_CLR);
    252     }
    253 
    254     return rv;
    255 }
    256 
    257 /*******************************************
    258 * @function _soc_cmicx_schan_intr_wait
    259 * purpose On CMICX chips with schan interrupts
    260 *
    261 * @param unit [in] unit
    262 * @param ch [in] channel number 0-4
    263 *
    264 * @returns SOC_E_XXX
    265 * @returns SOC_E_XXX
    266 *
    267 * Commnet: Called when CMICX chips with schan interrupts
    268 * enabled, wait on a schan interrupt.
    269 * When schan interrupts are disabled,
    270 * _soc_cmicx_schan_poll_wait is called instead.
    271 
    272 * @end
    273  */
    274 STATIC int
    275 _soc_cmicx_schan_intr_wait(int unit, int ch)
    276 {
    277     int rv = SOC_E_NONE;
    278     uint32 schanCtrl;
    279     intr_data_t    *int_data;
    280 
    281     soc_cmic_intr_enable(unit, INTR_SCHAN(ch));
    282     int_data = &_soc_cmicx_schan[unit].intr[ch];
    283     if (sal_sem_take(int_data->schanIntr,
    284                      SOC_CONTROL(unit)->schanTimeout) != 0) {
    285         soc_cmic_intr_disable(unit, INTR_SCHAN(ch));
    286         rv = SOC_E_TIMEOUT;
    287     }
    288 
    289     if (rv != SOC_E_TIMEOUT) {
    290         LOG_VERBOSE(BSL_LS_SOC_SCHAN,
    291                  (BSL_META_U(unit,
    292                              "  Interrupt Done\n")));
    293         schanCtrl = soc_pci_read(unit, CMIC_COMMON_POOL_SCHAN_CHx_CTRL(ch));
    294         rv = _soc_cmicx_schan_err_handle(unit, schanCtrl, ch);
    295     }
    296     return rv;
    297 }
    298 
    299 /*******************************************
    300 * @function _soc_cmicx_schan_poll_wait
    301 * purpose On CMICX chips with no schan interrupts
    302 *
    303 * @param unit [in] unit
    304 * @param msg [in] message <schan_msg_t>
    305 * @param ch [in] channel number 0-4
    306 *
    307 * @returns SOC_E_XXX
    308 * @returns SOC_E_XXX
    309 *
    310 * Commnet: Called when CMICX chips with schan interrupts
    311 * disabled, wait on a schan interrupt.
    312 * When schan interrupts are enabled,
    313 * _soc_cmicx_schan_intr_wait is called instead.
    314 
    315 * @end
    316  */
    317 
    318 STATIC int
    319 _soc_cmicx_schan_poll_wait(int unit, schan_msg_t *msg, int ch)
    320 {
    321     int rv = SOC_E_NONE;
    322     soc_timeout_t to;
    323     uint32 schanCtrl;
    324 
    325     soc_timeout_init(&to, SOC_CONTROL(unit)->schanTimeout,
    326                      SOC_SCHAN_POLL_WAIT_TIMEOUT);
    327 
    328     LOG_VERBOSE(BSL_LS_SOC_SCHAN,
    329                  (BSL_META_U(unit,
    330                              "  Timeout= %d usec\n"),
    331                              SOC_CONTROL(unit)->schanTimeout));
    332 
    333     while (((schanCtrl = soc_pci_read(unit, CMIC_COMMON_POOL_SCHAN_CHx_CTRL(ch))) &
    334             SC_CHx_MSG_DONE) == 0) {
    335         if (soc_timeout_check(&to)) {
    336             rv = SOC_E_TIMEOUT;
    337             LOG_VERBOSE(BSL_LS_SOC_SCHAN, (BSL_META_U(unit,
    338               " schan control value 0x%x after timeout in %d polls\n"), schanCtrl, to.polls));
    339             break;
    340         }
    341     }
    342     /* Polling finished no timeout , check other errors */
    343     if (rv == SOC_E_NONE) {
    344         LOG_VERBOSE(BSL_LS_SOC_SCHAN,
    345                  (BSL_META_U(unit,
    346                              "  Done in %d polls\n"), to.polls));
    347         rv = _soc_cmicx_schan_err_handle(unit, schanCtrl, ch);
    348     }
    349 
    350     return rv;
    351 }
    352 
    353 /*******************************************
    354 * @function _soc_cmicx_schan_wait
    355 * purpose This waits for either interrupt or poll
    356 *
    357 * @param handle [in] unit
    358 * @param msg [in] SCHAN message pointer
    359 * @param dwc_write [in] Number of messages to write
    360 * @param dwc_read [in] Number of messages to read
    361 * @param intr [in] Interrupt
    362 * @param ch [in] channel number 0-4
    363 *
    364 * @returns SOC_E_NONE
    365 * @returns SOC_E_XXX
    366 *
    367 * @end
    368  */
    369 
    370 STATIC int _soc_cmicx_schan_wait(int unit,
    371                                  schan_msg_t *msg,
    372                                  int dwc_write,
    373                                  int dwc_read,
    374                                  int intr,
    375                                  int ch)
    376 {
    377     int i, rv;
    378 
    379     LOG_VERBOSE(BSL_LS_SOC_SCHAN,
    380                  (BSL_META_U(unit,
    381                              "  Enter\n")));
    382     do {
    383 
    384         /* Wait for completion using either the interrupt or polling method */
    385         if (intr && *(SOC_SCHAN_CONTROL(unit).schanIntrEnb)) {
    386             rv = _soc_cmicx_schan_intr_wait(unit, ch);
    387         } else {
    388             rv = _soc_cmicx_schan_poll_wait(unit, msg, ch);
    389         }
    390 
    391         if (soc_schan_timeout_check(unit, &rv, msg, -1, ch) == TRUE) {
    392             break;
    393         }
    394 
    395         /* Read in data from S-Channel buffer space, if any */
    396         for (i = 0; i < dwc_read; i++) {
    397             msg->dwords[i] =
    398                  soc_pci_read(unit, CMIC_COMMON_POOL_SCHAN_CHx_MESSAGEn(ch, i));
    399         }
    400 
    401         if (LOG_CHECK(BSL_LS_SOC_SCHAN | BSL_VERBOSE)) {
    402             soc_schan_dump(unit, msg, dwc_read);
    403         }
    404 
    405     } while(0);
    406 
    407     if (rv == SOC_E_TIMEOUT) {
    408         if (LOG_CHECK(BSL_LS_SOC_SCHAN | BSL_ERROR)) {
    409             LOG_ERROR(BSL_LS_SOC_SCHAN,
    410                       (BSL_META_U(unit,
    411                        "soc_cmicx_schan_op operation timed out\n")));
    412             soc_schan_dump(unit, msg, dwc_read);
    413         }
    414     }
    415 
    416     return rv;
    417 }
    418 
    419 /*******************************************
    420 * @function soc_cmicx_schan_op
    421 * purpose SDK-6 API used to initiate the schan operation
    422 *
    423 * @param handle [in] unit
    424 * @param msg [in] SCHAN message pointer
    425 * @param dwc_write [in] Number of messages to write
    426 * @param dwc_read [in] Number of messages to read
    427 * @param intr [in] Interrupt
    428 *
    429 * @returns SOC_E_NONE
    430 * @returns SOC_E_XXX
    431 *
    432 * @end
    433  */
    434 STATIC int
    435 _soc_cmicx_schan_op(
    436          int unit,
    437          schan_msg_t *msg,
    438          int dwc_write,
    439          int dwc_read,
    440          int intr)
    441 
    442 {
    443     int i, rv;
    444     int ch;
    445 
    446     LOG_VERBOSE(BSL_LS_SOC_SCHAN,
    447                  (BSL_META_U(unit,
    448                              "  Enter\n")));
    449 
    450 #if defined BCM_DNX_SUPPORT && defined DNX_EMULATION_1_CORE
    451     if (SOC_IS_JERICHO_2_A0(unit) && (soc_sand_is_emulation_system(unit)!= 0)) {
    452         uint32 sbus_blk_id;
    453         int exit_now = 0;
    454         schan_header_t *header = &(msg->header);
    455         sbus_blk_id = (header->v4.dst_blk << 4) |(header->v4.acc_type>>1);
    456         switch(sbus_blk_id) {
    457             /* core 1 doesn't exist, redirect to core 0 when reading, return OK when writing */
    458             case 97: SET_V4_HEADER_DST_BLK_TYPE(96 )/* KAPS1 */
    459             case 155: SET_V4_HEADER_DST_BLK_TYPE(36) /* IPPA1 */
    460             case 156: SET_V4_HEADER_DST_BLK_TYPE(37) /* IPPB1 */
    461             case 157: SET_V4_HEADER_DST_BLK_TYPE(38)  /* IPPC1 */
    462             case 158: SET_V4_HEADER_DST_BLK_TYPE(39)  /* IPPD1 */
    463             case 159: SET_V4_HEADER_DST_BLK_TYPE(40) /* IPPE1 */
    464             case 160: SET_V4_HEADER_DST_BLK_TYPE(41)  /* IPPF1 */
    465             case 120: SET_V4_HEADER_DST_BLK_TYPE(51)  /* CDUM1 */
    466             /* Should not be really needed */
    467             case 121: SET_V4_HEADER_DST_BLK_TYPE(53)  /* CDU5 */
    468             case 122: SET_V4_HEADER_DST_BLK_TYPE(53)  /* CDU6 */
    469             case 123: SET_V4_HEADER_DST_BLK_TYPE(53)  /* CDU7 */
    470             case 124: SET_V4_HEADER_DST_BLK_TYPE(53)  /* CDU8 */
    471             case 125: SET_V4_HEADER_DST_BLK_TYPE(53)  /* CDU9 */
    472             case 151: SET_V4_HEADER_DST_BLK_TYPE(32)  /* PEM4 */
    473             case 152: SET_V4_HEADER_DST_BLK_TYPE(33)  /* PEM5 */
    474             case 153: SET_V4_HEADER_DST_BLK_TYPE(34)  /* PEM6 */
    475             case 154: SET_V4_HEADER_DST_BLK_TYPE(35)  /* PEM7 */
    476 #ifdef JR2_PREVENT_ACCESS_TO_ADDITIONAL_BLOCKS
    477             case 384: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD3 */
    478             case 432: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD4 */
    479             case 480: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD5 */
    480             case 528: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD6 */
    481             case 576: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD7 */
    482             case 624: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD8 */
    483             case 672: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD9 */
    484             case 720: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD10 */
    485             case 768: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD11 */
    486             case 816: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD12 */
    487             case 864: SET_V4_HEADER_DST_BLK_TYPE(240)  /* FSRD13 */
    488             case 352: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC6 */
    489             case 368: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC7 */
    490             case 400: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC8 */
    491             case 416: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC9 */
    492             case 448: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC10 */
    493             case 464: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC11 */
    494             case 496: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC12 */
    495             case 512: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC13 */
    496             case 544: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC14 */
    497             case 560: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC15 */
    498             case 592: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC16 */
    499             case 608: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC17 */
    500             case 640: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC18 */
    501             case 656: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC19 */
    502             case 688: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC20 */
    503             case 704: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC21 */
    504             case 736: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC22 */
    505             case 752: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC23 */
    506             case 784: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC24 */
    507             case 800: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC25 */
    508             case 832: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC26 */
    509             case 848: SET_V4_HEADER_DST_BLK_TYPE(208)  /* FMAC27 */
    510             case 1792: SET_V4_HEADER_DST_BLK_TYPE(1072)  /* CDMAC12, CDMAC13, CDPORT6 */
    511             case 1808: SET_V4_HEADER_DST_BLK_TYPE(1072)  /* CDMAC14, CDMAC15, CDPORT7 */
    512             case 1824: SET_V4_HEADER_DST_BLK_TYPE(1072)  /* CDMAC16, CDMAC17, CDPORT8 */
    513             case 1840: SET_V4_HEADER_DST_BLK_TYPE(1072)  /* CDMAC18, CDMAC19, CDPORT9 */
    514             case 1856: SET_V4_HEADER_DST_BLK_TYPE(1072)  /* CDMAC20, CDMAC20, CDPORT10 */
    515             case 1872: SET_V4_HEADER_DST_BLK_TYPE(1072)  /* CDMAC22, CDMAC23, CDPORT11 */
    516 #endif /* JR2_PREVENT_ACCESS_TO_ADDITIONAL_BLOCKS */
    517             case 99: SET_V4_HEADER_DST_BLK_TYPE(98)  /* TCAM1 */
    518             case 131: SET_V4_HEADER_DST_BLK_TYPE(68)  /* IQM1 */
    519             case 161: SET_V4_HEADER_DST_BLK_TYPE(42)  /* ITPPD1 */
    520             case 162: SET_V4_HEADER_DST_BLK_TYPE(43)  /* ITPP1 */
    521             case 164: SET_V4_HEADER_DST_BLK_TYPE(45)  /* ETPPA1 */
    522             case 165: SET_V4_HEADER_DST_BLK_TYPE(46)  /* ETPPB1 */
    523             case 166: SET_V4_HEADER_DST_BLK_TYPE(47)  /* ETPPC1 */
    524             case 163: SET_V4_HEADER_DST_BLK_TYPE(44)  /* ERPP1 */
    525             case 150: SET_V4_HEADER_DST_BLK_TYPE(31)  /* EDB1 */
    526             case 132: SET_V4_HEADER_DST_BLK_TYPE(69)  /* DQM1 */
    527             case 136: SET_V4_HEADER_DST_BLK_TYPE(17)  /* CRPS1 */
    528             case 127: SET_V4_HEADER_DST_BLK_TYPE(64)  /* MRPS1 */
    529             case 143: SET_V4_HEADER_DST_BLK_TYPE(24)  /* EPNI1 */
    530             case 144: SET_V4_HEADER_DST_BLK_TYPE(25)  /* EPRE1 */
    531             case 145: SET_V4_HEADER_DST_BLK_TYPE(26)  /* ECGM1 */
    532             case 139: SET_V4_HEADER_DST_BLK_TYPE(20)  /* CGM1 */
    533             case 141: SET_V4_HEADER_DST_BLK_TYPE(22)  /* FDR1 */
    534             case 129: SET_V4_HEADER_DST_BLK_TYPE(66)  /* MCP1 */
    535             case 881: SET_V4_HEADER_DST_BLK_TYPE(880)  /* OCB1 */
    536             case 118: SET_V4_HEADER_DST_BLK_TYPE(48)  /* ILE1 */
    537             case 167: SET_V4_HEADER_DST_BLK_TYPE(63)  /* SCH1 */
    538             case 138: SET_V4_HEADER_DST_BLK_TYPE(19)  /* IPT1 */
    539             case 137: SET_V4_HEADER_DST_BLK_TYPE(18)  /* IPS1 */
    540             case 134: SET_V4_HEADER_DST_BLK_TYPE(71)  /* IRE1 */
    541             case 119: SET_V4_HEADER_DST_BLK_TYPE(49)  /* NMG1 */
    542             case 149: SET_V4_HEADER_DST_BLK_TYPE(30)  /* EPS1 */
    543             case 148: SET_V4_HEADER_DST_BLK_TYPE(29)  /* FQP1 */
    544             case 146: SET_V4_HEADER_DST_BLK_TYPE(27)  /* RQP1 */
    545             case 147: SET_V4_HEADER_DST_BLK_TYPE(28)  /* PQP1 */
    546             case 133: SET_V4_HEADER_DST_BLK_TYPE(70)  /* SQM1 */
    547             case 135: SET_V4_HEADER_DST_BLK_TYPE(16)  /* SPB1 */
    548             case 128: SET_V4_HEADER_DST_BLK_TYPE(65)  /* DDP1 */
    549             case 130: SET_V4_HEADER_DST_BLK_TYPE(67)  /* PDM1 */
    550             case 140: SET_V4_HEADER_DST_BLK_TYPE(21)  /* BDM1 */
    551             case 126: SET_V4_HEADER_DST_BLK_TYPE(62)  /* SIF1 */
    552             default:
    553                 break;
    554         }
    555         if (exit_now) {
    556             return SOC_E_NONE;
    557         }
    558     }
    559 #endif /* defined BCM_DNX_SUPPORT && defined DNX_EMULATION_1_CORE */
    560 
    561     if (soc_schan_op_sanity_check(unit, msg,
    562                    dwc_write, dwc_read, &rv) == TRUE) {
    563         return rv;
    564     }
    565 
    566     /* Get the free channel */
    567     rv = _soc_cmicx_schan_get(unit, &ch);
    568 
    569     if (rv != SOC_E_NONE) {
    570         LOG_ERROR(BSL_LS_SOC_SCHAN,
    571                  (BSL_META_U(unit,
    572                              "  Unable to assign channel\n")));
    573         return rv;
    574 
    575     }
    576 
    577     LOG_VERBOSE(BSL_LS_SOC_SCHAN,
    578                  (BSL_META_U(unit,
    579                              " Assign channel = %d\n"), ch));
    580 
    581     do {
    582         /* Write raw S-Channel Data: dwc_write words */
    583         for (i = 0; i < dwc_write; i++) {
    584             soc_pci_write(unit, CMIC_COMMON_POOL_SCHAN_CHx_MESSAGEn(ch, i),
    585                                             msg->dwords[i]);
    586         }
    587 
    588         /* Tell CMIC to start */
    589         soc_pci_write(unit, CMIC_COMMON_POOL_SCHAN_CHx_CTRL(ch),
    590                                             SC_CHx_MSG_START);
    591     } while(0);
    592 
    593     rv = _soc_cmicx_schan_wait(unit, msg, dwc_write, dwc_read, intr, ch);
    594 
    595     _soc_cmicx_schan_put(unit, ch);
    596 
    597    return rv;
    598 }
    599 
    600 /*******************************************
    601 * @function _cmicx_schan_ch_done
    602 * Interrupt handler for schan channel done
    603 *
    604 * @param unit [in] unit
    605 * @param data [in] pointer provided during registration
    606 *
    607 *
    608 * @end
    609  */
    610 STATIC void
    611 _cmicx_schan_ch_done(int unit, void *data)
    612 {
    613     soc_control_t *soc = SOC_CONTROL(unit);
    614     intr_data_t *in_d = (intr_data_t *)data;
    615 
    616     if (soc->schanIntrEnb) {
    617         soc_cmic_intr_disable(unit, INTR_SCHAN(in_d->ch));
    618         sal_sem_give(in_d->schanIntr);
    619     }
    620 }
    621 
    622 /*******************************************
    623 * @function _cmicx_schan_intr_deinit
    624 * purpose API to de-Initialize SCHAN interrupts
    625 *
    626 * @param unit [in] unit
    627 *
    628 * @returns SOC_E_NONE
    629 * @returns SOC_E_XXX
    630 *
    631 * @end
    632  */
    633 STATIC int
    634 _cmicx_schan_intr_deinit(int unit)
    635 {
    636     int ch;
    637     intr_data_t    *int_data;
    638     for (ch = 0; ch < CMIC_SCHAN_NUM_MAX; ch++) {
    639         int_data = &_soc_cmicx_schan[unit].intr[ch];
    640         if (int_data->schanIntr) {
    641              sal_sem_destroy(int_data->schanIntr);
    642         }
    643     }
    644 
    645     return SOC_E_NONE;
    646 }
    647 
    648 /*******************************************
    649 * @function _cmicx_schan_intr_init
    650 * purpose API to Initialize SCHAN interrupts
    651 *
    652 * @param unit [in] unit
    653 *
    654 * @returns SOC_E_NONE
    655 * @returns SOC_E_XXX
    656 *
    657 * @end
    658  */
    659 STATIC int
    660 _cmicx_schan_intr_init(int unit)
    661 {
    662     int ch;
    663     soc_cmic_intr_handler_t *handle;
    664     soc_cmic_intr_handler_t *hitr;
    665     intr_data_t    *int_data;
    666     int rv = SOC_E_NONE;
    667 
    668 
    669     /* Register interrupts */
    670     handle = sal_alloc(CMIC_SCHAN_NUM_MAX * sizeof(soc_cmic_intr_handler_t),
    671                         "schan_interrupt");
    672     if (handle == NULL) {
    673         return SOC_E_MEMORY;
    674     }
    675 
    676     hitr = handle;
    677     for (ch = 0; ch < CMIC_SCHAN_NUM_MAX; ch++) {
    678          int_data = &_soc_cmicx_schan[unit].intr[ch];
    679          int_data->schanIntr =
    680                          sal_sem_create("SCHAN interrupt",
    681                                         sal_sem_BINARY, 0);
    682          if (int_data->schanIntr == NULL) {
    683              _cmicx_schan_intr_deinit(unit);
    684              rv = SOC_E_MEMORY;
    685              goto error;
    686          }
    687          int_data->ch = ch;
    688          hitr->num = INTR_SCHAN(ch);
    689          hitr->intr_fn = _cmicx_schan_ch_done;
    690          hitr->intr_data = int_data;
    691          hitr++;
    692     }
    693     rv = soc_cmic_intr_register(unit, handle, CMIC_SCHAN_NUM_MAX);
    694 error:
    695     sal_free(handle);
    696 
    697     return rv;
    698 }
    699 
    700 
    701 /*******************************************
    702 * @function _soc_cmicx_schan_deinit
    703 * purpose API to de-Initialize SCHAN
    704 *
    705 * @param unit [in] unit
    706 *
    707 * @returns SOC_E_NONE
    708 * @returns SOC_E_XXX
    709 *
    710 * @end
    711  */
    712 STATIC int
    713 _soc_cmicx_schan_deinit(int unit)
    714 {
    715    int ch;
    716 
    717    _cmicx_schan_intr_deinit(unit);
    718 
    719    /* reset all th schan channels */
    720    for (ch = 0 ; ch < CMIC_SCHAN_NUM_MAX; ch++) {
    721        _soc_cmicx_schan_reset(unit, -1, ch);
    722    }
    723    sal_spinlock_destroy(_soc_cmicx_schan[unit].lock);
    724 
    725    return SOC_E_NONE;
    726 }
    727 
    728 /*******************************************
    729 * @function soc_cmicx_schan_init
    730 * purpose API to Initialize cmicx SCHAN
    731 *
    732 * @param unit [in] unit
    733 * @param drv [out] soc_cmic_schan_drv_t pointer
    734 *
    735 * @returns SOC_E_NONE
    736 * @returns SOC_E_XXX
    737 *
    738 * @end
    739  */
    740 int soc_cmicx_schan_init(int unit, soc_cmic_schan_drv_t *drv)
    741 
    742 {
    743    int rv = SOC_E_NONE;
    744 
    745 #if defined(PLISIM) && (defined(BCM_DNX_SUPPORT) || defined(BCM_DNXF_SUPPORT))
    746         if (SAL_BOOT_PLISIM && (SOC_IS_DNX(unit)|| SOC_IS_DNXF(unit))) {
    747             /* Use CMICM simulation instead of CMICX simulation */
    748             return soc_cmicm_schan_init(unit, drv);
    749         }
    750 #endif
    751 
    752    sal_memset(&_soc_cmicx_schan[unit], 0, sizeof(soc_cmicx_schan_t));
    753    _soc_cmicx_schan[unit].lock = sal_spinlock_create("schan Lock");
    754 
    755    if (_soc_cmicx_schan[unit].lock == NULL) {
    756         return SOC_E_MEMORY;
    757    }
    758 
    759    _soc_cmicx_schan[unit].ch_map = (0x01 << CMIC_SCHAN_NUM_MAX) -1;
    760    _soc_cmicx_schan[unit].timeout = SOC_CONTROL(unit)->schanTimeout;
    761    /* program SBUS_RING_MAP registers */
    762 
    763    /* Program SCHAN ARB Weighted priority
    764     * CMIC_TOP_SBUS_RING_ARB_CTRL_SCHAN_BASE  12'h04c */
    765 
    766    /* Configure CMIC_SBUS_TIMEOUT */
    767    rv = _cmicx_schan_intr_init(unit);
    768 
    769    if (SOC_FAILURE(rv)) {
    770        _soc_cmicx_schan_deinit(unit);
    771        return rv;
    772    }
    773 
    774    drv->soc_schan_deinit = _soc_cmicx_schan_deinit;
    775    drv->soc_schan_op = _soc_cmicx_schan_op;
    776    drv->soc_schan_reset = _soc_cmicx_schan_reset;
    777 
    778    return rv;
    779 }
    780 
    781 
    782 #endif /* BCM_CMICX_SUPPORT  */