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

soc_schan_fifo.c (9277B)


      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:        soc_schan_fifo.c
      8  * Purpose:     SOC Schan-FIFO driver, supports both sync and async modes.
      9  */
     10 
     11 #include <shared/bsl.h>
     12 #include <shared/alloc.h>
     13 #include <soc/drv.h>
     14 #include <soc/debug.h>
     15 #include <soc/cm.h>
     16 #include <soc/soc_schan_fifo_internal.h>
     17 
     18 
     19 STATIC soc_schan_fifo_drv_t     _schan_fifo_drv[SOC_MAX_NUM_DEVICES];
     20 
     21 #ifdef BCM_SOC_ASYNC_SUPPORT
     22 
     23 /*******************************************
     24 * @function _soc_schan_fifo_cb_f
     25 * purpose this function calls used defined callback
     26 *
     27 * @param unit [in] unit #
     28 * @param data [in] User parameter
     29 * @param cookie [in] user/driver data
     30 * @param cookie [in] status
     31 *
     32 * @end
     33  */
     34 STATIC void
     35 _soc_schan_fifo_cb_f(int unit,
     36                     void *data, void *cookie, int status)
     37 {
     38     soc_schan_fifo_wparam_t *wparam;
     39 
     40     wparam = (soc_schan_fifo_wparam_t *)cookie;
     41     if (wparam) {
     42         wparam->cb_f(unit, data, wparam->cookie, status);
     43         sal_free(wparam);
     44     }
     45 }
     46 
     47 /*******************************************
     48 * @function _soc_schan_fifo_msg_alloc
     49 * purpose this function to initialize sbuus message
     50 *
     51 * @param unit [in] unit #
     52 * @param msg [in, out] pointer to pointer soc_async_msg_t
     53 * @param param [in] user data pointer
     54 * @param cookie [in]cookie pointer
     55 * @param cbf [in] user call back function
     56 *
     57 * @returns SOC_E_BUSY
     58 * @returns SOC_E_MEMORY
     59 * @end
     60  */
     61 STATIC int
     62 _soc_schan_fifo_msg_alloc(int unit,
     63                      soc_async_msg_t  **msg,
     64                      soc_schan_fifo_msg_t *param,
     65                      void *cookie,
     66                      soc_async_cb_f   cbf)
     67 {
     68     soc_schan_fifo_wparam_t *wparam;
     69     soc_schan_fifo_drv_op_t *op = &_schan_fifo_drv[unit].op;
     70 
     71     wparam = sal_alloc(sizeof(soc_schan_fifo_wparam_t),
     72                        "soc_schan_fifo_wparam");
     73 
     74     if(!wparam) {
     75         return SOC_E_MEMORY;
     76     }
     77 
     78     if (SOC_FAILURE(soc_async_msg_alloc(
     79                 _schan_fifo_drv[unit].handle, msg))) {
     80         sal_free(wparam);
     81         return SOC_E_MEMORY;
     82     }
     83     (*msg)->unit = unit;
     84     (*msg)->type = p_schan_fifo;
     85     (*msg)->data = param;
     86     (*msg)->cookie = wparam;
     87     (*msg)->proc_f = op->soc_schan_fifo_op_prog;
     88     (*msg)->wait_f = op->soc_schan_fifo_op_complete;
     89     (*msg)->cb_f = _soc_schan_fifo_cb_f;
     90     wparam->cb_f = cbf;
     91     wparam->cookie = cookie;
     92 
     93     return SOC_E_NONE;
     94 }
     95 
     96 /*******************************************
     97 * @function _soc_schan_fifo_msg_free
     98 * purpose this function to initialize sbuus message
     99 *
    100 * @param unit [in] unit #
    101 * @param msg [in] pointer to soc_async_msg_t
    102 *
    103 * @returns SOC_E_BUSY
    104 * @returns SOC_E_MEMORY
    105 * @end
    106  */
    107 STATIC int
    108 _soc_schan_fifo_msg_free(int unit,
    109                      soc_async_msg_t  *msg)
    110 {
    111    soc_schan_fifo_wparam_t *wparam = NULL;
    112 
    113    if (msg == NULL)
    114        return SOC_E_PARAM;
    115 
    116    wparam = (soc_schan_fifo_wparam_t *)msg->cookie;
    117 
    118    if (wparam) {
    119        sal_free(wparam);
    120    }
    121 
    122    soc_async_msg_free(_schan_fifo_drv[unit].handle, msg);
    123 
    124    return SOC_E_NONE;
    125 }
    126 
    127 #endif
    128 /*******************************************
    129 * @function soc_schan_fifo_msg_send
    130 * purpose cmic SCHAN FIFO operation
    131 *
    132 * @param unit [in] unit
    133 * @param msg [in, out] soc_schan_fifo_msg_t
    134 * @param cookie [in] pointer to void, user data
    135 * @param cbf [in] soc_async_cb_f, call back function
    136 *
    137 * @returns SOC_E_NONE
    138 * @returns SOC_E_XXX
    139  */
    140 extern int
    141 soc_schan_fifo_msg_send(int unit,
    142              soc_schan_fifo_msg_t *msg,
    143              void *cookie,
    144              soc_async_cb_f cbf)
    145 {
    146     int rv = SOC_E_NONE;
    147 
    148     LOG_VERBOSE(BSL_LS_SOC_SCHANFIFO,
    149                  (BSL_META_U(unit,
    150                              "  Enter: soc_schan_fifo_msg_send\n")));
    151 
    152 #ifdef BCM_SOC_ASYNC_SUPPORT
    153     /* If callback is defined it is async call */
    154     if (cbf != NULL) {
    155         soc_async_msg_t  *async_m;
    156         rv = _soc_schan_fifo_msg_alloc(unit, &async_m, msg, cookie, cbf);
    157         if (rv == SOC_E_NONE) {
    158             if (_schan_fifo_drv[unit].handle) {
    159                 rv = soc_async_msg_queue(
    160                         _schan_fifo_drv[unit].handle, async_m);
    161                 if (SOC_FAILURE(rv)) {
    162                         LOG_ERROR(BSL_LS_SOC_SCHANFIFO,
    163                                   (BSL_META_U(unit,
    164                                               " Unable to Queue = %d\n"), rv));
    165                     (void)_soc_schan_fifo_msg_free(unit, async_m);
    166                 }
    167             } else {
    168                rv = SOC_E_INIT;
    169             }
    170         }
    171 
    172     }
    173     else
    174 #endif
    175     {
    176         soc_schan_fifo_wparam_t wparam;
    177         soc_schan_fifo_drv_op_t *op = &_schan_fifo_drv[unit].op;
    178 
    179         if (op->soc_schan_fifo_op_prog != NULL) {
    180             rv = op->soc_schan_fifo_op_prog(unit, msg, &wparam);
    181         } else {
    182             rv = SOC_E_INIT;
    183         }
    184         if (rv == SOC_E_NONE) {
    185             if (op->soc_schan_fifo_op_complete != NULL) {
    186                 rv = op->soc_schan_fifo_op_complete(unit,
    187                                               msg, &wparam);
    188             } else {
    189                 rv = SOC_E_INIT;
    190             }
    191         }
    192     }
    193 /*
    194  * COVERITY
    195  * The allocated message memory (async_m )is freed in Async Module
    196  */
    197  /* coverity[leaked_storage: FALSE] */
    198 
    199     return rv;
    200 
    201 }
    202 
    203 /*******************************************
    204 * @function soc_schan_fifo_control
    205 * purpose API to control SCHAN FIFO
    206 *
    207 * @param unit [in] unit
    208 * @param ctl [in] schan_fifo_ctl_t
    209 * @param data [in, out] pointer to void
    210 *
    211 * @returns SOC_E_NONE
    212 *
    213 * @end
    214  */
    215 int
    216 soc_schan_fifo_control(int unit,
    217                  schan_fifo_ctl_t ctl, void *data)
    218 {
    219     soc_schan_fifo_drv_op_t *op = &_schan_fifo_drv[unit].op;
    220 
    221     switch (ctl) {
    222 #ifdef BCM_SOC_ASYNC_SUPPORT
    223         case CTL_FIFO_START:
    224             if (_schan_fifo_drv[unit].handle) {
    225                 soc_async_msg_start(_schan_fifo_drv[unit].handle);
    226             }
    227         break;
    228         case CTL_FIFO_STOP:
    229             if (_schan_fifo_drv[unit].handle) {
    230                 soc_async_msg_stop(_schan_fifo_drv[unit].handle);
    231             }
    232         break;
    233         case CTL_FIFO_ABORT:
    234 
    235             if (_schan_fifo_drv[unit].handle) {
    236                 soc_async_flush_queue(_schan_fifo_drv[unit].handle);
    237             }
    238             if (op->soc_schan_fifo_control) {
    239                 (void)op->soc_schan_fifo_control(unit, ctl, NULL);
    240             }
    241 
    242         break;
    243         case CTL_FIFO_FLUSH:
    244 
    245             if (_schan_fifo_drv[unit].handle) {
    246                 soc_async_flush_queue(_schan_fifo_drv[unit].handle);
    247             }
    248 
    249         break;
    250 #endif
    251         case CTL_FIFO_MAX_MSG_GET:
    252         case CTL_FIFO_RESP_ALLOC:
    253         case CTL_FIFO_RESP_FREE:
    254             if (op->soc_schan_fifo_control) {
    255                 (void)op->soc_schan_fifo_control(unit, ctl, data);
    256             }
    257         break;
    258 
    259         default:
    260             LOG_VERBOSE(BSL_LS_SOC_SCHANFIFO,
    261               (BSL_META_U(unit,":undefined control command = %d\n"), ctl));
    262         break;
    263 
    264     }
    265 
    266     return SOC_E_NONE;
    267 }
    268 
    269 /*******************************************
    270 * @function soc_schan_fifo_deinit
    271 * purpose API to deInitialize and config SCHAN FIFO
    272 * It will abort the current operation, flush the queue
    273 * and release all the resources.
    274 *
    275 * @param unit [in] unit
    276 *
    277 * @returns SOC_E_NONE
    278 *
    279 * @end
    280  */
    281 extern int
    282 soc_schan_fifo_deinit(int unit)
    283 {
    284    soc_schan_fifo_drv_op_t *op = &_schan_fifo_drv[unit].op;
    285 
    286    if (op->soc_schan_fifo_deinit) {
    287        (void)op->soc_schan_fifo_deinit(unit);
    288    }
    289 #ifdef BCM_SOC_ASYNC_SUPPORT
    290    if (_schan_fifo_drv[unit].handle) {
    291        (void)soc_async_proc_deinit(_schan_fifo_drv[unit].handle);
    292        _schan_fifo_drv[unit].handle = NULL;
    293    }
    294 #endif
    295    return SOC_E_NONE;
    296 }
    297 
    298 /*******************************************
    299 * @function soc_schan_fifo_init
    300 * purpose API to Initialize and config SCHAN FIFO
    301 * It will initialize the SCHAN FIFO hardware and
    302 * allocate resources for async operation.
    303 * In case of sync only set soc_async_prop_t pointer
    304 * to be NULL.
    305 *
    306 * @param unit [in] unit
    307 * @param prop [in] pointer to soc_async_prop_t
    308 * @param config [in] pointer to soc_schan_fifo_config_t
    309 *
    310 * @returns SOC_E_NONE
    311 * @returns SOC_E_XXX
    312 *
    313 * @end
    314  */
    315 extern int
    316 soc_schan_fifo_init(int unit,
    317                    soc_async_prop_t  *prop,
    318                    soc_schan_fifo_config_t *config)
    319 {
    320     int rv = SOC_E_NONE;
    321 
    322     /* Cleanup if already initialized */
    323     soc_schan_fifo_deinit(unit);
    324 
    325 #ifdef BCM_CMICX_SUPPORT
    326     if (soc_feature(unit, soc_feature_cmicx)) {
    327         SOC_IF_ERROR_RETURN(soc_cmicx_schan_fifo_init(unit,
    328                                 &_schan_fifo_drv[unit].op, config));
    329     }
    330 #endif
    331 
    332 #ifdef BCM_SOC_ASYNC_SUPPORT
    333     /* check if async support is needed */
    334     if (!prop) {
    335         return SOC_E_NONE;
    336     }
    337     rv = soc_async_proc_init(
    338                   unit,
    339                   prop,
    340                   &_schan_fifo_drv[unit].handle);
    341 
    342     if (rv != SOC_E_NONE) {
    343         LOG_ERROR(BSL_LS_SOC_SCHANFIFO,
    344               (BSL_META_U(unit,
    345                  "Failed to initialize Async Proc =%d\n"), rv));
    346         (void)soc_schan_fifo_deinit(unit);
    347         return rv;
    348     }
    349 #endif
    350     LOG_VERBOSE(BSL_LS_SOC_SCHANFIFO,
    351               (BSL_META_U(unit,":SUCCESS\n")));
    352 
    353     return rv;
    354 
    355 }
    356