1/******************************************************************************
2
3 � 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
4 All rights reserved.
5
6 This is proprietary source code of Freescale Semiconductor Inc.,
7 and its use is subject to the NetComm Device Drivers EULA.
8 The copyright notice above does not evidence any actual or intended
9 publication of such source code.
10
11 ALTERNATIVELY, redistribution and use in source and binary forms, with
12 or without modification, are permitted provided that the following
13 conditions are met:
14     * Redistributions of source code must retain the above copyright
15       notice, this list of conditions and the following disclaimer.
16     * Redistributions in binary form must reproduce the above copyright
17       notice, this list of conditions and the following disclaimer in the
18       documentation and/or other materials provided with the distribution.
19     * Neither the name of Freescale Semiconductor nor the
20       names of its contributors may be used to endorse or promote products
21       derived from this software without specific prior written permission.
22
23 THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34
35 **************************************************************************/
36/******************************************************************************
37 @File          bm.c
38
39 @Description   BM
40*//***************************************************************************/
41#include "error_ext.h"
42#include "std_ext.h"
43#include "string_ext.h"
44#include "mem_ext.h"
45#include "core_ext.h"
46
47#include "bm.h"
48
49
50#define __ERR_MODULE__  MODULE_BM
51
52
53/****************************************/
54/*       static functions               */
55/****************************************/
56
57/* (De)Registration of depletion notification callbacks */
58static void depletion_link(t_BmPool *p_BmPool)
59{
60    t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
61
62    NCSW_PLOCK(p_Portal);
63    p_Portal->depletionPoolsTable[p_BmPool->bpid] = p_BmPool;
64    bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 1);
65    PUNLOCK(p_Portal);
66}
67
68static void depletion_unlink(t_BmPool *p_BmPool)
69{
70    t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
71
72    NCSW_PLOCK(p_Portal);
73    p_Portal->depletionPoolsTable[p_BmPool->bpid] = NULL;
74    bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 0);
75    PUNLOCK(p_Portal);
76}
77
78static t_Error BmPoolRelease(t_BmPool *p_BmPool,
79                             t_Handle h_BmPortal,
80                             struct bm_buffer *bufs,
81                             uint8_t num,
82                             uint32_t flags)
83{
84    ASSERT_COND(num && (num <= 8));
85    if (p_BmPool->flags & BMAN_POOL_FLAG_NO_RELEASE)
86        return ERROR_CODE(E_INVALID_VALUE);
87
88    /* Without stockpile, this API is a pass-through to the h/w operation */
89    if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
90        return BmPortalRelease(h_BmPortal, p_BmPool->bpid, bufs, num, flags);
91
92    /* This needs some explanation. Adding the given buffers may take the
93     * stockpile over the threshold, but in fact the stockpile may already
94     * *be* over the threshold if a previous release-to-hw attempt had
95     * failed. So we have 3 cases to cover;
96     *   1. we add to the stockpile and don't hit the threshold,
97     *   2. we add to the stockpile, hit the threshold and release-to-hw,
98     *   3. we have to release-to-hw before adding to the stockpile
99     *      (not enough room in the stockpile for case 2).
100     * Our constraints on thresholds guarantee that in case 3, there must be
101     * at least 8 bufs already in the stockpile, so all release-to-hw ops
102     * are for 8 bufs. Despite all this, the API must indicate whether the
103     * given buffers were taken off the caller's hands, irrespective of
104     * whether a release-to-hw was attempted. */
105    while (num)
106    {
107        /* Add buffers to stockpile if they fit */
108        if ((p_BmPool->spFill + num) <= p_BmPool->spMaxBufs)
109        {
110            memcpy(PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
111                   bufs,
112                   sizeof(struct bm_buffer) * num);
113            p_BmPool->spFill += num;
114            num = 0; /* --> will return success no matter what */
115        }
116        else
117        /* Do hw op if hitting the high-water threshold */
118        {
119            t_Error ret = BmPortalRelease(h_BmPortal,
120                                          p_BmPool->bpid,
121                                          (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - p_BmPool->spBufsCmd)),
122                                          p_BmPool->spBufsCmd,
123                                          flags);
124            if (ret)
125                return (num ? ret : E_OK);
126            p_BmPool->spFill -= p_BmPool->spBufsCmd;
127        }
128    }
129
130    return E_OK;
131}
132
133static int BmPoolAcquire(t_BmPool *p_BmPool,t_Handle h_BmPortal,
134            struct bm_buffer *bufs, uint8_t num, uint32_t flags)
135{
136    ASSERT_COND(IN_RANGE(1, num, 8));
137    if (p_BmPool->flags & BMAN_POOL_FLAG_ONLY_RELEASE)
138        return 0;
139
140    /* Without stockpile, this API is a pass-through to the h/w operation */
141    if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
142        return BmPortalAcquire(h_BmPortal, p_BmPool->bpid, bufs, num);
143    /* Only need a h/w op if we'll hit the low-water thresh */
144    if (!(flags & BMAN_ACQUIRE_FLAG_STOCKPILE) &&
145            ((p_BmPool->spFill - num) < p_BmPool->spMinBufs))
146    {
147            p_BmPool->spFill += BmPortalAcquire(h_BmPortal,
148                                               p_BmPool->bpid,
149                                               (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
150                                               p_BmPool->spBufsCmd);
151    }
152    else if (p_BmPool->spFill < num)
153        return 0;
154    if (!p_BmPool->spFill)
155        return 0;
156    memcpy(bufs,
157           PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - num)),
158           sizeof(struct bm_buffer) * num);
159    p_BmPool->spFill -= num;
160    return num;
161}
162
163static t_Error BmPoolFree(t_BmPool *p_BmPool, bool discardBuffers)
164{
165    t_Handle    h_BufContext;
166    void        *p_Data;
167
168    ASSERT_COND(p_BmPool);
169
170    if (!p_BmPool->shadowMode)
171    {
172        if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
173        {
174            depletion_unlink(p_BmPool);
175            BmUnSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid);
176        }
177        while (TRUE)
178        {
179            p_Data = BM_POOL_GetBuf(p_BmPool, p_BmPool->h_BmPortal);
180            if (!p_Data)
181                break;
182            h_BufContext = BM_POOL_GetBufferContext(p_BmPool, p_Data);
183            if (!discardBuffers)
184                p_BmPool->bufferPoolInfo.f_PutBuf(p_BmPool->bufferPoolInfo.h_BufferPool, p_Data, h_BufContext);
185        }
186        BmBpidPut(p_BmPool->h_Bm, p_BmPool->bpid);
187    }
188
189    if (p_BmPool->sp)
190        XX_Free(p_BmPool->sp);
191
192    XX_Free(p_BmPool);
193
194    return E_OK;
195}
196
197/****************************************/
198/*       API Init unit functions        */
199/****************************************/
200
201t_Handle BM_POOL_Config(t_BmPoolParam *p_BmPoolParam)
202{
203    t_BmPool        *p_BmPool;
204
205    SANITY_CHECK_RETURN_VALUE(p_BmPoolParam, E_INVALID_HANDLE, NULL);
206    SANITY_CHECK_RETURN_VALUE(p_BmPoolParam->h_Bm, E_INVALID_HANDLE, NULL);
207    SANITY_CHECK_RETURN_VALUE((p_BmPoolParam->shadowMode ||
208                               (p_BmPoolParam->bufferPoolInfo.h_BufferPool &&
209                               p_BmPoolParam->bufferPoolInfo.f_GetBuf &&
210                               p_BmPoolParam->bufferPoolInfo.f_PutBuf &&
211                               p_BmPoolParam->bufferPoolInfo.bufferSize)), E_INVALID_STATE, NULL);
212
213    p_BmPool = (t_BmPool*)XX_Malloc(sizeof(t_BmPool));
214    if (!p_BmPool)
215    {
216        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("BM Pool obj!!!"));
217        return NULL;
218    }
219    memset(p_BmPool, 0, sizeof(t_BmPool));
220
221    p_BmPool->p_BmPoolDriverParams = (t_BmPoolDriverParams *)XX_Malloc(sizeof(t_BmPoolDriverParams));
222    if (!p_BmPool->p_BmPoolDriverParams)
223    {
224        XX_Free(p_BmPool);
225        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool driver parameters"));
226        return NULL;
227    }
228    memset(p_BmPool->p_BmPoolDriverParams, 0, sizeof(t_BmPoolDriverParams));
229
230    p_BmPool->h_Bm          = p_BmPoolParam->h_Bm;
231    p_BmPool->h_BmPortal    = p_BmPoolParam->h_BmPortal;
232    p_BmPool->h_App         = p_BmPoolParam->h_App;
233    p_BmPool->numOfBuffers  = p_BmPoolParam->numOfBuffers;
234    p_BmPool->shadowMode    = p_BmPoolParam->shadowMode;
235
236    if (!p_BmPool->h_BmPortal)
237    {
238        p_BmPool->h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
239        SANITY_CHECK_RETURN_VALUE(p_BmPool->h_BmPortal, E_INVALID_HANDLE, NULL);
240    }
241
242    memcpy(&p_BmPool->bufferPoolInfo, &p_BmPoolParam->bufferPoolInfo, sizeof(t_BufferPoolInfo));
243    if (!p_BmPool->bufferPoolInfo.f_PhysToVirt)
244        p_BmPool->bufferPoolInfo.f_PhysToVirt = XX_PhysToVirt;
245    if (!p_BmPool->bufferPoolInfo.f_VirtToPhys)
246        p_BmPool->bufferPoolInfo.f_VirtToPhys = XX_VirtToPhys;
247
248    p_BmPool->p_BmPoolDriverParams->dynamicBpid     = DEFAULT_dynamicBpid;
249    p_BmPool->p_BmPoolDriverParams->useDepletion    = DEFAULT_useDepletion;
250    p_BmPool->p_BmPoolDriverParams->useStockpile    = DEFAULT_useStockpile;
251
252    if (p_BmPool->shadowMode)
253    {
254        p_BmPool->numOfBuffers = 0;
255        BM_POOL_ConfigBpid(p_BmPool, p_BmPoolParam->bpid);
256    }
257
258    return p_BmPool;
259}
260
261t_Error BM_POOL_Init(t_Handle h_BmPool)
262{
263    t_BmPool        *p_BmPool = (t_BmPool *)h_BmPool;
264    t_Error         err;
265
266    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
267    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
268
269    p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->dynamicBpid)?BMAN_POOL_FLAG_DYNAMIC_BPID:0;
270    p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->useStockpile)?BMAN_POOL_FLAG_STOCKPILE:0;
271    p_BmPool->flags |= ((!p_BmPool->shadowMode) &&
272                        (p_BmPool->p_BmPoolDriverParams->useDepletion))?BMAN_POOL_FLAG_DEPLETION:0;
273
274    if (p_BmPool->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
275    {
276        if((p_BmPool->bpid = (uint8_t)BmBpidGet(p_BmPool->h_Bm, FALSE, (uint32_t)0)) == (uint8_t)ILLEGAL_BASE)
277        {
278            BM_POOL_Free(p_BmPool);
279            RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't allocate new dynamic pool id"));
280        }
281    }
282    else
283    {
284        if (BmBpidGet(p_BmPool->h_Bm, TRUE, (uint32_t)p_BmPool->bpid) == (uint32_t)ILLEGAL_BASE)
285        {
286            BM_POOL_Free(p_BmPool);
287            RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't force pool id %d", p_BmPool->bpid));
288        }
289    }
290    if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
291    {
292        if(BmSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid, p_BmPool->p_BmPoolDriverParams->depletionThresholds))
293        {
294            BM_POOL_Free(p_BmPool);
295            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can't set thresh for pool bpid %d",p_BmPool->bpid));
296        }
297
298        depletion_link(p_BmPool);
299    }
300
301    if (p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE)
302    {
303        p_BmPool->sp = (struct bm_buffer *)XX_Malloc(sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
304        if (!p_BmPool->sp)
305        {
306            BM_POOL_Free(p_BmPool);
307            RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool Stockpile"));
308        }
309        memset(p_BmPool->sp, 0, sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
310    }
311
312    XX_Free(p_BmPool->p_BmPoolDriverParams);
313    p_BmPool->p_BmPoolDriverParams = NULL;
314
315    /*******************/
316    /* Create buffers  */
317    /*******************/
318    if ((err = BM_POOL_FillBufs (p_BmPool, p_BmPool->h_BmPortal, p_BmPool->numOfBuffers)) != E_OK)
319    {
320        BM_POOL_Free(p_BmPool);
321        RETURN_ERROR(MAJOR, err, NO_MSG);
322    }
323
324    return E_OK;
325}
326
327t_Error BM_POOL_Free(t_Handle h_BmPool)
328{
329    SANITY_CHECK_RETURN_ERROR(h_BmPool, E_INVALID_HANDLE);
330
331    return BmPoolFree(h_BmPool, FALSE);
332}
333
334t_Error  BM_POOL_ConfigBpid(t_Handle h_BmPool, uint8_t bpid)
335{
336    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
337
338    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
339    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
340    SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE);
341
342    p_BmPool->p_BmPoolDriverParams->dynamicBpid = FALSE;
343    p_BmPool->bpid = bpid;
344
345    return E_OK;
346}
347
348
349t_Error  BM_POOL_ConfigDepletion(t_Handle h_BmPool, t_BmDepletionCallback *f_Depletion, uint32_t *p_Thresholds)
350{
351    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
352
353    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
354    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
355    SANITY_CHECK_RETURN_ERROR(f_Depletion, E_INVALID_HANDLE);
356
357    p_BmPool->p_BmPoolDriverParams->useDepletion = TRUE;
358    p_BmPool->f_Depletion = f_Depletion;
359    memcpy(&p_BmPool->p_BmPoolDriverParams->depletionThresholds,
360           p_Thresholds,
361           sizeof(p_BmPool->p_BmPoolDriverParams->depletionThresholds));
362
363    return E_OK;
364}
365
366t_Error  BM_POOL_ConfigStockpile(t_Handle h_BmPool, uint16_t maxBuffers, uint16_t minBuffers)
367{
368    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
369
370    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
371    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
372    SANITY_CHECK_RETURN_ERROR(maxBuffers, E_INVALID_STATE);
373    SANITY_CHECK_RETURN_ERROR(maxBuffers >= minBuffers, E_INVALID_STATE);
374    SANITY_CHECK_RETURN_ERROR((p_BmPool->shadowMode ||
375                              ((maxBuffers * 2) <= p_BmPool->numOfBuffers)),
376                              E_INVALID_STATE);
377
378    p_BmPool->p_BmPoolDriverParams->useStockpile = TRUE;
379    p_BmPool->spMaxBufs     = maxBuffers;
380    p_BmPool->spMinBufs     = minBuffers;
381    p_BmPool->spBufsCmd     = DEFAULT_numOfBufsPerCmd;
382
383    SANITY_CHECK_RETURN_ERROR((p_BmPool->spMaxBufs >=
384                               (p_BmPool->spMinBufs + p_BmPool->spBufsCmd)),
385                              E_INVALID_STATE);
386
387    return E_OK;
388}
389
390t_Error  BM_POOL_ConfigBuffContextMode(t_Handle h_BmPool, bool en)
391{
392    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
393
394    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
395    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
396
397    p_BmPool->noBuffCtxt = !en;
398
399    return E_OK;
400}
401
402void * BM_POOL_GetBuf(t_Handle h_BmPool, t_Handle h_BmPortal)
403{
404    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
405    struct bm_buffer    bufs[1];
406    uint8_t             retBufsNum;
407    uint64_t            physAddr;
408    uint32_t            flags = 0;
409
410    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
411    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
412    SANITY_CHECK_RETURN_VALUE(p_BmPool->bufferPoolInfo.f_PhysToVirt, E_INVALID_STATE, NULL);
413
414    if (!h_BmPortal)
415    {
416        if (p_BmPool->h_BmPortal)
417            h_BmPortal = p_BmPool->h_BmPortal;
418        else
419        {
420            SANITY_CHECK_RETURN_VALUE(p_BmPool->h_Bm, E_INVALID_HANDLE, NULL);
421            h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
422            SANITY_CHECK_RETURN_VALUE(h_BmPortal, E_INVALID_HANDLE, NULL);
423        }
424    }
425
426    retBufsNum = (uint8_t)BmPoolAcquire(p_BmPool, h_BmPortal, bufs, 1, flags);
427    if (!retBufsNum)
428    {
429        REPORT_ERROR(TRACE, E_NOT_AVAILABLE, ("buffer"));
430        return NULL;
431    }
432    physAddr  = (uint64_t)bufs[0].lo;
433    physAddr |= (uint64_t)(((uint64_t)bufs[0].hi << 32) & 0x000000ff00000000LL);
434    DBG(TRACE,("Get Buffer : poolId %d, address 0x%016llx",
435               p_BmPool->bpid,
436               p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr)));
437
438    return p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr);
439}
440
441t_Error BM_POOL_PutBuf(t_Handle h_BmPool, t_Handle h_BmPortal, void *p_Buff)
442{
443    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
444    uint64_t            physAddress;
445    struct bm_buffer    bufs[1];
446
447    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
448    SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
449    SANITY_CHECK_RETURN_ERROR(p_Buff, E_NULL_POINTER);
450
451    physAddress = (uint64_t)(XX_VirtToPhys(p_Buff));
452
453    bufs[0].bpid = p_BmPool->bpid;
454    bufs[0].hi = (uint8_t)((physAddress & 0x000000ff00000000LL) >> 32);
455    bufs[0].lo = (uint32_t)(physAddress & 0xffffffff);
456
457    DBG(TRACE,("Put Buffer : poolId %d, address 0x%016llx, phys 0x%016llx",
458               p_BmPool->bpid, (uint64_t)PTR_TO_UINT(p_Buff), physAddress));
459
460    if (!h_BmPortal)
461    {
462        if (p_BmPool->h_BmPortal)
463            h_BmPortal = p_BmPool->h_BmPortal;
464        else
465        {
466            SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
467            h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
468            SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
469        }
470    }
471
472    return BmPoolRelease(p_BmPool, h_BmPortal, bufs, 1, BMAN_RELEASE_FLAG_WAIT);
473}
474
475t_Error BM_POOL_FillBufs(t_Handle h_BmPool, t_Handle h_BmPortal, uint32_t numBufs)
476{
477    t_BmPool    *p_BmPool   = (t_BmPool *)h_BmPool;
478
479    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
480    SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
481
482    if (!h_BmPortal)
483    {
484        if (p_BmPool->h_BmPortal)
485            h_BmPortal = p_BmPool->h_BmPortal;
486        else
487        {
488            SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
489            h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
490            SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
491        }
492    }
493
494    while (numBufs--)
495    {
496        uint8_t             *p_Data;
497        t_Error             res;
498        t_Handle            h_BufContext;
499
500        p_Data = p_BmPool->bufferPoolInfo.f_GetBuf(p_BmPool->bufferPoolInfo.h_BufferPool, &h_BufContext);
501        if(!p_Data)
502            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("run-out of buffers for bpid %d",p_BmPool->bpid));
503
504        if (!p_BmPool->noBuffCtxt)
505            *(t_Handle *)(p_Data - sizeof(t_Handle)) = h_BufContext;
506
507        if ((res = BM_POOL_PutBuf(p_BmPool, h_BmPortal, p_Data)) != E_OK)
508            RETURN_ERROR(CRITICAL, res, ("Seeding reserved buffer pool failed"));
509    }
510
511    return E_OK;
512}
513
514uint8_t BM_POOL_GetId(t_Handle h_BmPool)
515{
516    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
517
518    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
519    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
520
521    return p_BmPool->bpid;
522}
523
524uint16_t BM_POOL_GetBufferSize(t_Handle h_BmPool)
525{
526    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
527
528    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
529    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
530
531    return p_BmPool->bufferPoolInfo.bufferSize;
532}
533
534t_Handle BM_POOL_GetBufferContext(t_Handle h_BmPool, void *p_Buff)
535{
536    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
537
538    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
539    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
540    SANITY_CHECK_RETURN_VALUE(p_Buff, E_NULL_POINTER, NULL);
541
542    if (p_BmPool->noBuffCtxt)
543        return NULL;
544
545    return *(t_Handle *)PTR_MOVE(p_Buff, -(sizeof(t_Handle)));
546}
547
548void * BM_POOL_PhysToVirt(t_Handle h_BmPool, physAddress_t addr)
549{
550    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
551
552    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
553    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
554
555    return p_BmPool->bufferPoolInfo.f_PhysToVirt(addr);
556}
557
558physAddress_t BM_POOL_VirtToPhys(t_Handle h_BmPool, void *p_Buff)
559{
560    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
561
562    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, (physAddress_t)0);
563    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, (physAddress_t)0);
564
565    return p_BmPool->bufferPoolInfo.f_VirtToPhys(p_Buff);
566}
567
568uint32_t BM_POOL_GetCounter(t_Handle h_BmPool, e_BmPoolCounters counter)
569{
570    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
571
572    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
573    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
574
575    switch(counter)
576    {
577        case(e_BM_POOL_COUNTERS_CONTENT):
578            return BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_CONTENT, p_BmPool->bpid);
579        case(e_BM_POOL_COUNTERS_SW_DEPLETION):
580            return (p_BmPool->swDepletionCount +=
581                BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_SW_DEPLETION, p_BmPool->bpid));
582        case(e_BM_POOL_COUNTERS_HW_DEPLETION):
583            return (p_BmPool->hwDepletionCount +=
584                BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_HW_DEPLETION, p_BmPool->bpid));
585        default:
586            break;
587    }
588
589    /* should never get here */
590    ASSERT_COND(FALSE);
591
592    return 0;
593}
594