]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/bcp/src/bcp.c
bcp-lld: add to PDK
[processor-sdk/pdk.git] / packages / ti / drv / bcp / src / bcp.c
1 /** \r
2  *   @file  bcp.c\r
3  *\r
4  *   @brief  \r
5  *      This file contains the BCP driver's higher layer API implementations.\r
6  *\r
7  *      The BCP Higher Layer presents a useful set of APIs to send/receive\r
8  *      data from BCP.\r
9  * \r
10  *  ============================================================================\r
11  *  @n   (C) Copyright 2010, Texas Instruments, Inc.\r
12  * \r
13  *  Redistribution and use in source and binary forms, with or without \r
14  *  modification, are permitted provided that the following conditions \r
15  *  are met:\r
16  *\r
17  *    Redistributions of source code must retain the above copyright \r
18  *    notice, this list of conditions and the following disclaimer.\r
19  *\r
20  *    Redistributions in binary form must reproduce the above copyright\r
21  *    notice, this list of conditions and the following disclaimer in the \r
22  *    documentation and/or other materials provided with the   \r
23  *    distribution.\r
24  *\r
25  *    Neither the name of Texas Instruments Incorporated nor the names of\r
26  *    its contributors may be used to endorse or promote products derived\r
27  *    from this software without specific prior written permission.\r
28  *\r
29  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
30  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
31  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
32  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
33  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
34  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
36  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
37  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
38  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
39  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
40  *  ============================================================================\r
41  *\r
42 */\r
43 /* BCP types include */\r
44 #include <bcp_types.h>\r
45 \r
46 /* BCP OSAL include */\r
47 #include <bcp_osal.h>\r
48 \r
49 /* BCP include */\r
50 #include <ti/drv/bcp/bcp.h>\r
51 \r
52 /* BCP private definitions include file */\r
53 #include <ti/drv/bcp/include/bcp_pvt.h>\r
54 \r
55 /* Standard C definitions include */\r
56 #include <string.h>\r
57 \r
58 /***************************************************************\r
59  ******************** GLOBAL VARIABLES *************************\r
60  **************************************************************/\r
61 \r
62 /** Global variable to hold the BCP driver' state info */\r
63 extern Bcp_InstanceInfo         gBcp_instanceInfo [BCP_MAX_NUM_INSTANCES];\r
64 \r
65 /** @addtogroup BCP_FUNCTION\r
66  @{ */\r
67 \r
68 /***************************************************************\r
69  ******************** BCP Internal APIs ************************\r
70  **************************************************************/\r
71 \r
72 /**\r
73 * ============================================================================\r
74 *  @n@b Bcp_txQueueOpen\r
75 *\r
76 *  @b   brief\r
77 *  @n   If not already open, this API sets up the BCP Transmit queue corresponding \r
78 *       to the queue number specified in 'bcpTxQNum' (valid values 0-8) and the\r
79 *       BCP instance specified by 'pBcpInstInfo' handle. If open already, the \r
80 *       queue configuration is skipped.\r
81 *\r
82 *       As part of the queue configuration this API opens the CPPI queue, and the\r
83 *       corresponding Tx, Rx channels.\r
84 *\r
85 *  @param[in]\r
86 *       pBcpInstInfo        BCP instance information handle.\r
87 *\r
88 *  @param[in]\r
89 *       bcpTxQNum           BCP Transmit queue number for which the setup needs \r
90 *                           to be performed. Valid values are between 0-8.\r
91 *\r
92 *  @return     Bcp_TxQInfo*\r
93 *  @li         NULL         -   Tx queue setup failed as per input provided.\r
94 *  @li         Valid Handle -   Success. Valid Tx queue handle returned.\r
95 *\r
96 *  @pre\r
97 *  @n   @a Bcp_open () API must have been called to initialize the driver's\r
98 *       global state before calling this API.\r
99 *\r
100 *  @post\r
101 *  @n   BCP Queue 'bcpTxQNum' opened and the corresponding CPPI channels are \r
102 *       opened too if called for the first time. Reference counter for the \r
103 *       queue is incremented to keep track of all the application threads \r
104 *       using this queue.\r
105 * ============================================================================\r
106 */\r
107 static Bcp_TxQInfo* Bcp_txQueueOpen\r
108 (\r
109     Bcp_InstanceInfo*           pBcpInstInfo,\r
110     Bcp_QueueId                 bcpTxQNum\r
111 )\r
112 {\r
113     uint8_t                     isAllocated;        \r
114     Cppi_TxChInitCfg            txChCfg;\r
115     Qmss_QueueHnd               hQmssTxQ = (Qmss_QueueHnd)NULL;\r
116     Cppi_ChHnd                  hCppiTxChan = NULL;  \r
117     void*                       hBcpTxQueueInfo;\r
118     uint8_t                     destSel [8], prioVal [8];\r
119 \r
120     /* If this is the first time we are initializing this the BCP transmit queue,\r
121      * setup the configuration, otherwise just increment the reference count\r
122      * and return the queue handle.\r
123      */\r
124     if (!pBcpInstInfo->Bcp_txQInfo[bcpTxQNum].refCnt)\r
125     {\r
126         /* Setup and open the Tx channel corresponding to this queue.\r
127          * In BCP, Tx queues are mapped one to one with Tx channels.\r
128          *\r
129          * Get the priority for the channel (Tx QFIFO) from the BCP MMRs \r
130          * configured by the application.\r
131          */\r
132         Bcp_getTxQfifoReadDestSelReg (&pBcpInstInfo->bcpLldObj, destSel, prioVal);\r
133 \r
134         txChCfg.channelNum      =   bcpTxQNum;                      \r
135         txChCfg.txEnable        =   Cppi_ChState_CHANNEL_DISABLE;   \r
136         txChCfg.filterEPIB      =   0;\r
137         txChCfg.filterPS        =   0;\r
138         txChCfg.aifMonoMode     =   0;\r
139         txChCfg.priority        =   prioVal [bcpTxQNum];  \r
140         if ((hCppiTxChan = Cppi_txChannelOpen (pBcpInstInfo->hCppi, &txChCfg, &isAllocated)) == NULL)\r
141         {\r
142             Bcp_osalLog ("Error opening Tx channel corresponding to BCP queue : %d\n", bcpTxQNum);\r
143             goto return_error;\r
144         }\r
145 \r
146         /* Open the BCP Tx queue */\r
147         if ((hQmssTxQ = Qmss_queueOpen ((Qmss_QueueType) QMSS_PARAM_NOT_SPECIFIED, pBcpInstInfo->baseTxQueueNum + bcpTxQNum, &isAllocated)) < 0)\r
148         {\r
149             Bcp_osalLog ("Error opening BCP Tx Queue Number %d \n", bcpTxQNum);\r
150             goto return_error;\r
151         }\r
152 \r
153         /* Finally, enable the Tx channel so that we can start sending data to BCP */\r
154         Cppi_channelEnable (hCppiTxChan);\r
155 \r
156         /* Save the channel setup info */\r
157         pBcpInstInfo->Bcp_txQInfo[bcpTxQNum].qNum           =   bcpTxQNum;\r
158         pBcpInstInfo->Bcp_txQInfo[bcpTxQNum].hCppiTxChan    =   hCppiTxChan;\r
159         pBcpInstInfo->Bcp_txQInfo[bcpTxQNum].hQmssTxQ       =   hQmssTxQ;\r
160     }\r
161 \r
162     /* Increment the reference count on this queue */\r
163     pBcpInstInfo->Bcp_txQInfo[bcpTxQNum].refCnt ++;                    \r
164     \r
165     hBcpTxQueueInfo = &pBcpInstInfo->Bcp_txQInfo[bcpTxQNum];\r
166 \r
167     /* Return success. Return the handle to the Tx queue */\r
168     return hBcpTxQueueInfo;\r
169 \r
170 return_error:\r
171     if (hCppiTxChan)\r
172     {\r
173         Cppi_channelClose (hCppiTxChan);\r
174     }\r
175     if (hQmssTxQ)\r
176     {\r
177         Qmss_queueClose (hQmssTxQ);       \r
178     }\r
179 \r
180     /* Return NULL handle to indicate that the setup failed */\r
181     return NULL;\r
182 }\r
183 \r
184 /**\r
185 * ============================================================================\r
186 *  @n@b Bcp_txQueueClose\r
187 *\r
188 *  @b   brief\r
189 *  @n   This API decrements the reference count on the transmit queue handle\r
190 *       provided and when the reference count reaches zero, i.e., when no\r
191 *       application thread is no longer using this transmit queue handle it\r
192 *       frees up the BCP transmit queue handle and all associated configuration.\r
193 *       If an application wishes to use the transmit queue, it would have to do\r
194 *       so by opening the BCP transmit queue with appropriate configuration\r
195 *       using the API @a Bcp_txQueueOpen ().\r
196 *\r
197 *  @param[in]\r
198 *       pBcpTxQInfo         Handle to the transmit queue obtained using\r
199 *                           @a  Bcp_txQueueOpen () API.\r
200 *\r
201 *  @return     Bcp_RetVal\r
202 *  @li         BCP_RETVAL_EBAD_HANDLE  -   Invalid transmit queue handle provided.\r
203 *  @li         BCP_RETVAL_SUCCESS      -   Succesfully closed the queue.\r
204 *\r
205 *  @pre\r
206 *  @n   @a Bcp_txQueueOpen () must have been called succesfully to setup the \r
207 *       BCP transmit queue before calling this API.\r
208 *\r
209 *  @post\r
210 *  @n   Reference counter on the queue handle decremented. If reference counter\r
211 *       reaches zero, queue configuration cleaned up and all associated CPPI\r
212 *       handles released.\r
213 * ============================================================================\r
214 */\r
215 static Bcp_RetVal Bcp_txQueueClose \r
216 (\r
217     Bcp_TxQInfo*               pBcpTxQInfo\r
218 )\r
219 {\r
220     /* Validate input */\r
221     if (!pBcpTxQInfo)\r
222     {\r
223         Bcp_osalLog ("Invalid Transmit queue handle provided \n");\r
224         return BCP_RETVAL_EBAD_HANDLE;  \r
225     }\r
226 \r
227     if (!pBcpTxQInfo->refCnt)\r
228     {\r
229         return BCP_RETVAL_SUCCESS;      \r
230     }\r
231 \r
232     /* We can close the queue and clean up all its associated CPPI\r
233      * handles only if there is no other application/driver using\r
234      * this queue other than us, i.e. refCnt is 1.\r
235      */\r
236     if (pBcpTxQInfo->refCnt == 1)\r
237     {\r
238         /* Disable the Tx channel */            \r
239         Cppi_channelDisable (pBcpTxQInfo->hCppiTxChan);\r
240 \r
241         /* Close the CPPI/QMSS channels and queues associated with \r
242          * the transmit queue specified.\r
243          */\r
244         Cppi_channelClose (pBcpTxQInfo->hCppiTxChan);\r
245         Qmss_queueClose (pBcpTxQInfo->hQmssTxQ);\r
246     \r
247         /* Update our database of tx queue state info */\r
248         pBcpTxQInfo->qNum           =   0;\r
249         pBcpTxQInfo->hCppiTxChan    =   NULL;\r
250         pBcpTxQInfo->hQmssTxQ       =   (Qmss_QueueHnd) NULL;\r
251     }\r
252 \r
253     /* Decrement the reference count to reflect the successful\r
254      * close.\r
255      */\r
256     pBcpTxQInfo->refCnt --;\r
257 \r
258     /* Return Success */\r
259     return BCP_RETVAL_SUCCESS;\r
260 }\r
261 \r
262 /**\r
263  * ============================================================================\r
264  *  @n@b Bcp_getNextAvailRxObjId\r
265  *\r
266  *  @b  brief\r
267  *  @n  Given a BCP peripheral instance number, this API searches through\r
268  *      the instance's global Rx object info database to find the next \r
269  *      available empty slot to store a new Rx object's info. Each slot in this \r
270  *      global Rx object info database stores Rx object information that needs\r
271  *      to be globally accessible, i.e., accessible from all cores of the \r
272  *      device.\r
273  *\r
274  *      * API for internal use by the driver *\r
275  *\r
276  *  @param[in]    \r
277         instNum             BCP instance number from which an empty Rx object\r
278                             slot must be found.\r
279  *\r
280  *  @return     int32_t\r
281  *  @li         <0  -   Error finding an empty slot in the\r
282  *                      Rx object global database.\r
283  *                                  \r
284  *  @li         >=0 -   Valid Rx object slot id from the database returned \r
285  *                      to store the new Rx object info.\r
286  *\r
287  *  @pre\r
288  *  @n  @a Bcp_open () must have been called to initialize the driver before \r
289  *      calling this API. Also a valid instance number must be specified to \r
290  *      this API in 'instNum' parameter.\r
291  *\r
292  *  @post\r
293  *  @n  None.\r
294  * \r
295  *  @code\r
296         ...\r
297 \r
298         // Get the next available Rx object slot from the database.\r
299         if (Bcp_getNextAvailRxObjId (CSL_BCP) < 0)\r
300         {\r
301             // Number of Rx objects created exceeds maximum allowed.\r
302         }        \r
303     @endcode\r
304  * ============================================================================\r
305  */\r
306 static int32_t Bcp_getNextAvailRxObjId \r
307 (\r
308     uint8_t                   instNum\r
309 )\r
310 {\r
311     int32_t                   i;\r
312 \r
313     for (i = 0; i < BCP_MAX_NUM_RXOBJECTS; i++)\r
314     {\r
315         if (!gBcp_instanceInfo[instNum].Bcp_rxObjGlobalInfo[i].bIsValid)\r
316         {\r
317             /* Found an empty Rx object slot. Return the slot number */                \r
318             return i;                \r
319         }\r
320         /* Slot at "i" already taken by a Rx object. Continue searching */                \r
321     }\r
322 \r
323     /* If we are here, indicates that we are done searching\r
324      * through the entire Rx object global database and found\r
325      * no slot empty.\r
326      *\r
327      * Return error. Maximum number of Rx objects reached.\r
328      */\r
329     return BCP_RETVAL_EFAILURE;\r
330 }\r
331 \r
332 \r
333 /***************************************************************\r
334  ******************** BCP Exported APIs ************************\r
335  **************************************************************/\r
336 \r
337 /**\r
338  * ============================================================================\r
339  *  @n@b Bcp_getVersionID\r
340  *\r
341  *  @b  brief\r
342  *  @n  This API returns the BCP driver's version Id.\r
343  *      \r
344  *  @return     \r
345  *  @n  uint32_t    -   Returns the BCP driver version Id\r
346  *\r
347  *  @pre\r
348  *  @n  None. \r
349  *\r
350  *  @post\r
351  *  @n  None.\r
352  * ============================================================================\r
353  */\r
354 uint32_t Bcp_getVersionID \r
355\r
356     void\r
357 )\r
358 {\r
359     return BCP_VERSION_ID;\r
360 }\r
361 \r
362 const char  Bcp_versionStr[] = BCP_VERSION_STR ":" __DATE__  ":" __TIME__;\r
363 \r
364 /**\r
365  * ============================================================================\r
366  *  @n@b Bcp_getVersionStr\r
367  *\r
368  *  @b  brief\r
369  *  @n  This API returns the BCP driver's version information in string format.\r
370  *      \r
371  *  @return     \r
372  *  @n  const char*     -   Returns the BCP driver build and version info in \r
373  *                          string format.\r
374  *\r
375  *  @pre\r
376  *  @n  None. \r
377  *\r
378  *  @post\r
379  *  @n  None.\r
380  * ============================================================================\r
381  */\r
382 const char* Bcp_getVersionStr \r
383 (\r
384     void\r
385 )\r
386 {\r
387     return (const char *) (Bcp_versionStr);\r
388 }\r
389 \r
390 /**\r
391  * ============================================================================\r
392  *  @n@b Bcp_init\r
393  *\r
394  *  @b  brief\r
395  *  @n  This API initializes the BCP peripheral with the configuration provided,\r
396  *      and opens the BCP CDMA for use.\r
397  *\r
398  *      BCP driver can be initialized in 2 modes - "local" and "remote".\r
399  *      In "remote" mode, applications can only send/receive data to/from BCP, \r
400  *      but cannot configure its registers or its CDMA. "Local" mode however\r
401  *      gives access to entire BCP register and CDMA configuration space in \r
402  *      addition to the ability to send/receive packets from it. Application must\r
403  *      initialize BCP in appropriate mode depending on whether BCP peripheral \r
404  *      is present on the device where driver is being executed or not.\r
405  *\r
406  *      This API MUST be called ONLY once in the system and at system startup\r
407  *      for any given BCP peripheral instance before using any of the BCP \r
408  *      driver APIs.\r
409  *\r
410  *  @param[in]    \r
411  *      instNum             BCP peripheral instance number.\r
412  *\r
413  *  @param[in]    \r
414  *      mode                Indicates if BCP driver needs to execute in "local"\r
415  *                          or "remote" modes. \r
416  *\r
417  *  @param[in]    \r
418  *      pBcpInitCfg         BCP initialization configuration.\r
419  *\r
420  *  @return     Bcp_RetVal\r
421  *  @li         BCP_RETVAL_EINVALID_PARAMS -   Invalid instance number provided.\r
422  *  @li         BCP_RETVAL_EBAD_HANDLE     -   Invalid init configuration\r
423  *                                             handle provided.\r
424  *  @li         BCP_RETVAL_EFAILURE        -   Error initializing driver for the\r
425  *                                             BCP instance requested.\r
426  *  @li         BCP_RETVAL_SUCCESS         -   BCP instance initialized succesfully.                                              \r
427  *\r
428  *  @pre\r
429  *  @n  This API MUST be called only once during system startup. \r
430  *\r
431  *  @post\r
432  *  @n  BCP driver initialized for the instance specified.\r
433  * ============================================================================\r
434  */\r
435 Bcp_RetVal Bcp_init \r
436 (\r
437     uint8_t                     instNum, \r
438     Bcp_DrvMode                 mode,\r
439     Bcp_InitCfg*                pBcpInitCfg\r
440 )\r
441 {\r
442     Cppi_Handle                 hCppi;\r
443     Cppi_CpDmaInitCfg           cpdmaCfg;\r
444         \r
445     /* Validate user input */\r
446     if (instNum >= BCP_MAX_NUM_INSTANCES)\r
447     {\r
448         Bcp_osalLog ("Invalid instance number! Valid range 0 - %d \n", (BCP_MAX_NUM_INSTANCES - 1));\r
449         return BCP_RETVAL_EINVALID_PARAMS;\r
450     }\r
451 \r
452     if (!pBcpInitCfg)\r
453     {\r
454         Bcp_osalLog ("Invalid BCP Init configuration handle passed \n");\r
455         return BCP_RETVAL_EBAD_HANDLE;\r
456     }\r
457 \r
458     if (!pBcpInitCfg->BcpTunnel_txOpen || !pBcpInitCfg->BcpTunnel_txClose ||\r
459         !pBcpInitCfg->BcpTunnel_rxOpen || !pBcpInitCfg->BcpTunnel_rxClose ||\r
460         !pBcpInitCfg->BcpTunnel_send || !pBcpInitCfg->BcpTunnel_recv ||\r
461         !pBcpInitCfg->BcpTunnel_freeRecvBuffer)\r
462     {\r
463         Bcp_osalLog ("Invalid BCP transport layer function handlers passed \n");\r
464         return BCP_RETVAL_EBAD_HANDLE;\r
465     }\r
466 \r
467     /* Enter Critical Section */\r
468     Bcp_osalMultiCoreCsEnter ();\r
469 \r
470     Bcp_osalBeginMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));    \r
471 \r
472     /* Reset the driver's global info for this instance */            \r
473     memset (&gBcp_instanceInfo [instNum], 0, sizeof (Bcp_InstanceInfo));\r
474 \r
475     /* Setup BCP peripheral/CDMA only if it is local to the device */\r
476     if (mode == Bcp_DrvMode_LOCAL)\r
477     {\r
478         /* Set up the BCP CDMA configuration */\r
479         memset (&cpdmaCfg, 0, sizeof (Cppi_CpDmaInitCfg));\r
480         cpdmaCfg.dmaNum     =   pBcpInitCfg->cpdmaNum;\r
481 \r
482         /* Initialize BCP CDMA */\r
483         if ((hCppi = Cppi_open (&cpdmaCfg)) == NULL)\r
484         {\r
485             Bcp_osalLog ("Error opening BCP CDMA %d\n", cpdmaCfg.dmaNum);\r
486 \r
487             /* Exit Critical Section */\r
488             Bcp_osalMultiCoreCsExit ();\r
489             return BCP_RETVAL_EFAILURE;\r
490         }\r
491 \r
492         /* Disable BCP CDMA loopback */\r
493         if (Cppi_setCpdmaLoopback (hCppi, 0) != CPPI_SOK)\r
494         {\r
495             Bcp_osalLog ("Error disabling loopback for BCP CDMA %d\n", cpdmaCfg.dmaNum);\r
496 \r
497             /* Exit Critical Section */\r
498             Bcp_osalMultiCoreCsExit ();\r
499             return BCP_RETVAL_EFAILURE;\r
500         }\r
501 \r
502         /* Open the BCP LLD for this instance. \r
503          *\r
504          * Required to setup/read the BCP MMR for this instance.\r
505          */\r
506         if (Bcp_lldOpen (instNum, pBcpInitCfg->cfgRegsBaseAddress, &gBcp_instanceInfo[instNum].bcpLldObj) != 0)\r
507         {\r
508             /* BCP LLD Instance open failed */            \r
509             Bcp_osalLog ("BCP LLD Instance %d open failed \n", instNum);\r
510 \r
511             /* Exit Critical Section */\r
512             Bcp_osalMultiCoreCsExit ();\r
513             return BCP_RETVAL_EFAILURE;\r
514         }\r
515 \r
516         /* Save the CPPi driver handle and the Start Tx queue number for this instance. */\r
517         gBcp_instanceInfo[instNum].hCppi                    =   hCppi;\r
518         gBcp_instanceInfo[instNum].baseTxQueueNum           =   pBcpInitCfg->baseTxQueueNum;\r
519     }\r
520 \r
521     /* Save the transport layer callbacks and other info */\r
522     gBcp_instanceInfo[instNum].instNum                      =   instNum;\r
523     gBcp_instanceInfo[instNum].mode                         =   mode;\r
524     gBcp_instanceInfo[instNum].pFxnBcpTunnel_txOpen         =   pBcpInitCfg->BcpTunnel_txOpen;\r
525     gBcp_instanceInfo[instNum].pFxnBcpTunnel_txClose        =   pBcpInitCfg->BcpTunnel_txClose;\r
526     gBcp_instanceInfo[instNum].pFxnBcpTunnel_rxOpen         =   pBcpInitCfg->BcpTunnel_rxOpen;\r
527     gBcp_instanceInfo[instNum].pFxnBcpTunnel_rxClose        =   pBcpInitCfg->BcpTunnel_rxClose;\r
528     gBcp_instanceInfo[instNum].pFxnBcpTunnel_send           =   pBcpInitCfg->BcpTunnel_send;\r
529     gBcp_instanceInfo[instNum].pFxnBcpTunnel_recv           =   pBcpInitCfg->BcpTunnel_recv;\r
530     gBcp_instanceInfo[instNum].pFxnBcpTunnel_freeRecvBuffer =   pBcpInitCfg->BcpTunnel_freeRecvBuffer;\r
531 \r
532     /* Increment the reference count to indicate that this instance\r
533      * has been initialized and is ready for use by an application.\r
534      */\r
535     gBcp_instanceInfo[instNum].refCnt ++;\r
536 \r
537     /* Writeback the shared Instance Info object */\r
538     Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
539 \r
540     /* Exit Critical Section */\r
541     Bcp_osalMultiCoreCsExit ();\r
542 \r
543     /* Successfully done with initialization. Return. */\r
544     return BCP_RETVAL_SUCCESS;\r
545 }\r
546 \r
547 /**\r
548  * ============================================================================\r
549  *  @n@b Bcp_deInit\r
550  *\r
551  *  @b  brief\r
552  *  @n  This API closes the BCP peripheral instance opened earlier using \r
553  *      @a Bcp_init () API. When all the applications using this BCP\r
554  *      instance have released it (reference count on the instance reaches zero),\r
555  *      this API closes the BCP CDMA, closes the BCP LLD and finally initiates \r
556  *      a software reset on the BCP to reset all its registers, and \r
557  *      it's state machine. On success, it restores the BCP peripheral state \r
558  *      to 'un-initialized' state\r
559  *\r
560  *      If an application or driver would like to use any of the driver APIs again,\r
561  *      it can do so only after calling @a Bcp_init() again.\r
562  *\r
563  *  @param[in]\r
564  *       instNum             BCP peripheral instance number.\r
565  *\r
566  *  @return     Bcp_RetVal\r
567  *  @li         BCP_RETVAL_SUCCESS      -   Successfully closed the BCP CDMA.\r
568  *\r
569  *  @pre\r
570  *  @n  @a Bcp_init () must be called before calling this API. \r
571  *\r
572  *  @post\r
573  *  @n  Reference count decremented on the BCP instance in the driver. When\r
574  *      reference count reaches zero, CDMA is closed, all BCP Tx queues closed \r
575  *      and deallocated. BCP software reset performed.\r
576  * ============================================================================\r
577  */\r
578 Bcp_RetVal Bcp_deInit \r
579 (\r
580     uint8_t                     instNum\r
581 )\r
582 {\r
583     /* BCP setup cannot be undone unless initialized */\r
584     if (!Bcp_isInitialized (instNum))\r
585     {\r
586         Bcp_osalLog ("BCP instance %d not open !! \n", instNum);\r
587         return BCP_RETVAL_SUCCESS;\r
588     }\r
589 \r
590     /* Enter Critical Section */\r
591     Bcp_osalMultiCoreCsEnter ();\r
592 \r
593     /* Ensure all applications using this BCP instance are done\r
594      * using before resetting the instance.\r
595      */\r
596     if (gBcp_instanceInfo[instNum].refCnt == 1)\r
597     {\r
598         /* Reset BCP peripheral only if deinit being done from local device */            \r
599         if (gBcp_instanceInfo[instNum].mode == Bcp_DrvMode_LOCAL)\r
600         {\r
601             /* Close the CDMA */\r
602             Cppi_close (gBcp_instanceInfo[instNum].hCppi);\r
603 \r
604             /* Issue a software reset to BCP to reset all its register values \r
605              * and state machines to its initial state.\r
606              */\r
607             Bcp_doSoftwareReset (&gBcp_instanceInfo[instNum].bcpLldObj);\r
608 \r
609             Bcp_lldClose (&gBcp_instanceInfo[instNum].bcpLldObj);\r
610 \r
611             /* BCP deinit successful. Update the status variables. */\r
612             gBcp_instanceInfo[instNum].hCppi                    =   NULL;\r
613             gBcp_instanceInfo[instNum].baseTxQueueNum           =   0;\r
614         }\r
615    \r
616         gBcp_instanceInfo[instNum].instNum                      =   0;\r
617         gBcp_instanceInfo[instNum].mode                         =   Bcp_DrvMode_LOCAL;\r
618         gBcp_instanceInfo[instNum].refCnt                       =   0;\r
619         gBcp_instanceInfo[instNum].pFxnBcpTunnel_txOpen         =   NULL;\r
620         gBcp_instanceInfo[instNum].pFxnBcpTunnel_txClose        =   NULL;\r
621         gBcp_instanceInfo[instNum].pFxnBcpTunnel_rxOpen         =   NULL;\r
622         gBcp_instanceInfo[instNum].pFxnBcpTunnel_rxClose        =   NULL;\r
623         gBcp_instanceInfo[instNum].pFxnBcpTunnel_send           =   NULL;\r
624         gBcp_instanceInfo[instNum].pFxnBcpTunnel_recv           =   NULL;\r
625         gBcp_instanceInfo[instNum].pFxnBcpTunnel_freeRecvBuffer =   NULL;\r
626     }\r
627 \r
628     /* De-init complete. Update the physical memory. */\r
629     Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
630 \r
631     /* Exit Critical Section */\r
632     Bcp_osalMultiCoreCsExit ();\r
633     \r
634     /* Return success. */\r
635     return BCP_RETVAL_SUCCESS;\r
636 }\r
637 \r
638 /**\r
639  * ============================================================================\r
640  *  @n@b Bcp_isInitialized\r
641  *\r
642  *  @b  brief\r
643  *  @n  Given an BCP peripheral instance number, this API returns 1 to\r
644  *      indicate that it is initialized and has been successfully setup, 0 otherwise.\r
645  *\r
646  *  @param[in]\r
647  *      instNum             BCP peripheral instance number to check the status \r
648  *                          on.\r
649  *\r
650  *  @return     uint8_t\r
651  *  @li         1       -   Driver initialized for the instance number passed.\r
652  *  @li         0       -   Instance number invalid/not initialized.\r
653  *\r
654  *  @pre\r
655  *  @n  None.\r
656  *\r
657  *  @post\r
658  *  @n  None.\r
659  * ============================================================================\r
660  */\r
661 uint8_t Bcp_isInitialized \r
662 (\r
663     uint8_t                     instNum\r
664 )\r
665 {\r
666     uint8_t                     retVal;\r
667 \r
668     /* Critical section start */\r
669     Bcp_osalMultiCoreCsEnter ();\r
670 \r
671     /* Invalidate cache before reading shared Instance Info to\r
672      * ensure we are in sync.\r
673      */\r
674     Bcp_osalBeginMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
675 \r
676     /* Validate input */\r
677     if (instNum >= BCP_MAX_NUM_INSTANCES || !gBcp_instanceInfo[instNum].refCnt)\r
678     {\r
679         Bcp_osalLog ("Invalid instance number passed \n");\r
680     \r
681         /* critical section end */\r
682         Bcp_osalMultiCoreCsExit ();\r
683         return 0;\r
684     }\r
685 \r
686     /* check if the BCP instance is setup and valid */\r
687     if (gBcp_instanceInfo[instNum].refCnt)\r
688     {\r
689         /* BCP instance open */            \r
690         retVal = 1;\r
691     }\r
692     else\r
693     {\r
694         /* BCP instance not open */            \r
695         retVal = 0;\r
696     }    \r
697 \r
698     /* critical section end */\r
699     Bcp_osalMultiCoreCsExit ();\r
700 \r
701     return retVal;\r
702 }\r
703 \r
704 /**\r
705  * ============================================================================\r
706  *  @n@b Bcp_open\r
707  *\r
708  *  @b  brief\r
709  *  @n  This API MUST be called by all BCP driver users at least once to obtain\r
710  *      an BCP driver handle.\r
711  *\r
712  *  @param[in]    \r
713  *      instNum             BCP Instance number that the application would like\r
714  *                          to use.\r
715  *\r
716  *  @param[in]    \r
717  *      pBcpDrvCfg          Handle to BCP driver configuration structure.\r
718  *\r
719  *  @param[out]    \r
720  *      pRetVal             Pointer to hold the return value returned by this API. \r
721  *                          Following are the possible return values for this API:\r
722  *                            \r
723  *  @li         BCP_RETVAL_EINVALID_PARAMS  -   Invalid instance number/driver \r
724  *                                              configuration provided.\r
725  *  @li         BCP_RETVAL_EBAD_HANDLE      -   Invalid driver configuration\r
726  *                                              handle provided.\r
727  *  @li         BCP_RETVAL_ENO_MEM          -   Error allocating memory for driver's \r
728  *                                              internal book-keeping data.\r
729  *  @li         BCP_RETVAL_SUCCESS          -   Successfully opened the driver instance.\r
730  *\r
731  *  @return     Bcp_DrvHandle\r
732  *  @li         NULL                        -   Error. Appropriate error code is returned\r
733  *                                              in the output parameter 'pRetVal'.\r
734  *  @li         >0                          -   Success. Valid BCP driver handle is returned.\r
735  *\r
736  *  @pre\r
737  *  @n  None\r
738  *\r
739  *  @post\r
740  *  @n  None \r
741  * ============================================================================\r
742  */\r
743 Bcp_DrvHandle Bcp_open \r
744 (\r
745     uint8_t                     instNum,\r
746     Bcp_DrvCfg*                 pBcpDrvCfg,\r
747     Bcp_RetVal*                 pRetVal\r
748 )\r
749 {\r
750     Bcp_DrvInfo*                pBcpDrvInfo;\r
751 \r
752     /* Validate input */\r
753     if (!pRetVal)\r
754     {\r
755         Bcp_osalLog ("Invalid Retrun value handle passed \n");\r
756         return NULL;\r
757     }\r
758 \r
759     /* Validate the instance number passed. Instance number passed is invalid if:\r
760      *\r
761      *  (1) Instance number exceeds the acceptable range.\r
762      *  (2) Instance number is valid, but the driver's state info indicates that\r
763      *      the instance has not been setup using Bcp_init () API.\r
764      */\r
765     if (!Bcp_isInitialized (instNum))\r
766     {\r
767         Bcp_osalLog ("Invalid instance number or instance not initialized yet. \n");\r
768         *pRetVal    =   BCP_RETVAL_EINVALID_PARAMS;\r
769         return NULL;\r
770     }\r
771             \r
772     if (!pBcpDrvCfg)\r
773     {\r
774         Bcp_osalLog ("Invalid BCP driver configuration handle passed \n");\r
775         *pRetVal    =   BCP_RETVAL_EBAD_HANDLE;\r
776         return NULL;\r
777     }\r
778 \r
779     /* Allocate space to hold BCP descriptor configuration for this user */\r
780     if ((pBcpDrvInfo = (Bcp_DrvInfo *) Bcp_osalMalloc (sizeof (Bcp_DrvInfo), FALSE)) == NULL)\r
781     {\r
782         Bcp_osalLog ("Error allocating memory for BCP driver info \n");\r
783         *pRetVal    =   BCP_RETVAL_ENO_MEM;\r
784         return NULL;\r
785     }\r
786     memset ((void *)pBcpDrvInfo, 0, sizeof (Bcp_DrvInfo));\r
787 \r
788     /* Save driver settings */\r
789     pBcpDrvInfo->instNum                        =   instNum;   \r
790     pBcpDrvInfo->mode                           =   gBcp_instanceInfo[instNum].mode;   \r
791     pBcpDrvInfo->drvCfg                         =   *pBcpDrvCfg;\r
792     pBcpDrvInfo->pFxnBcpTunnel_txOpen           =   gBcp_instanceInfo[instNum].pFxnBcpTunnel_txOpen;\r
793     pBcpDrvInfo->pFxnBcpTunnel_txClose          =   gBcp_instanceInfo[instNum].pFxnBcpTunnel_txClose;\r
794     pBcpDrvInfo->pFxnBcpTunnel_rxOpen           =   gBcp_instanceInfo[instNum].pFxnBcpTunnel_rxOpen;\r
795     pBcpDrvInfo->pFxnBcpTunnel_rxClose          =   gBcp_instanceInfo[instNum].pFxnBcpTunnel_rxClose;\r
796     pBcpDrvInfo->pFxnBcpTunnel_send             =   gBcp_instanceInfo[instNum].pFxnBcpTunnel_send;\r
797     pBcpDrvInfo->pFxnBcpTunnel_recv             =   gBcp_instanceInfo[instNum].pFxnBcpTunnel_recv;\r
798     pBcpDrvInfo->pFxnBcpTunnel_freeRecvBuffer   =   gBcp_instanceInfo[instNum].pFxnBcpTunnel_freeRecvBuffer;\r
799 \r
800     /* Enter Critical Section */\r
801     Bcp_osalMultiCoreCsEnter ();\r
802 \r
803     /* Increment reference count to keep the instance info alive */\r
804     gBcp_instanceInfo[instNum].refCnt ++;\r
805 \r
806     Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
807 \r
808     /* Exit Critical Section */\r
809     Bcp_osalMultiCoreCsExit ();\r
810 \r
811     /* Return success */\r
812     *pRetVal    =   BCP_RETVAL_SUCCESS;\r
813 \r
814     /* Return handle to the BCP instance info */ \r
815     return ((Bcp_DrvHandle) pBcpDrvInfo);\r
816 }\r
817 \r
818 /**\r
819  * ============================================================================\r
820  *  @n@b Bcp_close\r
821  *\r
822  *  @b  brief\r
823  *  @n  This API closes the BCP driver instance opened earlier using a call\r
824  *      to @a Bcp_open () API. \r
825  *\r
826  *  @param[in]\r
827  *      hBcp                BCP driver handle obtained using @a Bcp_open () \r
828  *                          API.\r
829  *\r
830  *  @return     Bcp_RetVal\r
831  *  @li         BCP_RETVAL_EBAD_HANDLE  -   Invalid input handle passed. Error.\r
832  *  @li         BCP_RETVAL_SUCCESS      -   Successfully closed the BCP.\r
833  *\r
834  *  @pre\r
835  *  @n  @a Bcp_open () must have been called to open the driver instance prior to\r
836  *      calling this API. Also, all open Tx, Rx objects opened by an application\r
837  *      must be closed by calling @a Bcp_txClose () and Bcp_rxClose () APIs \r
838  *      before calling this API to ensure all associated memory is freed cleanly.\r
839  *\r
840  *  @post\r
841  *  @n  Reference count decremented on the BCP instance in the driver. \r
842  * ============================================================================\r
843  */\r
844 Bcp_RetVal Bcp_close \r
845 (\r
846     Bcp_DrvHandle           hBcp\r
847 )\r
848 {\r
849     Bcp_DrvInfo*            pBcpDrvInfo;\r
850 \r
851     /* Validate input */\r
852     if (!hBcp)\r
853     {\r
854         Bcp_osalLog ("Invalid BCP driver handle passed! \n");\r
855         return BCP_RETVAL_EBAD_HANDLE;\r
856     }\r
857 \r
858     pBcpDrvInfo   =   (Bcp_DrvInfo *) hBcp;\r
859 \r
860     /* Enter Critical Section */\r
861     Bcp_osalMultiCoreCsEnter ();\r
862 \r
863     /* Invalidate the BCP instance in cache */\r
864     Bcp_osalBeginMemAccess (&gBcp_instanceInfo[pBcpDrvInfo->instNum], sizeof (Bcp_InstanceInfo));\r
865     gBcp_instanceInfo[pBcpDrvInfo->instNum].refCnt --;            \r
866     Bcp_osalEndMemAccess (&gBcp_instanceInfo[pBcpDrvInfo->instNum], sizeof (Bcp_InstanceInfo));\r
867 \r
868     /* Exit Critical Section */\r
869     Bcp_osalMultiCoreCsExit ();\r
870     \r
871     /* Free the BCP state info handle */\r
872     Bcp_osalFree ((void*) pBcpDrvInfo, sizeof (Bcp_DrvInfo), FALSE);\r
873 \r
874     /* Return success. */\r
875     return BCP_RETVAL_SUCCESS;\r
876 }\r
877 \r
878 \r
879 /**\r
880  * ============================================================================\r
881  *  @n@b Bcp_getLLDHandle\r
882  *\r
883  *  @b  brief\r
884  *  @n  This API returns the BCP LLD object handle corresponding to the BCP\r
885  *      instance number provided. \r
886  *\r
887  *  @param[in]\r
888  *      instNum             BCP instance number.\r
889  *\r
890  *  @return     Bcp_LldObj*\r
891  *  @li         NULL        -   Invalid instance number passed/Corresponding BCP \r
892  *                              instance not initialized yet. Error.\r
893  *  @li         >0          -   BCP LLD object handle returned.\r
894  *\r
895  *  @pre\r
896  *  @n  @a Bcp_init () must have been called to open the driver instance prior to\r
897  *      calling this API. \r
898  *\r
899  *  @post\r
900  *  @n  None\r
901  * ============================================================================\r
902  */\r
903 Bcp_LldObj* Bcp_getLLDHandle \r
904 (\r
905     uint8_t                 instNum\r
906 )\r
907 {\r
908     Bcp_LldObj*             pBcpLldObj = NULL;\r
909 \r
910     /* Validate input */\r
911     if (!Bcp_isInitialized (instNum))\r
912     {\r
913         Bcp_osalLog ("Invalid BCP instance number passed \n");\r
914         return NULL;\r
915     }\r
916 \r
917     /* Enter Critical Section */\r
918     Bcp_osalMultiCoreCsEnter ();\r
919 \r
920     /* Invalidate the BCP instance in cache */\r
921     Bcp_osalBeginMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
922 \r
923     if (gBcp_instanceInfo[instNum].mode == Bcp_DrvMode_LOCAL)\r
924         pBcpLldObj =   &gBcp_instanceInfo[instNum].bcpLldObj;            \r
925     else\r
926         pBcpLldObj =   NULL;\r
927 \r
928     /* Exit Critical Section */\r
929     Bcp_osalMultiCoreCsExit ();\r
930     \r
931     /* Return LLD handle. */\r
932     return pBcpLldObj;\r
933 }\r
934 \r
935 /**\r
936 * ============================================================================\r
937 *  @n@b Bcp_txOpen\r
938 *\r
939 *  @b   brief\r
940 *  @n   This API sets up a transmit object for the calling application. A \r
941 *       transmit object must be setup by any application that wishes to\r
942 *       send data for processing to BCP using the driver. \r
943 *\r
944 *       On success, this API returns a valid, non-zero Tx handle and NULL \r
945 *       otherwise to indicate an error.\r
946 *\r
947 *       On BCP local device, a valid Tx endpoint configuration must be passed\r
948 *       in 'pTxEndpointCfg' if the BCP Tx queue being opened needs to be\r
949 *       made accessible from remote device too. If no remote access is required\r
950 *       for this BCP Tx queue, then 'pTxEndpointCfg' parameter can be set\r
951 *       to NULL.\r
952 *\r
953 *       On BCP remote device, the BCP Tx queue configuration 'pBcpTxCfg'\r
954 *       must be set to NULL since remote device has no direct access to \r
955 *       BCP CDMA. Configuration required to open a BCP Tx remote endpoint\r
956 *       must be passed in 'pTxEndpointCfg' and the driver in turn passes\r
957 *       this as-is to the registered Tx endpoint open API.\r
958 *\r
959 *  @param[in]\r
960 *       hBcp                BCP driver handle obtained using @a Bcp_open () \r
961 *                           API.\r
962 *\r
963 *  @param[in]  \r
964 *       pBcpTxCfg           Input structure that holds configuration for the\r
965 *                           Tx object. MUST be set to NULL on remote device\r
966 *                           and MUST contain valid configuration on local\r
967 *                           device.\r
968 *\r
969 *  @param[in]  \r
970 *       pTxEndpointCfg      Configuration for BCP tunnel Tx endpoint object.\r
971 *                           MUST be valid for remote device. Can be NULL\r
972 *                           or a valid handle on local device based on whether\r
973 *                           remote access needs to be enabled for this Tx queue\r
974 *                           or not.\r
975 *\r
976 *  @return      Bcp_TxHandle\r
977 *  @li          NULL                -   Error. Invalid configuration passed. \r
978 *  @li          Valid Tx handle     -   Success. \r
979 *\r
980 *  @pre\r
981 *  @n   Valid BCP driver handle must be obtained by calling @a Bcp_open () API\r
982 *       by the application before calling this API. Valid Tx configuration must be \r
983 *       specified in 'pBcpTxCfg' structure as input to this API on local device.\r
984 *\r
985 *  @post\r
986 *  @n   BCP Tx queue open and setup if this API being called for first time for\r
987 *       a given Tx queue number. Tx object is ready for use to send data to BCP.\r
988 *       BCP tunnel Tx endpoint is setup too using the callback registered at\r
989 *       BCP init time.\r
990 * ============================================================================\r
991 */\r
992 Bcp_TxHandle Bcp_txOpen\r
993 (\r
994     Bcp_DrvHandle               hBcp,\r
995     Bcp_TxCfg*                  pBcpTxCfg,\r
996     void*                       pTxEndpointCfg\r
997 )\r
998 {\r
999     Bcp_DrvInfo*                pBcpDrvInfo;\r
1000     Bcp_TxQInfo*                pBcpTxQInfo = NULL;\r
1001     Bcp_TxInfo*                 pTxObjInfo;\r
1002     void*                       hTxEndpointInfo = NULL;\r
1003     uint8_t                     instNum;\r
1004 \r
1005     /* Validate application's BCP driver handle. */\r
1006     if (!hBcp)\r
1007     {\r
1008         Bcp_osalLog ("Invalid BCP driver handle passed! \n");\r
1009         return NULL;\r
1010     }\r
1011 \r
1012     pBcpDrvInfo     =   (Bcp_DrvInfo *) hBcp;\r
1013     instNum         =   pBcpDrvInfo->instNum;\r
1014     \r
1015     /* Validate input */\r
1016     if ((pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL && !pBcpTxCfg) ||\r
1017         (pBcpDrvInfo->mode == Bcp_DrvMode_REMOTE && !pTxEndpointCfg))\r
1018     {\r
1019         Bcp_osalLog ("Invalid inputs passed \n");            \r
1020         return NULL;\r
1021     }\r
1022 \r
1023     /* Enter Critical Section */\r
1024     Bcp_osalMultiCoreCsEnter ();            \r
1025 \r
1026     Bcp_osalBeginMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1027 \r
1028     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1029     {\r
1030         /* Open the BCP Tx queue if it is local to the device */\r
1031         if ((pBcpTxQInfo = Bcp_txQueueOpen (&gBcp_instanceInfo[instNum], pBcpTxCfg->txQNum)) == NULL)\r
1032         {\r
1033             Bcp_osalLog ("BCP Tx Queue Open failed \n");\r
1034             Bcp_osalMultiCoreCsExit ();\r
1035             return NULL;\r
1036         }\r
1037 \r
1038         /* Create a BCP tunnel Tx local endpoint for this queue if requested. */\r
1039         if (pTxEndpointCfg)\r
1040         {\r
1041             if ((hTxEndpointInfo = pBcpDrvInfo->pFxnBcpTunnel_txOpen (pTxEndpointCfg)) == NULL)\r
1042             {\r
1043                 Bcp_osalLog ("Error opening BCP tunnel's local Tx endpoint \n");\r
1044 \r
1045                 Bcp_txQueueClose (pBcpTxQInfo);\r
1046                 Bcp_osalMultiCoreCsExit ();\r
1047                 return NULL;\r
1048             }\r
1049         }\r
1050     }\r
1051     else\r
1052     {\r
1053         /* Create a BCP tunnel Tx remote endpoint. */\r
1054         if ((hTxEndpointInfo = pBcpDrvInfo->pFxnBcpTunnel_txOpen (pTxEndpointCfg)) == NULL)\r
1055         {\r
1056             Bcp_osalLog ("Error opening BCP tunnel's Tx remote endpoint \n");\r
1057 \r
1058             Bcp_osalMultiCoreCsExit ();\r
1059             return NULL;\r
1060         }\r
1061     }\r
1062 \r
1063     /* Allocate memory for holding the Tx object info */\r
1064     if ((pTxObjInfo = (Bcp_TxInfo *) Bcp_osalMalloc (sizeof (Bcp_TxInfo), FALSE)) == NULL)\r
1065     {\r
1066         Bcp_osalLog ("Error allocating memory for Tx object \n");\r
1067 \r
1068         if (hTxEndpointInfo)\r
1069             pBcpDrvInfo->pFxnBcpTunnel_txClose (hTxEndpointInfo);\r
1070 \r
1071         if (pBcpTxQInfo)\r
1072             Bcp_txQueueClose (pBcpTxQInfo);\r
1073 \r
1074         Bcp_osalMultiCoreCsExit ();\r
1075         Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1076         return NULL;\r
1077     }\r
1078 \r
1079     /* Initialize the Tx handle */\r
1080     memset ((void*) pTxObjInfo, 0, sizeof (Bcp_TxInfo));\r
1081 \r
1082     /* Save the Tx settings and state information */\r
1083     pTxObjInfo->pTxQInfo        =   pBcpTxQInfo;\r
1084     pTxObjInfo->hBcp            =   hBcp;\r
1085     pTxObjInfo->hTxEndpointInfo =   hTxEndpointInfo;\r
1086 \r
1087     Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1088 \r
1089     Bcp_osalMultiCoreCsExit ();\r
1090 \r
1091     /* Return success. Return Tx object handle. */\r
1092     return ((Bcp_TxHandle) pTxObjInfo);\r
1093 }\r
1094 \r
1095 /**\r
1096 * ============================================================================\r
1097 *  @n@b Bcp_txClose\r
1098 *\r
1099 *  @b   brief\r
1100 *  @n   This API closes the Tx object and frees memory allocated for it.\r
1101 *\r
1102 *       On local device, it also decrements the reference count on the Tx \r
1103 *       queue this object uses. When the reference count on the queue reaches \r
1104 *       zero, the Tx queue is closed. Additionally, if any tunnel Tx endpoint \r
1105 *       was created, its corresponding close function is closed to clean it\r
1106 *       up.\r
1107 *\r
1108 *       On remote device, the Tx remote endpoint is closed by calling the\r
1109 *       corresponding transport layer function.\r
1110 *\r
1111 *  @param[in]\r
1112 *       hBcpTxInfo         BCP Tx handle obtained using @a Bcp_txOpen() API.\r
1113 *\r
1114 *  @return     Bcp_RetVal\r
1115 *  @li         BCP_RETVAL_EBAD_HANDLE  -   Error. Invalid input passed.\r
1116 *  @li         BCP_RETVAL_SUCCESS      -   Success. BCP Tx object closed.\r
1117 *\r
1118 *  @pre\r
1119 *  @n   A valid Tx handle also must be obtained using @a Bcp_txOpen () \r
1120 *       before calling this API.\r
1121 *\r
1122 *  @post\r
1123 *  @n   BCP Tx object successfully closed. The Tx queue the object uses is closed \r
1124 *       if reference count on it reaches zero.\r
1125 * ============================================================================\r
1126 */\r
1127 Bcp_RetVal Bcp_txClose \r
1128 (\r
1129     Bcp_TxHandle                hBcpTxInfo\r
1130 )\r
1131 {\r
1132     Bcp_TxInfo*                 pTxObjInfo;\r
1133     Bcp_DrvInfo*                pBcpDrvInfo;\r
1134     uint8_t                     instNum;\r
1135 \r
1136     /* Validate input handles */\r
1137     if (!hBcpTxInfo)\r
1138     {\r
1139         Bcp_osalLog ("Invalid Transmit Object Handle provided \n");\r
1140         return BCP_RETVAL_EBAD_HANDLE;  \r
1141     }\r
1142 \r
1143     pTxObjInfo      =   (Bcp_TxInfo *) hBcpTxInfo;\r
1144     pBcpDrvInfo     =   (Bcp_DrvInfo *) pTxObjInfo->hBcp;\r
1145     instNum         =   pBcpDrvInfo->instNum;\r
1146 \r
1147     /* Grab the driver's lock to access shared info */\r
1148     Bcp_osalMultiCoreCsEnter ();\r
1149 \r
1150     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1151     {\r
1152         Bcp_osalBeginMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1153 \r
1154         /* Close the Tx queue used by the Tx object */\r
1155         Bcp_txQueueClose (pTxObjInfo->pTxQInfo);\r
1156 \r
1157         Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1158     }\r
1159 \r
1160     if (pTxObjInfo->hTxEndpointInfo)\r
1161         pBcpDrvInfo->pFxnBcpTunnel_txClose (pTxObjInfo->hTxEndpointInfo);\r
1162 \r
1163     /* Release the driver's lock. */\r
1164     Bcp_osalMultiCoreCsExit ();       \r
1165 \r
1166     /* Done cleaning up. Free the Tx object handle. */\r
1167     Bcp_osalFree (pTxObjInfo, sizeof (Bcp_TxInfo), FALSE);\r
1168 \r
1169     /* Return Success */\r
1170     return BCP_RETVAL_SUCCESS;\r
1171 }\r
1172 \r
1173 /**\r
1174 * ============================================================================\r
1175 *  @n@b Bcp_rxOpen\r
1176 *\r
1177 *  @b   brief\r
1178 *  @n   This API sets up a Rx object for the calling application. A Rx object\r
1179 *       is required by driver users to receive output from the BCP.\r
1180 *\r
1181 *       On Local device, a valid Rx object configuration MUST be provided in \r
1182 *       the input parameter 'pBcpRxCfg'. This API creates a BCP flow using the \r
1183 *       configuration provided. It also sets up the accumulator interrupts if \r
1184 *       interrupts are requested for this object. If any configuration needs\r
1185 *       to be done to redirect output from BCP to a remote device, then a\r
1186 *       valid configuration can be passed in 'pRxEndpointCfg' parameter and\r
1187 *       the driver will invoke the BCP transport layer's Rx endpoint open\r
1188 *       function. This parameter can be set to NULL if BCP output is to\r
1189 *       be processed on the same device or if no additional transport layer\r
1190 *       configuration is required.\r
1191 *\r
1192 *       On Remote device, a valid Rx endpoint configuration must be passed in\r
1193 *       the 'pRxEndpointCfg' parameter. This API in turn calls the transport\r
1194 *       layer's Rx endpoint open API to do the needful configuration to \r
1195 *       receive results from BCP on that device.\r
1196 *\r
1197 *       On success, this API returns a valid, non-zero Rx oject handle and returns \r
1198 *       NULL otherwise to indicate an error.\r
1199 *\r
1200 *  @param[in]\r
1201 *       hBcp                BCP driver handle obtained using @a Bcp_open () \r
1202 *                           API.\r
1203 *\r
1204 *  @param[in]  \r
1205 *       pBcpRxCfg           Input structure that holds configuration for the\r
1206 *                           Rx object. MUST be a valid handle on local device.\r
1207 *                           MUST be set to NULL on remote device.\r
1208 *\r
1209 *  @param[in]  \r
1210 *       pRxEndpointCfg      Transport layer's Rx endpoint configuration. MUST be\r
1211 *                           valid on remote device. Can be NULL or a valid handle\r
1212 *                           on local device, depending on whether BCP output\r
1213 *                           is going to be processed on local device or not.\r
1214 *\r
1215 *  @return      Bcp_RxHandle\r
1216 *  @li          NULL                -   Error. Invalid Rx object configuration. \r
1217 *  @li          Valid Rx handle     -   Success. BCP Rx object, Rx queue successfully \r
1218 *                                       setup. \r
1219 *\r
1220 *  @pre\r
1221 *  @n   Valid BCP driver handle must be obtained by calling @a Bcp_open () API\r
1222 *       by the application before calling this API. \r
1223 *\r
1224 *  @post\r
1225 *  @n   A Rx queue, flow successfully setup with input configuration specified on local \r
1226 *       device. On remote device, Rx remote endpoint is opened. The\r
1227 *       Rx object can now be used to retrieve results from the BCP. \r
1228 * ============================================================================\r
1229 */\r
1230 Bcp_RxHandle Bcp_rxOpen\r
1231 (\r
1232     Bcp_DrvHandle               hBcp,\r
1233     Bcp_RxCfg*                  pBcpRxCfg,\r
1234     void*                       pRxEndpointCfg\r
1235 )\r
1236 {\r
1237     int32_t                     result;                \r
1238     Bcp_DrvInfo*                pBcpDrvInfo;\r
1239     Qmss_QueueHnd               hQmssRxQ = (Qmss_QueueHnd)NULL;\r
1240     Cppi_RxChInitCfg            rxChInitCfg;\r
1241     Cppi_ChHnd                  hCppiRxChan = NULL;  \r
1242     Cppi_FlowHnd                hCppiRxFlow;\r
1243     Qmss_QueueType              queueType=Qmss_QueueType_UNSPECIFIED;\r
1244     Bcp_RxInfo*                 pRxObjInfo = NULL;\r
1245     Bcp_RxGlobalInfo*           pRxGlobalObjInfo = NULL;\r
1246     int32_t                     instNum, flowId;\r
1247     Bcp_FlowInfo*               pFlowInfo;\r
1248     void*                       hRxEndpointInfo = NULL;\r
1249     Cppi_PSLoc                  psLocation;\r
1250     uint8_t                     isAllocated, bPSInfoPresent;\r
1251 \r
1252     /* Validate input. */\r
1253     if (!hBcp)\r
1254     {\r
1255         Bcp_osalLog ("Error! Invalid BCP driver handle passed! \n");\r
1256         return NULL;\r
1257     }\r
1258 \r
1259     pBcpDrvInfo   =   (Bcp_DrvInfo *) hBcp;\r
1260     instNum         =   pBcpDrvInfo->instNum;\r
1261 \r
1262     if ((pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL && !pBcpRxCfg) ||\r
1263         (pBcpDrvInfo->mode == Bcp_DrvMode_REMOTE && !pRxEndpointCfg)) \r
1264     {\r
1265         Bcp_osalLog ("Error! Invalid Rx configuration handle provided! \n");\r
1266         return NULL;\r
1267     }\r
1268 \r
1269     /* Critical Section Start */\r
1270     Bcp_osalMultiCoreCsEnter ();            \r
1271 \r
1272     Bcp_osalBeginMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1273 \r
1274     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1275     {\r
1276         /************* Rx queue and Interrupt Setup. *****************/\r
1277 \r
1278         /* Open the Rx Queue for this Rx object based on input specified.\r
1279          *\r
1280          * We need to specify either a Rx queue number or a queue type.\r
1281          * If a queue is specified, assume that the queueType is also chosen and correct. \r
1282          * If a queue is not specified, then set the queueType to be general purpose.\r
1283          */\r
1284         if (pBcpRxCfg->rxQNum == QMSS_PARAM_NOT_SPECIFIED)\r
1285         {\r
1286             /* No specific queue number specified. Lets pick next available \r
1287              * Rx Queue from the General purpose queue pool since we do not\r
1288              * need any interrupt capability on it.\r
1289              */\r
1290             queueType = Qmss_QueueType_GENERAL_PURPOSE_QUEUE;            \r
1291         }\r
1292         if ((hQmssRxQ = Qmss_queueOpen (queueType, pBcpRxCfg->rxQNum, &isAllocated)) < 0)\r
1293         {\r
1294             Bcp_osalLog ("Error opening Rx Queue Number %d \n",pBcpRxCfg->rxQNum);\r
1295             goto return_error;\r
1296         }\r
1297 \r
1298         /* Get the receive queue number in case it wasnt specified */\r
1299         pBcpRxCfg->rxQNum       =   Qmss_getQIDFromHandle(hQmssRxQ);\r
1300     \r
1301         /* Configure interrupts using the application specified accumulator configuration. */\r
1302         if (pBcpRxCfg->bUseInterrupts)\r
1303         {\r
1304             /* Ensure that the accumulator channel is not already in use. */\r
1305             result = Qmss_disableAccumulator (Qmss_PdspId_PDSP1, pBcpRxCfg->accumCfg.channel);\r
1306             if (result != QMSS_ACC_SOK && result != QMSS_ACC_CHANNEL_NOT_ACTIVE)\r
1307             {\r
1308                 Bcp_osalLog ("Error disabling high priority accumulator for channel : %d error code: %d\n",\r
1309                             pBcpRxCfg->accumCfg.channel, result);\r
1310                 goto return_error;\r
1311             }\r
1312 \r
1313             /* Program the accumulator */\r
1314             if ((result = Qmss_programAccumulator (Qmss_PdspId_PDSP1, &pBcpRxCfg->accumCfg)) != QMSS_ACC_SOK)\r
1315             {\r
1316                 Bcp_osalLog ("Error programming high priority accumulator for channel : %d queue : %d error code : %d\n",\r
1317                             pBcpRxCfg->accumCfg.channel, pBcpRxCfg->accumCfg.queMgrIndex, result);\r
1318                 goto return_error;\r
1319             }\r
1320         }\r
1321 \r
1322         /************* Flow and Channel Setup. *****************/\r
1323 \r
1324         /* The Rx channel is mapped one to one with Rx QFIFO. */\r
1325         rxChInitCfg.channelNum          = pBcpRxCfg->tmFlowCfg.qfifo_out; \r
1326         rxChInitCfg.rxEnable            = Cppi_ChState_CHANNEL_DISABLE; \r
1327         if ((hCppiRxChan = Cppi_rxChannelOpen (gBcp_instanceInfo[instNum].hCppi, \r
1328                                                &rxChInitCfg, \r
1329                                                &isAllocated)) == NULL)\r
1330         {\r
1331             Bcp_osalLog ("Error opening Rx channel: %d \n", rxChInitCfg.channelNum);\r
1332             goto return_error;\r
1333         }\r
1334     \r
1335         /* Configure the Rx flow with the parameters specified by application */\r
1336         if ((hCppiRxFlow = Cppi_configureRxFlow (gBcp_instanceInfo[instNum].hCppi, \r
1337                                                 &pBcpRxCfg->flowCfg, \r
1338                                                 &isAllocated)) == NULL)\r
1339         {\r
1340             Bcp_osalLog ("Error configuring Rx flow \n");\r
1341             goto return_error;\r
1342         }\r
1343 \r
1344         /* Also enable Rx Channel */\r
1345         Cppi_channelEnable (hCppiRxChan);\r
1346 \r
1347         /* Setup TM flow entry corresponding to CPPI Rx flow just setup.\r
1348          *\r
1349          * CPPI Rx flows in BCP CDMA are mapped one to one with TM flows. \r
1350          */\r
1351         flowId          =   Cppi_getFlowId (hCppiRxFlow);\r
1352         Bcp_setTmFlowEntry (&gBcp_instanceInfo[instNum].bcpLldObj, flowId, &pBcpRxCfg->tmFlowCfg);\r
1353 \r
1354         /* No Rx tunnel needed to receive packets from BCP if it is local. */\r
1355         hRxEndpointInfo =   NULL;\r
1356 \r
1357         /* PS Info read from Rx descriptors is no longer reliable because\r
1358          * of a CDMA H/W Bug. Hence save the settings so as to use on Rx\r
1359          * results.\r
1360          */    \r
1361         bPSInfoPresent  =   pBcpRxCfg->flowCfg.rx_psinfo_present;\r
1362         psLocation      =   (Cppi_PSLoc) pBcpRxCfg->flowCfg.rx_ps_location;\r
1363 \r
1364         if (pRxEndpointCfg)\r
1365         {\r
1366             if ((hRxEndpointInfo = pBcpDrvInfo->pFxnBcpTunnel_rxOpen (pRxEndpointCfg)) == NULL)\r
1367             {\r
1368                 Bcp_osalLog ("Error creating BCP tunnel Rx local end point! \n");\r
1369                 goto return_error;\r
1370             }\r
1371         }\r
1372     }\r
1373     else\r
1374     {\r
1375         /* Create a tunnel Rx endpoint only if the application is on remote device and wants to\r
1376          * receive data from BCP.\r
1377          */\r
1378         if ((hRxEndpointInfo = pBcpDrvInfo->pFxnBcpTunnel_rxOpen (pRxEndpointCfg)) == NULL)\r
1379         {\r
1380             Bcp_osalLog ("Error creating BCP tunnel Rx remote end point! \n");\r
1381             goto return_error;\r
1382         }\r
1383         bPSInfoPresent  =   0;\r
1384         psLocation      =   (Cppi_PSLoc)0;\r
1385     }\r
1386 \r
1387     /************* Save Info and Return. *****************/\r
1388     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1389     {\r
1390         /* Get the next available slot from Rx object global database to store our info. */\r
1391         if ((result = Bcp_getNextAvailRxObjId (instNum)) == BCP_RETVAL_EFAILURE)\r
1392         {\r
1393             Bcp_osalLog ("Error! Max number of Rx objects exceeded. \n");\r
1394             goto return_error;\r
1395         }\r
1396         pRxGlobalObjInfo    =   &gBcp_instanceInfo[pBcpDrvInfo->instNum].Bcp_rxObjGlobalInfo[result];\r
1397         memset ((void*) pRxGlobalObjInfo, 0, sizeof (Bcp_RxGlobalInfo));\r
1398         pRxGlobalObjInfo->Id            =   result;\r
1399         pRxGlobalObjInfo->bIsValid      =   1;\r
1400         pRxGlobalObjInfo->flowId        =   flowId;   \r
1401         pRxGlobalObjInfo->rxQNum        =   pBcpRxCfg->rxQNum;\r
1402 \r
1403         /* Save the flow settings. */\r
1404         pFlowInfo   =   &gBcp_instanceInfo[instNum].Bcp_flowInfo[flowId];\r
1405         memset (pFlowInfo, 0, sizeof (Bcp_FlowInfo));  \r
1406         pFlowInfo->hCppiRxFlow          =   hCppiRxFlow;    \r
1407         pFlowInfo->flowId               =   flowId;   \r
1408         pFlowInfo->bPSInfoPresent       =   bPSInfoPresent;\r
1409         pFlowInfo->psLocation           =   psLocation;\r
1410     \r
1411         /* Increment the flow reference count to keep it around while in use by this Rx object. */\r
1412         pFlowInfo->refCnt ++;\r
1413     }\r
1414     else\r
1415     {\r
1416         /* In remote case, no BCP flow is created. Hence we dont need a BCP flow info            \r
1417          * object or a Rx global object.\r
1418          */\r
1419         result  =   -1;            \r
1420         flowId  =   -1;\r
1421     }\r
1422 \r
1423     /* Allocate memory for holding the Rx object info */\r
1424     if ((pRxObjInfo = Bcp_osalMalloc (sizeof (Bcp_RxInfo), FALSE)) == NULL)\r
1425     {\r
1426         Bcp_osalLog ("Error allocating memory for Rx object \n");\r
1427         goto return_error;\r
1428     }\r
1429     memset ((void*) pRxObjInfo, 0, sizeof (Bcp_RxInfo));\r
1430 \r
1431     pRxObjInfo->hBcp                =   hBcp;\r
1432     pRxObjInfo->hRxEndpointInfo     =   hRxEndpointInfo;\r
1433     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1434     {\r
1435         pRxObjInfo->flowId          =   flowId;   \r
1436         pRxObjInfo->rxQNum          =   pBcpRxCfg->rxQNum;\r
1437         pRxObjInfo->cfg             =   *pBcpRxCfg;\r
1438         pRxObjInfo->hQmssRxQ        =   hQmssRxQ;\r
1439         pRxObjInfo->globalObjId         =       result;\r
1440         pRxObjInfo->bPSInfoPresent  =   bPSInfoPresent;\r
1441         pRxObjInfo->psLocation      =   psLocation;\r
1442         pRxObjInfo->hCppiRxChan     =   hCppiRxChan;\r
1443     }\r
1444 \r
1445     Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1446 \r
1447     /* Done here. Release the CS lock */\r
1448     Bcp_osalMultiCoreCsExit ();\r
1449 \r
1450     /* Return success. Return global Rx object handle. */\r
1451     return ((Bcp_RxHandle) pRxObjInfo);\r
1452 \r
1453 return_error:\r
1454     /* Close the Rx queue just opened. */\r
1455     if (hQmssRxQ)\r
1456         Qmss_queueClose (hQmssRxQ);\r
1457 \r
1458     if (hRxEndpointInfo)\r
1459         pBcpDrvInfo->pFxnBcpTunnel_rxClose (hRxEndpointInfo);                    \r
1460 \r
1461     if (hCppiRxChan)\r
1462         Cppi_channelClose (hCppiRxChan);\r
1463 \r
1464     /* Free up the Rx object */\r
1465     if (pRxObjInfo)\r
1466         Bcp_osalFree ((void *)pRxObjInfo, sizeof (Bcp_RxInfo), FALSE);\r
1467 \r
1468     /* Free up the Rx object's global counterpart too. */\r
1469     if (pRxGlobalObjInfo)\r
1470         pRxGlobalObjInfo->bIsValid  =   0;\r
1471 \r
1472     Bcp_osalEndMemAccess (&gBcp_instanceInfo[instNum], sizeof (Bcp_InstanceInfo));\r
1473 \r
1474     /* exit critical section */\r
1475     Bcp_osalMultiCoreCsExit ();\r
1476 \r
1477     return NULL;\r
1478 }\r
1479 \r
1480 /**\r
1481 * ============================================================================\r
1482 *  @n@b Bcp_rxClose\r
1483 *\r
1484 *  @b   brief\r
1485 *  @n   This API closes the Rx object, any Rx tunnel endpoints. \r
1486 *\r
1487 *       On local device, the API closes the Rx flow and cleans up all \r
1488 *       associated queue and channel handles. \r
1489 *\r
1490 *       On remote device, the API invokes the corresponding Rx tunnel endpoint \r
1491 *       close API.\r
1492 *\r
1493 *  @param[in]\r
1494 *       hBcpRxInfo          BCP Rx object handle obtained using @a Bcp_rxOpen() \r
1495 *                           API.\r
1496 *\r
1497 *  @return     Bcp_RetVal\r
1498 *  @li         BCP_RETVAL_EBAD_HANDLE  -   BCP Rx object close failed.\r
1499 *  @li         BCP_RETVAL_SUCCESS      -   BCP Rx object successfully closed.\r
1500 *\r
1501 *  @pre\r
1502 *  @n   Valid Rx object handle must be obtained using Bcp_rxOpen () API \r
1503 *       before calling this API.\r
1504 *\r
1505 *  @post\r
1506 *  @n   BCP Rx object, Rx flow successfully closed on local device. Rx endpoint\r
1507 *       close callback API invoked.\r
1508 * ============================================================================\r
1509 */\r
1510 Bcp_RetVal Bcp_rxClose \r
1511 (\r
1512     Bcp_RxHandle                hBcpRxInfo\r
1513 )\r
1514 {\r
1515     Bcp_RxInfo*                 pRxObjInfo;\r
1516     Bcp_RxGlobalInfo*           pRxGlobalObjInfo;\r
1517     uint16_t                    flowId;\r
1518     Bcp_DrvInfo*                pBcpDrvInfo;\r
1519     Bcp_FlowInfo*               pFlowInfo;\r
1520 \r
1521     /* Validate input handles and driver state  */\r
1522     if (!hBcpRxInfo)\r
1523     {\r
1524         Bcp_osalLog ("Invalid Receive Object Handle provided \n");\r
1525         return BCP_RETVAL_EBAD_HANDLE;  \r
1526     }\r
1527 \r
1528     pRxObjInfo      =   (Bcp_RxInfo *) hBcpRxInfo;\r
1529     pBcpDrvInfo     =   (Bcp_DrvInfo *) pRxObjInfo->hBcp;\r
1530     flowId          =   pRxObjInfo->flowId;\r
1531 \r
1532     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1533     {\r
1534         /* Enter Critical Section */\r
1535         Bcp_osalMultiCoreCsEnter ();\r
1536             \r
1537         Bcp_osalBeginMemAccess (&gBcp_instanceInfo[pBcpDrvInfo->instNum], sizeof (Bcp_InstanceInfo));\r
1538 \r
1539         /* Clean up all BCP CPPI resources if BCP is local to the application */            \r
1540         pFlowInfo       =   &gBcp_instanceInfo[pBcpDrvInfo->instNum].Bcp_flowInfo[flowId];\r
1541         pRxGlobalObjInfo=   &gBcp_instanceInfo[pBcpDrvInfo->instNum].Bcp_rxObjGlobalInfo[pRxObjInfo->globalObjId];\r
1542 \r
1543         /* Close the Rx queue */\r
1544         Qmss_queueClose (pRxObjInfo->hQmssRxQ);\r
1545 \r
1546         /* Decrement reference count to release the flow */\r
1547         pFlowInfo->refCnt --;\r
1548 \r
1549         /* If flow not in use by any Rx object clean it up */\r
1550         if (pFlowInfo->refCnt == 0)\r
1551             Cppi_closeRxFlow (pFlowInfo->hCppiRxFlow);\r
1552 \r
1553         /* Disable the Rx channel */            \r
1554         Cppi_channelDisable (pRxObjInfo->hCppiRxChan);\r
1555         Cppi_channelClose (pRxObjInfo->hCppiRxChan);\r
1556 \r
1557         /* Free up the Rx object's global counterpart too. */\r
1558         pRxGlobalObjInfo->bIsValid  =   0;\r
1559 \r
1560         if (pRxObjInfo->hRxEndpointInfo)\r
1561             pBcpDrvInfo->pFxnBcpTunnel_rxClose (pRxObjInfo->hRxEndpointInfo);            \r
1562 \r
1563         Bcp_osalEndMemAccess (&gBcp_instanceInfo[pBcpDrvInfo->instNum], sizeof (Bcp_InstanceInfo));\r
1564 \r
1565         /* Release CS lock */\r
1566         Bcp_osalMultiCoreCsExit ();\r
1567     }\r
1568     else\r
1569     {\r
1570         /* Clean up the remote Rx endpoint we had created earlier */            \r
1571         pBcpDrvInfo->pFxnBcpTunnel_rxClose (pRxObjInfo->hRxEndpointInfo);            \r
1572     }\r
1573 \r
1574     /* Free up the Rx object space */\r
1575     Bcp_osalFree (pRxObjInfo, sizeof (Bcp_RxInfo), FALSE);\r
1576    \r
1577     /* Return Success */\r
1578     return BCP_RETVAL_SUCCESS;\r
1579 }\r
1580 \r
1581 /**\r
1582 * ============================================================================\r
1583 *  @n@b Bcp_findFlowIdByQueueNumber\r
1584 *\r
1585 *  @b   brief\r
1586 *  @n   Given a Rx queue number, this API returns the corresponding flow Id \r
1587 *       associated from the driver's Rx object database.\r
1588 *\r
1589 *  @param[in]\r
1590 *       hBcp                BCP driver handle obtained using @a Bcp_open () \r
1591 *                           API. Specifies which BCP instance to search for \r
1592 *                           a match.\r
1593 *  @param[in]\r
1594 *       rxQueueNumber       Rx queue number for which the flow Id lookup must\r
1595 *                           be performed.\r
1596 *\r
1597 *  @return     Bcp_RetVal\r
1598 *  @li         <0                       -   Flow Id retrieval failed. Unable \r
1599 *                                           to find a flow for the Rx queue \r
1600 *                                           number and BCP instance\r
1601 *                                           provided in the driver database.\r
1602 *  @li         >=0                      -   Success. Valid Flow Id returned.\r
1603 *\r
1604 *  @pre\r
1605 *  @n   A valid driver handle must be obtained using @a Bcp_open () API \r
1606 *       before calling this API.\r
1607 *\r
1608 *  @post\r
1609 *  @n   None.\r
1610 * ============================================================================\r
1611 */\r
1612 Bcp_RetVal Bcp_findFlowIdByQueueNumber\r
1613 (\r
1614     Bcp_DrvHandle               hBcp,\r
1615     uint32_t                    rxQueueNumber\r
1616 )\r
1617 {\r
1618     uint32_t                    i;\r
1619     Bcp_DrvInfo*                pBcpDrvInfo;\r
1620     Bcp_InstanceInfo*           pBcpInstInfo;\r
1621 \r
1622     /* Invalid driver handle specified. */\r
1623     if (!hBcp)\r
1624     {\r
1625         Bcp_osalLog ("Invalid driver handle specified \n");\r
1626         return BCP_RETVAL_EBAD_HANDLE;            \r
1627     }\r
1628 \r
1629     pBcpDrvInfo           =   (Bcp_DrvInfo *) hBcp;\r
1630 \r
1631     if (pBcpDrvInfo->mode == Bcp_DrvMode_REMOTE)\r
1632         return BCP_RETVAL_ENOT_SUPPORTED;            \r
1633 \r
1634     /* Enter critical section */\r
1635     Bcp_osalMultiCoreCsEnter ();\r
1636 \r
1637     Bcp_osalBeginMemAccess (&gBcp_instanceInfo[pBcpDrvInfo->instNum], sizeof (Bcp_InstanceInfo));\r
1638 \r
1639     pBcpInstInfo           =   (Bcp_InstanceInfo *)&gBcp_instanceInfo [pBcpDrvInfo->instNum];\r
1640 \r
1641     /* Search through the driver's database of all valid\r
1642      * Rx objects for the BCP instance corresponding to the \r
1643      * driver handle passed to find a matching entry\r
1644      * for Rx queue number provided.\r
1645      */\r
1646     for (i = 0; i < BCP_MAX_NUM_RXOBJECTS; i ++)\r
1647     {\r
1648         if ((pBcpInstInfo->Bcp_rxObjGlobalInfo[i].bIsValid) && \r
1649             (pBcpInstInfo->Bcp_rxObjGlobalInfo[i].rxQNum == rxQueueNumber))\r
1650         {\r
1651             /* Found a match. Return the flow Id corresponding to this object. */                \r
1652             break;                \r
1653         }\r
1654     }\r
1655 \r
1656     /* Check if we found a match or if we are here\r
1657      * because we are done searching through all entries\r
1658      * and found no matches.\r
1659      */\r
1660     if (i == BCP_MAX_NUM_RXOBJECTS)\r
1661     {\r
1662         /* Found no match. Return error */            \r
1663     \r
1664         /* Exit critical section */\r
1665         Bcp_osalMultiCoreCsExit ();\r
1666 \r
1667         return BCP_RETVAL_EINVALID_PARAMS;\r
1668     }\r
1669 \r
1670     /* Exit critical section */\r
1671     Bcp_osalMultiCoreCsExit ();\r
1672 \r
1673     /* Success. Return flow id found. */\r
1674     return (pBcpInstInfo->Bcp_rxObjGlobalInfo[i].flowId);\r
1675 }\r
1676 \r
1677 /**\r
1678 * ============================================================================\r
1679 *  @n@b Bcp_rxGetRxQueueNumber\r
1680 *\r
1681 *  @b   brief\r
1682 *  @n   This API retrieves the given Rx object's Receive queue number.\r
1683 *       This API is especially useful if the application didnt specify a \r
1684 *       Rx Queue number during @a Bcp_rxOpen () API and would like to\r
1685 *       retrieve the queue number at a later point.\r
1686 *\r
1687 *       This API is supported only on BCP local device, i.e., if BCP driver\r
1688 *       was initialized in "local" mode.\r
1689 *\r
1690 *  @param[in]\r
1691 *       hBcpRxInfo          BCP Rx object handle obtained using \r
1692 *                           @a Bcp_rxOpen() API.\r
1693 \r
1694 *\r
1695 *  @return  Bcp_RetVal\r
1696 *  @li      BCP_RETVAL_EBAD_HANDLE      -   Rx Queue Number retrieval failed.\r
1697 *  @li      BCP_RETVAL_ENOT_SUPPORTED   -   This API not supported on BCP remote\r
1698 *                                           device.\r
1699 *  @li      >=0                         -   The destination queue number associated \r
1700 *                                           with the Rx object's flow.\r
1701 *\r
1702 *  @pre\r
1703 *  @n   Valid Rx object handle must be obtained using @a Bcp_rxOpen () API \r
1704 *       before calling this API.\r
1705 *\r
1706 *  @post\r
1707 *  @n   None.\r
1708 * ============================================================================\r
1709 */\r
1710 Bcp_RetVal Bcp_rxGetRxQueueNumber\r
1711 (\r
1712     Bcp_RxHandle                hBcpRxInfo\r
1713 )\r
1714 {\r
1715     Bcp_RxInfo*                 pRxObjInfo;\r
1716     Bcp_DrvInfo*                pBcpDrvInfo;\r
1717 \r
1718     /* Invalid Rx object handle specified. */\r
1719     if (!hBcpRxInfo)\r
1720     {\r
1721         Bcp_osalLog ("Invalid Rx object handle specified \n");\r
1722         return BCP_RETVAL_EBAD_HANDLE;            \r
1723     }\r
1724 \r
1725     pRxObjInfo  =   (Bcp_RxInfo *) hBcpRxInfo;        \r
1726     pBcpDrvInfo =   (Bcp_DrvInfo *) pRxObjInfo->hBcp;\r
1727 \r
1728     /* Return the destination queue number saved in the Rx object info */\r
1729     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1730         return (pRxObjInfo->rxQNum);\r
1731     else\r
1732         return BCP_RETVAL_ENOT_SUPPORTED;            \r
1733 }\r
1734 \r
1735 \r
1736 /**\r
1737 * ============================================================================\r
1738 *  @n@b Bcp_rxGetFlowId\r
1739 *\r
1740 *  @b   brief\r
1741 *  @n   This API retrieves a given Rx object's Rx flow id number.\r
1742 *\r
1743 *       This API is supported only on BCP local device, i.e., if BCP driver\r
1744 *       was initialized in "local" mode.\r
1745 *\r
1746 *  @param[in]\r
1747 *       hBcpRxInfo              BCP Rx object handle obtained using \r
1748 *                               @a Bcp_rxOpen() API.\r
1749 *\r
1750 *  @return  Bcp_RetVal\r
1751 *  @li      BCP_RETVAL_EBAD_HANDLE      -   Flow Id value retrieval failed.\r
1752 *                                           Invalid Rx object handle passed.\r
1753 *  @li      BCP_RETVAL_ENOT_SUPPORTED   -   This API not supported on BCP remote\r
1754 *                                           device.\r
1755 *  @li         >=0                      -   The Flow Id associated with the Rx object\r
1756 *                                           ranging between 0 and (BCP_MAX_NUM_FLOWS-1) \r
1757 *                                           (both inclusive).\r
1758 *\r
1759 *  @pre\r
1760 *  @n   Valid Rx object handle must be obtained using @a Bcp_rxOpen () API \r
1761 *       before calling this API.\r
1762 *\r
1763 *  @post\r
1764 *  @n   None.\r
1765 * ============================================================================\r
1766 */\r
1767 Bcp_RetVal Bcp_rxGetFlowId\r
1768 (\r
1769     Bcp_RxHandle                hBcpRxInfo\r
1770 )\r
1771 {\r
1772     Bcp_RxInfo*                 pRxObjInfo;\r
1773     Bcp_DrvInfo*                pBcpDrvInfo;\r
1774 \r
1775     /* Invalid Rx object handle specified. */\r
1776     if (!hBcpRxInfo)\r
1777     {\r
1778         Bcp_osalLog ("Invalid Rx object handle specified \n");\r
1779         return BCP_RETVAL_EBAD_HANDLE;            \r
1780     }\r
1781 \r
1782     pRxObjInfo  =   (Bcp_RxInfo *) hBcpRxInfo;        \r
1783     pBcpDrvInfo =   (Bcp_DrvInfo *) pRxObjInfo->hBcp;\r
1784 \r
1785     /* Return flow id */\r
1786     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1787         return (pRxObjInfo->flowId);\r
1788     else\r
1789         return BCP_RETVAL_ENOT_SUPPORTED;\r
1790 }\r
1791 \r
1792 /**\r
1793 * ============================================================================\r
1794 *  @n@b Bcp_send\r
1795 *\r
1796 *  @b   brief\r
1797 *  @n   Given a Tx object handle, descriptor containing data, and the descriptor \r
1798 *       size, this API pushes the data onto BCP Tx queue for processing. \r
1799 *\r
1800 *       On remote device, this API instead invokes the BCP transport \r
1801 *       layer's send API to send out the packet to BCP using appropriate\r
1802 *       transport mechanism.\r
1803 *\r
1804 *  @param[in]\r
1805 *       hBcpTxInfo          Tx handle obtained using @a Bcp_txOpen () API.\r
1806 *\r
1807 *  @param[in]\r
1808 *       hDrvBuffer          CPPI descriptor built by the application containing \r
1809 *                           data to be processed by BCP.\r
1810 *\r
1811 *  @param[in]\r
1812 *       drvBufferLen        Size of the CPPI descriptor being sent.\r
1813 *\r
1814 *  @param[in]\r
1815 *       pDestnAddress       Destination device info. On remote device, will contain\r
1816 *                           information regarding BCP device and on local device\r
1817 *                           must be set to NULL.\r
1818 *\r
1819 *  @return      Bcp_RetVal\r
1820 *  @li          BCP_RETVAL_EBAD_HANDLE     -    Invalid input handles provided. \r
1821 *                                               BCP send failed.\r
1822 *  @li          BCP_RETVAL_SUCCESS         -    Successfully sent data for BCP\r
1823 *                                               processing.\r
1824 *\r
1825 *  @pre\r
1826 *  @n   A valid Tx object handle must be obtained using @a Bcp_txOpen (), and a \r
1827 *       valid descriptor handle, length must be passed to this API.\r
1828 *\r
1829 *  @post\r
1830 *  @n   Data pushed onto BCP Tx queue corresponding to the Tx object handle \r
1831 *       passed.\r
1832 *\r
1833 * ============================================================================\r
1834 */\r
1835 Bcp_RetVal Bcp_send\r
1836 (\r
1837     Bcp_TxHandle                hBcpTxInfo,\r
1838     Bcp_DrvBufferHandle         hDrvBuffer,\r
1839     uint32_t                    drvBufferLen,\r
1840     void*                       pDestnAddress\r
1841 )\r
1842 {\r
1843     Bcp_DrvInfo*                pBcpDrvInfo;        \r
1844     Bcp_TxInfo*                 pTxObjInfo;     \r
1845     Cppi_Desc*                  pCppiDesc;\r
1846 \r
1847 #ifdef BCP_DRV_DEBUG\r
1848     /* Validate input handles */\r
1849     if (!hDrvBuffer)            \r
1850     {\r
1851         Bcp_osalLog("Invalid descriptor handle provided. \n");\r
1852         return BCP_RETVAL_EBAD_HANDLE;\r
1853     }\r
1854 \r
1855     if (!hBcpTxInfo)\r
1856     {\r
1857         Bcp_osalLog ("Invalid Tx object handle provided \n");\r
1858         return BCP_RETVAL_EBAD_HANDLE;\r
1859     }\r
1860 #endif\r
1861 \r
1862     pTxObjInfo          =   (Bcp_TxInfo *) hBcpTxInfo;\r
1863     pBcpDrvInfo         =   (Bcp_DrvInfo *) pTxObjInfo->hBcp;\r
1864     pCppiDesc           =   (Cppi_Desc *) hDrvBuffer;\r
1865 \r
1866     if (pBcpDrvInfo->mode == Bcp_DrvMode_LOCAL)\r
1867     {\r
1868         /* Push descriptor onto BCP Tx queue */\r
1869         Qmss_queuePushDescSize (pTxObjInfo->pTxQInfo->hQmssTxQ, pCppiDesc, drvBufferLen);    \r
1870     }\r
1871     else\r
1872     {\r
1873         /* Send data to BCP using BCP transport layer */\r
1874         return pBcpDrvInfo->pFxnBcpTunnel_send (pTxObjInfo->hTxEndpointInfo, pCppiDesc, drvBufferLen, pDestnAddress);\r
1875     }\r
1876 \r
1877     /* Return success. */\r
1878     return BCP_RETVAL_SUCCESS;\r
1879 }\r
1880 \r
1881 /**\r
1882 * ============================================================================\r
1883 *  @n@b Bcp_rxGetNumOutputEntries\r
1884 *\r
1885 *  @b   brief\r
1886 *  @n   Given a Rx object handle, this API retrieves the number of BCP output\r
1887 *       entries pending to be serviced by the application for it.\r
1888 *\r
1889 *  @param[in]\r
1890 *       hBcpRxInfo          Rx handle obtained using @a Bcp_rxOpen () API.\r
1891 *\r
1892 *  @return  int32_t\r
1893 *  @li      BCP_RETVAL_EBAD_HANDLE      -   Invalid input Rx handle provided.\r
1894 *  @li      BCP_RETVAL_ENOT_SUPPORTED   -   API not supported on remote device.\r
1895 *  @li          >=0                     -   Number of pending output entries \r
1896 *                                           for this Rx object.  \r
1897 *\r
1898 *  @pre\r
1899 *  @n   A valid Rx object handle must be obtained using @a Bcp_rxOpen () \r
1900 *       API before calling this API.\r
1901 *\r
1902 *  @post\r
1903 *  @n   Returns the number of BCP output entries available for this Rx object.\r
1904 * ============================================================================\r
1905 */\r
1906 Bcp_RetVal Bcp_rxGetNumOutputEntries \r
1907 (\r
1908     Bcp_RxHandle                hBcpRxInfo\r
1909 )\r
1910 {    \r
1911     Bcp_RxInfo*                 pRxObjInfo;\r
1912     Bcp_DrvInfo*                pBcpDrvInfo;\r
1913 \r
1914 #ifdef BCP_DRV_DEBUG\r
1915     /* Validate input */\r
1916     if (!hBcpRxInfo)\r
1917     {\r
1918         Bcp_osalLog ("Invalid Rx object Handle provided \n");\r
1919         return BCP_RETVAL_EBAD_HANDLE;\r
1920     }\r
1921 #endif\r
1922 \r
1923     pRxObjInfo      =   (Bcp_RxInfo *)hBcpRxInfo;        \r
1924     pBcpDrvInfo     =   (Bcp_DrvInfo *)pRxObjInfo->hBcp;\r
1925 \r
1926     if (pBcpDrvInfo->mode == Bcp_DrvMode_REMOTE)\r
1927         return BCP_RETVAL_ENOT_SUPPORTED;\r
1928 \r
1929     if (pRxObjInfo->cfg.bUseInterrupts)\r
1930     {\r
1931         /* ISR not managed by driver. So no idea! */            \r
1932         return BCP_RETVAL_EBAD_HANDLE;            \r
1933     }\r
1934     else\r
1935     {\r
1936         /* Check the destination queue for the number of result packets to be serviced. */\r
1937         return (Qmss_getQueueEntryCount (pRxObjInfo->hQmssRxQ));\r
1938     }\r
1939 }\r
1940 \r
1941 /**\r
1942 * ============================================================================\r
1943 *  @n@b Bcp_recv\r
1944 *\r
1945 *  @b   brief\r
1946 *  @n   Given an Rx object handle, this API checks if there is any output\r
1947 *       available on the Rx queue from the BCP for its processing. If so, \r
1948 *       it does some basic validation on it and returns the descriptor handle, \r
1949 *       corresponding data buffer, its length, and any PS info found to the calling \r
1950 *       application. If no output found, this API either returns status to indicate \r
1951 *       the same.\r
1952 *\r
1953 *  @param[in]\r
1954 *       hBcpRxInfo          Rx handle obtained using @a Bcp_rxOpen () API.\r
1955 *\r
1956 *  @param[out]\r
1957 *       phDrvBuffer         Pointer to hold the output (descriptor) from BCP.\r
1958 *\r
1959 *  @param[out]\r
1960 *       ppDataBuffer        Pointer to hold data buffer pointer obtained from BCP.\r
1961 *\r
1962 *  @param[out]\r
1963 *       pDataBufferLen      Pointer to hold data buffer length, i.e.,holds the number of\r
1964 *                           bytes available to application in the data buffer for use.\r
1965 *\r
1966 *  @param[out]\r
1967 *       ppPSInfo            Pointer to PS Info pointer obtained from BCP.\r
1968 *\r
1969 *  @param[out]\r
1970 *       pPSInfoLen          Pointer to PS Info length, i.e.,holds the number of bytes \r
1971 *                           of PS info available for application to parse.\r
1972 *\r
1973 *  @param[out]\r
1974 *       pFlowId             Flow Id read from the descriptor's Source Tag lower\r
1975 *                           order 8 bits.\r
1976 *\r
1977 *  @param[out]\r
1978 *       pSrcId              Source Id read from the descriptor's Source Tag higher\r
1979 *                           order 8 bits.\r
1980 *\r
1981 *  @param[out]\r
1982 *       pDestnTagInfo       Destination tag info read from the descriptor.\r
1983 *\r
1984 *  @return      Bcp_RetVal\r
1985 *  @li          BCP_RETVAL_EBAD_HANDLE         -   Invalid input Rx object handle provided.\r
1986 *  @li          BCP_RETVAL_ENO_RESULT          -   No output available yet on the Rx queue.\r
1987 *  @li          BCP_RETVAL_SUCCESS             -   Successfully retrieved output and stored in \r
1988 *                                                  output parameter handles.\r
1989 *\r
1990 *  @pre\r
1991 *  @n   A valid Rx object handle must be obtained using @a Bcp_rxOpen () API \r
1992 *       before calling this API.\r
1993 *\r
1994 *  @post\r
1995 *  @n   If BCP output available, it is validated and handed over to application\r
1996 *       for further processing, otherwise appropriate status is returned.\r
1997 * ============================================================================\r
1998 */\r
1999 Bcp_RetVal Bcp_recv\r
2000 (\r
2001     Bcp_RxHandle                hBcpRxInfo,\r
2002     Bcp_DrvBufferHandle*        phDrvBuffer,\r
2003     uint8_t**                   ppDataBuffer,\r
2004     uint32_t*                   pDataBufferLen,                   \r
2005     uint8_t**                   ppPSInfo,\r
2006     uint32_t*                   pPSInfoLen,\r
2007     uint8_t*                    pFlowId,\r
2008     uint8_t*                    pSrcId,\r
2009     uint16_t*                   pDestnTagInfo\r
2010 )\r
2011 {\r
2012     Bcp_RxInfo*                 pRxObjInfo;\r
2013     Cppi_Desc*                  pCppiDesc;\r
2014     Bcp_DrvInfo*                pBcpDrvInfo;\r
2015 \r
2016 #ifdef BCP_DRV_DEBUG\r
2017     /* Validate input */\r
2018     if (!hBcpRxInfo || !phDrvBuffer || !ppDataBuffer || !pDataBufferLen \r
2019         || !ppPSInfo || !pPSInfoLen || !pFlowId || !pDestnTagInfo\r
2020        )\r
2021     {\r
2022         Bcp_osalLog ("Invalid input handles provided \n");\r
2023         return BCP_RETVAL_EBAD_HANDLE;\r
2024     }\r
2025 #endif\r
2026 \r
2027     pRxObjInfo      =   (Bcp_RxInfo *) hBcpRxInfo;\r
2028     pBcpDrvInfo     =   (Bcp_DrvInfo *) pRxObjInfo->hBcp;\r
2029 \r
2030     if (pBcpDrvInfo->mode == Bcp_DrvMode_REMOTE)\r
2031     {\r
2032         pBcpDrvInfo->pFxnBcpTunnel_recv (pRxObjInfo->hRxEndpointInfo, (void **) &pCppiDesc);            \r
2033 \r
2034         if (*phDrvBuffer == NULL)\r
2035         {\r
2036             /* No BCP output ready yet. */            \r
2037             return BCP_RETVAL_ENO_RESULT;                \r
2038         }\r
2039 \r
2040         /* Get the result info from the descriptor */\r
2041         Bcp_rxProcessDesc (hBcpRxInfo,\r
2042                            pCppiDesc, \r
2043                            phDrvBuffer,\r
2044                            ppDataBuffer,\r
2045                            pDataBufferLen,\r
2046                            ppPSInfo,\r
2047                            pPSInfoLen,\r
2048                            pFlowId,\r
2049                            pSrcId,\r
2050                            pDestnTagInfo);\r
2051     }\r
2052     else\r
2053     {\r
2054         /* Check the Rx queue for any pending output from BCP. */\r
2055         if (!pRxObjInfo->cfg.bUseInterrupts)\r
2056         {\r
2057             /* No interrupts enabled. \r
2058              *\r
2059              * Check the Rx object's destination queue to see if a\r
2060              * result has arrived from the BCP engine or not.\r
2061              */\r
2062             if ((pCppiDesc = Qmss_queuePop (pRxObjInfo->hQmssRxQ)) == NULL)\r
2063             {\r
2064                 /* No BCP output ready yet. */            \r
2065                 return BCP_RETVAL_ENO_RESULT;                \r
2066             }\r
2067 \r
2068             /* Get the result info from the descriptor */\r
2069             Bcp_rxProcessDesc (hBcpRxInfo,\r
2070                                pCppiDesc, \r
2071                                phDrvBuffer,\r
2072                                ppDataBuffer,\r
2073                                pDataBufferLen,\r
2074                                ppPSInfo,\r
2075                                pPSInfoLen,\r
2076                                pFlowId,\r
2077                                pSrcId,\r
2078                                pDestnTagInfo);\r
2079         }\r
2080         else\r
2081         {\r
2082             /* Interrupts enabled for this Rx object.\r
2083              *\r
2084              * Driver is not setup to manage the ISR for this Rx object. \r
2085              * Cannot use this API.\r
2086             */\r
2087             return BCP_RETVAL_EBAD_HANDLE;\r
2088         }\r
2089     }\r
2090 \r
2091     /* Return success. */\r
2092     return BCP_RETVAL_SUCCESS;                \r
2093 }\r
2094 \r
2095 /**\r
2096 * ============================================================================\r
2097 *  @n@b Bcp_rxProcessDesc\r
2098 *\r
2099 *  @b   brief\r
2100 *  @n   This API can be used to retrieve the various fields from\r
2101 *       the output descriptor received from the engine.\r
2102 *\r
2103 *  @param[in]\r
2104 *       hBcpRxInfo          Rx handle obtained using @a Bcp_rxOpen () API.\r
2105 *\r
2106 *  @param[in]\r
2107 *       pCppiDesc           Rx descriptor containing the output that needs to be\r
2108 *                           processed by this API.\r
2109 *\r
2110 *  @param[out]\r
2111 *       phDrvBuffer         Pointer to hold BCP driver output handle.\r
2112 *\r
2113 *  @param[out]\r
2114 *       ppDataBuffer        Pointer to hold data buffer pointer obtained from BCP.\r
2115 *\r
2116 *  @param[out]\r
2117 *       pDataBufferLen      Pointer to data buffer length, i.e.,holds the number of\r
2118 *                           bytes available to application in the output data buffer for\r
2119 *                           parsing.\r
2120 *  @param[out]\r
2121 *       ppPSInfo            Pointer to PS Info pointer obtained from BCP.\r
2122 *\r
2123 *  @param[out]\r
2124 *       pPSInfoLen          Pointer to PS Info length, i.e.,holds the number of bytes \r
2125 *                           of PS info available for application to parse.\r
2126 *  @param[out]\r
2127 *       pFlowId             Flow Id read from the descriptor's Source Tag lower\r
2128 *                           order 8 bits.\r
2129 *\r
2130 *  @param[out]\r
2131 *       pSrcId              Source Id read from the descriptor's Source Tag higher\r
2132 *                           order 8 bits.\r
2133 *  @param[out]\r
2134 *       pDestnTagInfo       Destination tag info read from the descriptor.\r
2135 *\r
2136 *  @return     Bcp_RetVal\r
2137 *  @li         BCP_RETVAL_EBAD_HANDLE      -   Bad input Handle provided.\r
2138 *  @li         BCP_RETVAL_SUCCESS          -   Success.\r
2139 *\r
2140 *  @pre\r
2141 *  @n   A valid CPPI descriptor handle must be sent to this API.\r
2142 * ============================================================================\r
2143 */\r
2144  Bcp_RetVal Bcp_rxProcessDesc \r
2145 (\r
2146     Bcp_RxHandle                hBcpRxInfo,\r
2147     Cppi_Desc*                  pCppiDesc,\r
2148     Bcp_DrvBufferHandle*        phDrvBuffer,\r
2149     uint8_t**                   ppDataBuffer,\r
2150     uint32_t*                   pDataBufferLen,                   \r
2151     uint8_t**                   ppPSInfo,\r
2152     uint32_t*                   pPSInfoLen,\r
2153     uint8_t*                    pFlowId,\r
2154     uint8_t*                    pSrcId,\r
2155     uint16_t*                   pDestnTagInfo\r
2156 )\r
2157 {\r
2158     Cppi_DescTag                cppiTagInfo;\r
2159     Cppi_DescType               descType;\r
2160     Bcp_RxInfo*                 pRxObjInfo;\r
2161 \r
2162 #ifdef BCP_DRV_DEBUG\r
2163     /* Validate input */\r
2164     if (!hBcpRxInfo || !phDrvBuffer || !ppDataBuffer || !pDataBufferLen \r
2165         || !ppPSInfo || !pPSInfoLen || !pFlowId || !pDestnTagInfo\r
2166        )\r
2167     {\r
2168         Bcp_osalLog ("Invalid input Handle provided \n");\r
2169         return BCP_RETVAL_EBAD_HANDLE;\r
2170     }\r
2171 #endif\r
2172 \r
2173     pRxObjInfo  =   hBcpRxInfo;\r
2174 \r
2175     /* Invalidate descriptor to ensure our reads/writes are consistent with \r
2176      * the memory in case descriptor is in cacheable memory.\r
2177      * Since we dont manage the Tx/Rx descriptors, we dont know their sizes. \r
2178      * We pass the Rx handle to the application to help it figure out the\r
2179      * descriptor size.\r
2180      */\r
2181     Bcp_osalBeginDescMemAccess (pRxObjInfo, pCppiDesc);\r
2182     \r
2183     /* The descriptor address returned from the hardware has the \r
2184      * descriptor size appended to the address in the last 4 bits.\r
2185      *\r
2186      * To get the true descriptor size, always mask off the last \r
2187      * 4 bits of the address.\r
2188      */\r
2189     pCppiDesc = (void*) (QMSS_DESC_PTR (pCppiDesc));    \r
2190     descType = Cppi_getDescType (pCppiDesc);\r
2191 \r
2192     /* Get the source and destination tag information */\r
2193     cppiTagInfo         =   Cppi_getTag (descType, pCppiDesc);\r
2194     *pSrcId             =   cppiTagInfo.srcTagHi;\r
2195     *pFlowId            =   cppiTagInfo.srcTagLo;\r
2196     *pDestnTagInfo      =   ((cppiTagInfo.destTagHi << 8) | (cppiTagInfo.destTagLo));\r
2197 \r
2198     /* Store the descriptor in the output driver buffer handle.\r
2199      *\r
2200      * Required when freeing the descriptor to restore it back to Rx FDQ\r
2201      */\r
2202     *phDrvBuffer        =   (Bcp_DrvBufferHandle) pCppiDesc;\r
2203 \r
2204     /* Get Data buffer containing the output and its length */\r
2205     Cppi_getData (descType, pCppiDesc, ppDataBuffer, pDataBufferLen);\r
2206 \r
2207     /* Get PS data buffer and its length from the descriptor */\r
2208     Cppi_getPSData (descType, pRxObjInfo->psLocation, pCppiDesc, ppPSInfo, pPSInfoLen);\r
2209 \r
2210     /* Check if any PS info is in the result SOP Buffer. If so,\r
2211      * move the data buffer pointer to point to the actual data and not the PS info.\r
2212      *\r
2213      * Due to a CDMA H/W Bug, the PS Location Info read from the descriptor\r
2214      * is no longer reliable. Hence, use the PS Info stored from the flow\r
2215      * configuration the Rx object uses.\r
2216      */ \r
2217     if ((descType == Cppi_DescType_HOST) && \r
2218         (pRxObjInfo->bPSInfoPresent) && \r
2219         (pRxObjInfo->psLocation == Cppi_PSLoc_PS_IN_SOP))\r
2220     {\r
2221         *ppDataBuffer +=  *pPSInfoLen;                      \r
2222     }\r
2223 \r
2224     return BCP_RETVAL_SUCCESS;\r
2225 }\r
2226 \r
2227 /**\r
2228 * ============================================================================\r
2229 *  @n@b Bcp_rxFreeResult\r
2230 *\r
2231 *  @b   brief\r
2232 *  @n   Given a Rx object handle and driver buffer handle obtained from \r
2233 *       @a Bcp_recv () API, this API frees the driver buffer handle and \r
2234 *       restores the associated Rx descriptor back to its Rx Free descriptor \r
2235 *       queue. This API must be called by the application once its done processing \r
2236 *       the result, otherwise the driver could run out of output buffers eventually \r
2237 *       if none restored in time. \r
2238 *\r
2239 *       On remote device, this API instead invokes the free receive buffer API\r
2240 *       of the BCP transport layer.\r
2241 *\r
2242 *  @param[in]\r
2243 *       hBcpRxInfo          Rx handle obtained using @a Bcp_rxOpen () API.\r
2244 *\r
2245 *  @param[in]\r
2246 *       hDrvBuffer          BCP driver output buffer handle obtained using \r
2247 *                           @a Bcp_recv () API.\r
2248 *\r
2249 *  @param[in]\r
2250 *       drvBufferLen        Size of the CPPI descriptor (BCP output buffer) \r
2251 *                           being freed.\r
2252 *\r
2253 *  @return     Bcp_RetVal\r
2254 *  @li         BCP_RETVAL_EBAD_HANDLE  -   Invalid input provided. Free failed.\r
2255 *  @li         BCP_RETVAL_SUCCESS      -   Free succeeded.\r
2256 *\r
2257 *  @pre\r
2258 *  @n   A valid driver buffer handle should have been obtained using \r
2259 *       @a Bcp_recv () before calling this API to free the descriptor.\r
2260 *\r
2261 *  @post\r
2262 *  @n   The result buffers passed are freed up and restored to the Rx object's free\r
2263 *       descriptors.\r
2264 * ============================================================================\r
2265 */\r
2266 Bcp_RetVal Bcp_rxFreeRecvBuffer \r
2267 (\r
2268     Bcp_RxHandle                hBcpRxInfo,\r
2269     Bcp_DrvBufferHandle         hDrvBuffer,\r
2270     uint32_t                    drvBufferLen\r
2271 )\r
2272 {\r
2273     Qmss_Queue                  rxReturnQInfo;\r
2274     Cppi_Desc*                  pCppiDesc;\r
2275     Bcp_DrvInfo*                pBcpDrvInfo;\r
2276     Bcp_RxInfo*                 pRxObjInfo;\r
2277     Qmss_QueueHnd               qHandle;\r
2278 \r
2279 #ifdef BCP_DRV_DEBUG\r
2280     /* Validate input */\r
2281     if (!hBcpRxInfo || !hDrvBuffer)\r
2282         return BCP_RETVAL_EBAD_HANDLE;\r
2283 #endif\r
2284 \r
2285     pRxObjInfo      =   (Bcp_RxInfo *) hBcpRxInfo;\r
2286     pCppiDesc       =   (Cppi_Desc*) hDrvBuffer;\r
2287     pBcpDrvInfo     =   (Bcp_DrvInfo*) pRxObjInfo->hBcp;\r
2288 \r
2289     if (pBcpDrvInfo->mode == Bcp_DrvMode_REMOTE)\r
2290     {\r
2291         pBcpDrvInfo->pFxnBcpTunnel_freeRecvBuffer (pRxObjInfo->hRxEndpointInfo, pCppiDesc, drvBufferLen); \r
2292     }\r
2293     else\r
2294     {\r
2295         rxReturnQInfo = Cppi_getReturnQueue (Cppi_getDescType (pCppiDesc), pCppiDesc);\r
2296         qHandle = Qmss_getQueueHandle(rxReturnQInfo);\r
2297 \r
2298         /* Push descriptor back to free queue */\r
2299             Qmss_queuePushDescSize (qHandle, pCppiDesc, drvBufferLen);\r
2300     }\r
2301 \r
2302     /* Return success. */\r
2303     return BCP_RETVAL_SUCCESS;\r
2304 }\r
2305 \r
2306 /**\r
2307 @}\r
2308 */\r