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