1296177Sjhibbits/******************************************************************************
2296177Sjhibbits
3296177Sjhibbits � 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
4296177Sjhibbits All rights reserved.
5296177Sjhibbits
6296177Sjhibbits This is proprietary source code of Freescale Semiconductor Inc.,
7296177Sjhibbits and its use is subject to the NetComm Device Drivers EULA.
8296177Sjhibbits The copyright notice above does not evidence any actual or intended
9296177Sjhibbits publication of such source code.
10296177Sjhibbits
11296177Sjhibbits ALTERNATIVELY, redistribution and use in source and binary forms, with
12296177Sjhibbits or without modification, are permitted provided that the following
13296177Sjhibbits conditions are met:
14296177Sjhibbits     * Redistributions of source code must retain the above copyright
15296177Sjhibbits       notice, this list of conditions and the following disclaimer.
16296177Sjhibbits     * Redistributions in binary form must reproduce the above copyright
17296177Sjhibbits       notice, this list of conditions and the following disclaimer in the
18296177Sjhibbits       documentation and/or other materials provided with the distribution.
19296177Sjhibbits     * Neither the name of Freescale Semiconductor nor the
20296177Sjhibbits       names of its contributors may be used to endorse or promote products
21296177Sjhibbits       derived from this software without specific prior written permission.
22296177Sjhibbits
23296177Sjhibbits THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24296177Sjhibbits EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25296177Sjhibbits WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26296177Sjhibbits DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27296177Sjhibbits DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28296177Sjhibbits (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29296177Sjhibbits LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30296177Sjhibbits ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31296177Sjhibbits (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32296177Sjhibbits SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33296177Sjhibbits *
34296177Sjhibbits
35296177Sjhibbits **************************************************************************/
36296177Sjhibbits/******************************************************************************
37296177Sjhibbits @File          bm.c
38296177Sjhibbits
39296177Sjhibbits @Description   BM
40296177Sjhibbits*//***************************************************************************/
41296177Sjhibbits#include "error_ext.h"
42296177Sjhibbits#include "std_ext.h"
43296177Sjhibbits#include "string_ext.h"
44296177Sjhibbits#include "mem_ext.h"
45296177Sjhibbits#include "core_ext.h"
46296177Sjhibbits
47296177Sjhibbits#include "bm.h"
48296177Sjhibbits
49296177Sjhibbits
50296177Sjhibbits#define __ERR_MODULE__  MODULE_BM
51296177Sjhibbits
52296177Sjhibbits
53296177Sjhibbits/****************************************/
54296177Sjhibbits/*       static functions               */
55296177Sjhibbits/****************************************/
56296177Sjhibbits
57296177Sjhibbits/* (De)Registration of depletion notification callbacks */
58296177Sjhibbitsstatic void depletion_link(t_BmPool *p_BmPool)
59296177Sjhibbits{
60296177Sjhibbits    t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
61296177Sjhibbits
62296177Sjhibbits    NCSW_PLOCK(p_Portal);
63296177Sjhibbits    p_Portal->depletionPoolsTable[p_BmPool->bpid] = p_BmPool;
64296177Sjhibbits    bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 1);
65296177Sjhibbits    PUNLOCK(p_Portal);
66296177Sjhibbits}
67296177Sjhibbits
68296177Sjhibbitsstatic void depletion_unlink(t_BmPool *p_BmPool)
69296177Sjhibbits{
70296177Sjhibbits    t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
71296177Sjhibbits
72296177Sjhibbits    NCSW_PLOCK(p_Portal);
73296177Sjhibbits    p_Portal->depletionPoolsTable[p_BmPool->bpid] = NULL;
74296177Sjhibbits    bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 0);
75296177Sjhibbits    PUNLOCK(p_Portal);
76296177Sjhibbits}
77296177Sjhibbits
78296177Sjhibbitsstatic t_Error BmPoolRelease(t_BmPool *p_BmPool,
79296177Sjhibbits                             t_Handle h_BmPortal,
80296177Sjhibbits                             struct bm_buffer *bufs,
81296177Sjhibbits                             uint8_t num,
82296177Sjhibbits                             uint32_t flags)
83296177Sjhibbits{
84296177Sjhibbits    ASSERT_COND(num && (num <= 8));
85296177Sjhibbits    if (p_BmPool->flags & BMAN_POOL_FLAG_NO_RELEASE)
86296177Sjhibbits        return ERROR_CODE(E_INVALID_VALUE);
87296177Sjhibbits
88296177Sjhibbits    /* Without stockpile, this API is a pass-through to the h/w operation */
89296177Sjhibbits    if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
90296177Sjhibbits        return BmPortalRelease(h_BmPortal, p_BmPool->bpid, bufs, num, flags);
91296177Sjhibbits
92296177Sjhibbits    /* This needs some explanation. Adding the given buffers may take the
93296177Sjhibbits     * stockpile over the threshold, but in fact the stockpile may already
94296177Sjhibbits     * *be* over the threshold if a previous release-to-hw attempt had
95296177Sjhibbits     * failed. So we have 3 cases to cover;
96296177Sjhibbits     *   1. we add to the stockpile and don't hit the threshold,
97296177Sjhibbits     *   2. we add to the stockpile, hit the threshold and release-to-hw,
98296177Sjhibbits     *   3. we have to release-to-hw before adding to the stockpile
99296177Sjhibbits     *      (not enough room in the stockpile for case 2).
100296177Sjhibbits     * Our constraints on thresholds guarantee that in case 3, there must be
101296177Sjhibbits     * at least 8 bufs already in the stockpile, so all release-to-hw ops
102296177Sjhibbits     * are for 8 bufs. Despite all this, the API must indicate whether the
103296177Sjhibbits     * given buffers were taken off the caller's hands, irrespective of
104296177Sjhibbits     * whether a release-to-hw was attempted. */
105296177Sjhibbits    while (num)
106296177Sjhibbits    {
107296177Sjhibbits        /* Add buffers to stockpile if they fit */
108296177Sjhibbits        if ((p_BmPool->spFill + num) <= p_BmPool->spMaxBufs)
109296177Sjhibbits        {
110296177Sjhibbits            memcpy(PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
111296177Sjhibbits                   bufs,
112296177Sjhibbits                   sizeof(struct bm_buffer) * num);
113296177Sjhibbits            p_BmPool->spFill += num;
114296177Sjhibbits            num = 0; /* --> will return success no matter what */
115296177Sjhibbits        }
116296177Sjhibbits        else
117296177Sjhibbits        /* Do hw op if hitting the high-water threshold */
118296177Sjhibbits        {
119296177Sjhibbits            t_Error ret = BmPortalRelease(h_BmPortal,
120296177Sjhibbits                                          p_BmPool->bpid,
121296177Sjhibbits                                          (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - p_BmPool->spBufsCmd)),
122296177Sjhibbits                                          p_BmPool->spBufsCmd,
123296177Sjhibbits                                          flags);
124296177Sjhibbits            if (ret)
125296177Sjhibbits                return (num ? ret : E_OK);
126296177Sjhibbits            p_BmPool->spFill -= p_BmPool->spBufsCmd;
127296177Sjhibbits        }
128296177Sjhibbits    }
129296177Sjhibbits
130296177Sjhibbits    return E_OK;
131296177Sjhibbits}
132296177Sjhibbits
133296177Sjhibbitsstatic int BmPoolAcquire(t_BmPool *p_BmPool,t_Handle h_BmPortal,
134296177Sjhibbits            struct bm_buffer *bufs, uint8_t num, uint32_t flags)
135296177Sjhibbits{
136296177Sjhibbits    ASSERT_COND(IN_RANGE(1, num, 8));
137296177Sjhibbits    if (p_BmPool->flags & BMAN_POOL_FLAG_ONLY_RELEASE)
138296177Sjhibbits        return 0;
139296177Sjhibbits
140296177Sjhibbits    /* Without stockpile, this API is a pass-through to the h/w operation */
141296177Sjhibbits    if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
142296177Sjhibbits        return BmPortalAcquire(h_BmPortal, p_BmPool->bpid, bufs, num);
143296177Sjhibbits    /* Only need a h/w op if we'll hit the low-water thresh */
144296177Sjhibbits    if (!(flags & BMAN_ACQUIRE_FLAG_STOCKPILE) &&
145296177Sjhibbits            ((p_BmPool->spFill - num) < p_BmPool->spMinBufs))
146296177Sjhibbits    {
147296177Sjhibbits            p_BmPool->spFill += BmPortalAcquire(h_BmPortal,
148296177Sjhibbits                                               p_BmPool->bpid,
149296177Sjhibbits                                               (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
150296177Sjhibbits                                               p_BmPool->spBufsCmd);
151296177Sjhibbits    }
152296177Sjhibbits    else if (p_BmPool->spFill < num)
153296177Sjhibbits        return 0;
154296177Sjhibbits    if (!p_BmPool->spFill)
155296177Sjhibbits        return 0;
156296177Sjhibbits    memcpy(bufs,
157296177Sjhibbits           PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - num)),
158296177Sjhibbits           sizeof(struct bm_buffer) * num);
159296177Sjhibbits    p_BmPool->spFill -= num;
160296177Sjhibbits    return num;
161296177Sjhibbits}
162296177Sjhibbits
163296177Sjhibbitsstatic t_Error BmPoolFree(t_BmPool *p_BmPool, bool discardBuffers)
164296177Sjhibbits{
165296177Sjhibbits    t_Handle    h_BufContext;
166296177Sjhibbits    void        *p_Data;
167296177Sjhibbits
168296177Sjhibbits    ASSERT_COND(p_BmPool);
169296177Sjhibbits
170296177Sjhibbits    if (!p_BmPool->shadowMode)
171296177Sjhibbits    {
172296177Sjhibbits        if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
173296177Sjhibbits        {
174296177Sjhibbits            depletion_unlink(p_BmPool);
175296177Sjhibbits            BmUnSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid);
176296177Sjhibbits        }
177296177Sjhibbits        while (TRUE)
178296177Sjhibbits        {
179296177Sjhibbits            p_Data = BM_POOL_GetBuf(p_BmPool, p_BmPool->h_BmPortal);
180296177Sjhibbits            if (!p_Data)
181296177Sjhibbits                break;
182296177Sjhibbits            h_BufContext = BM_POOL_GetBufferContext(p_BmPool, p_Data);
183296177Sjhibbits            if (!discardBuffers)
184296177Sjhibbits                p_BmPool->bufferPoolInfo.f_PutBuf(p_BmPool->bufferPoolInfo.h_BufferPool, p_Data, h_BufContext);
185296177Sjhibbits        }
186296177Sjhibbits        BmBpidPut(p_BmPool->h_Bm, p_BmPool->bpid);
187296177Sjhibbits    }
188296177Sjhibbits
189296177Sjhibbits    if (p_BmPool->sp)
190296177Sjhibbits        XX_Free(p_BmPool->sp);
191296177Sjhibbits
192296177Sjhibbits    XX_Free(p_BmPool);
193296177Sjhibbits
194296177Sjhibbits    return E_OK;
195296177Sjhibbits}
196296177Sjhibbits
197296177Sjhibbits/****************************************/
198296177Sjhibbits/*       API Init unit functions        */
199296177Sjhibbits/****************************************/
200296177Sjhibbits
201296177Sjhibbitst_Handle BM_POOL_Config(t_BmPoolParam *p_BmPoolParam)
202296177Sjhibbits{
203296177Sjhibbits    t_BmPool        *p_BmPool;
204296177Sjhibbits
205296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPoolParam, E_INVALID_HANDLE, NULL);
206296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPoolParam->h_Bm, E_INVALID_HANDLE, NULL);
207296177Sjhibbits    SANITY_CHECK_RETURN_VALUE((p_BmPoolParam->shadowMode ||
208296177Sjhibbits                               (p_BmPoolParam->bufferPoolInfo.h_BufferPool &&
209296177Sjhibbits                               p_BmPoolParam->bufferPoolInfo.f_GetBuf &&
210296177Sjhibbits                               p_BmPoolParam->bufferPoolInfo.f_PutBuf &&
211296177Sjhibbits                               p_BmPoolParam->bufferPoolInfo.bufferSize)), E_INVALID_STATE, NULL);
212296177Sjhibbits
213296177Sjhibbits    p_BmPool = (t_BmPool*)XX_Malloc(sizeof(t_BmPool));
214296177Sjhibbits    if (!p_BmPool)
215296177Sjhibbits    {
216296177Sjhibbits        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("BM Pool obj!!!"));
217296177Sjhibbits        return NULL;
218296177Sjhibbits    }
219296177Sjhibbits    memset(p_BmPool, 0, sizeof(t_BmPool));
220296177Sjhibbits
221296177Sjhibbits    p_BmPool->p_BmPoolDriverParams = (t_BmPoolDriverParams *)XX_Malloc(sizeof(t_BmPoolDriverParams));
222296177Sjhibbits    if (!p_BmPool->p_BmPoolDriverParams)
223296177Sjhibbits    {
224296177Sjhibbits        XX_Free(p_BmPool);
225296177Sjhibbits        REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool driver parameters"));
226296177Sjhibbits        return NULL;
227296177Sjhibbits    }
228296177Sjhibbits    memset(p_BmPool->p_BmPoolDriverParams, 0, sizeof(t_BmPoolDriverParams));
229296177Sjhibbits
230296177Sjhibbits    p_BmPool->h_Bm          = p_BmPoolParam->h_Bm;
231296177Sjhibbits    p_BmPool->h_BmPortal    = p_BmPoolParam->h_BmPortal;
232296177Sjhibbits    p_BmPool->h_App         = p_BmPoolParam->h_App;
233296177Sjhibbits    p_BmPool->numOfBuffers  = p_BmPoolParam->numOfBuffers;
234296177Sjhibbits    p_BmPool->shadowMode    = p_BmPoolParam->shadowMode;
235296177Sjhibbits
236296177Sjhibbits    if (!p_BmPool->h_BmPortal)
237296177Sjhibbits    {
238296177Sjhibbits        p_BmPool->h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
239296177Sjhibbits        SANITY_CHECK_RETURN_VALUE(p_BmPool->h_BmPortal, E_INVALID_HANDLE, NULL);
240296177Sjhibbits    }
241296177Sjhibbits
242296177Sjhibbits    memcpy(&p_BmPool->bufferPoolInfo, &p_BmPoolParam->bufferPoolInfo, sizeof(t_BufferPoolInfo));
243296177Sjhibbits    if (!p_BmPool->bufferPoolInfo.f_PhysToVirt)
244296177Sjhibbits        p_BmPool->bufferPoolInfo.f_PhysToVirt = XX_PhysToVirt;
245296177Sjhibbits    if (!p_BmPool->bufferPoolInfo.f_VirtToPhys)
246296177Sjhibbits        p_BmPool->bufferPoolInfo.f_VirtToPhys = XX_VirtToPhys;
247296177Sjhibbits
248296177Sjhibbits    p_BmPool->p_BmPoolDriverParams->dynamicBpid     = DEFAULT_dynamicBpid;
249296177Sjhibbits    p_BmPool->p_BmPoolDriverParams->useDepletion    = DEFAULT_useDepletion;
250296177Sjhibbits    p_BmPool->p_BmPoolDriverParams->useStockpile    = DEFAULT_useStockpile;
251296177Sjhibbits
252296177Sjhibbits    if (p_BmPool->shadowMode)
253296177Sjhibbits    {
254296177Sjhibbits        p_BmPool->numOfBuffers = 0;
255296177Sjhibbits        BM_POOL_ConfigBpid(p_BmPool, p_BmPoolParam->bpid);
256296177Sjhibbits    }
257296177Sjhibbits
258296177Sjhibbits    return p_BmPool;
259296177Sjhibbits}
260296177Sjhibbits
261296177Sjhibbitst_Error BM_POOL_Init(t_Handle h_BmPool)
262296177Sjhibbits{
263296177Sjhibbits    t_BmPool        *p_BmPool = (t_BmPool *)h_BmPool;
264296177Sjhibbits    t_Error         err;
265296177Sjhibbits
266296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
267296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
268296177Sjhibbits
269296177Sjhibbits    p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->dynamicBpid)?BMAN_POOL_FLAG_DYNAMIC_BPID:0;
270296177Sjhibbits    p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->useStockpile)?BMAN_POOL_FLAG_STOCKPILE:0;
271296177Sjhibbits    p_BmPool->flags |= ((!p_BmPool->shadowMode) &&
272296177Sjhibbits                        (p_BmPool->p_BmPoolDriverParams->useDepletion))?BMAN_POOL_FLAG_DEPLETION:0;
273296177Sjhibbits
274296177Sjhibbits    if (p_BmPool->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
275296177Sjhibbits    {
276296177Sjhibbits        if((p_BmPool->bpid = (uint8_t)BmBpidGet(p_BmPool->h_Bm, FALSE, (uint32_t)0)) == (uint8_t)ILLEGAL_BASE)
277296177Sjhibbits        {
278296177Sjhibbits            BM_POOL_Free(p_BmPool);
279296177Sjhibbits            RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't allocate new dynamic pool id"));
280296177Sjhibbits        }
281296177Sjhibbits    }
282296177Sjhibbits    else
283296177Sjhibbits    {
284296177Sjhibbits        if (BmBpidGet(p_BmPool->h_Bm, TRUE, (uint32_t)p_BmPool->bpid) == (uint32_t)ILLEGAL_BASE)
285296177Sjhibbits        {
286296177Sjhibbits            BM_POOL_Free(p_BmPool);
287296177Sjhibbits            RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't force pool id %d", p_BmPool->bpid));
288296177Sjhibbits        }
289296177Sjhibbits    }
290296177Sjhibbits    if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
291296177Sjhibbits    {
292296177Sjhibbits        if(BmSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid, p_BmPool->p_BmPoolDriverParams->depletionThresholds))
293296177Sjhibbits        {
294296177Sjhibbits            BM_POOL_Free(p_BmPool);
295296177Sjhibbits            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can't set thresh for pool bpid %d",p_BmPool->bpid));
296296177Sjhibbits        }
297296177Sjhibbits
298296177Sjhibbits        depletion_link(p_BmPool);
299296177Sjhibbits    }
300296177Sjhibbits
301296177Sjhibbits    if (p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE)
302296177Sjhibbits    {
303296177Sjhibbits        p_BmPool->sp = (struct bm_buffer *)XX_Malloc(sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
304296177Sjhibbits        if (!p_BmPool->sp)
305296177Sjhibbits        {
306296177Sjhibbits            BM_POOL_Free(p_BmPool);
307296177Sjhibbits            RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool Stockpile"));
308296177Sjhibbits        }
309296177Sjhibbits        memset(p_BmPool->sp, 0, sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
310296177Sjhibbits    }
311296177Sjhibbits
312296177Sjhibbits    XX_Free(p_BmPool->p_BmPoolDriverParams);
313296177Sjhibbits    p_BmPool->p_BmPoolDriverParams = NULL;
314296177Sjhibbits
315296177Sjhibbits    /*******************/
316296177Sjhibbits    /* Create buffers  */
317296177Sjhibbits    /*******************/
318296177Sjhibbits    if ((err = BM_POOL_FillBufs (p_BmPool, p_BmPool->h_BmPortal, p_BmPool->numOfBuffers)) != E_OK)
319296177Sjhibbits    {
320296177Sjhibbits        BM_POOL_Free(p_BmPool);
321296177Sjhibbits        RETURN_ERROR(MAJOR, err, NO_MSG);
322296177Sjhibbits    }
323296177Sjhibbits
324296177Sjhibbits    return E_OK;
325296177Sjhibbits}
326296177Sjhibbits
327296177Sjhibbitst_Error BM_POOL_Free(t_Handle h_BmPool)
328296177Sjhibbits{
329296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(h_BmPool, E_INVALID_HANDLE);
330296177Sjhibbits
331296177Sjhibbits    return BmPoolFree(h_BmPool, FALSE);
332296177Sjhibbits}
333296177Sjhibbits
334296177Sjhibbitst_Error  BM_POOL_ConfigBpid(t_Handle h_BmPool, uint8_t bpid)
335296177Sjhibbits{
336296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
337296177Sjhibbits
338296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
339296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
340296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE);
341296177Sjhibbits
342296177Sjhibbits    p_BmPool->p_BmPoolDriverParams->dynamicBpid = FALSE;
343296177Sjhibbits    p_BmPool->bpid = bpid;
344296177Sjhibbits
345296177Sjhibbits    return E_OK;
346296177Sjhibbits}
347296177Sjhibbits
348296177Sjhibbits
349296177Sjhibbitst_Error  BM_POOL_ConfigDepletion(t_Handle h_BmPool, t_BmDepletionCallback *f_Depletion, uint32_t *p_Thresholds)
350296177Sjhibbits{
351296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
352296177Sjhibbits
353296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
354296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
355296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(f_Depletion, E_INVALID_HANDLE);
356296177Sjhibbits
357296177Sjhibbits    p_BmPool->p_BmPoolDriverParams->useDepletion = TRUE;
358296177Sjhibbits    p_BmPool->f_Depletion = f_Depletion;
359296177Sjhibbits    memcpy(&p_BmPool->p_BmPoolDriverParams->depletionThresholds,
360296177Sjhibbits           p_Thresholds,
361296177Sjhibbits           sizeof(p_BmPool->p_BmPoolDriverParams->depletionThresholds));
362296177Sjhibbits
363296177Sjhibbits    return E_OK;
364296177Sjhibbits}
365296177Sjhibbits
366296177Sjhibbitst_Error  BM_POOL_ConfigStockpile(t_Handle h_BmPool, uint16_t maxBuffers, uint16_t minBuffers)
367296177Sjhibbits{
368296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
369296177Sjhibbits
370296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
371296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
372296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(maxBuffers, E_INVALID_STATE);
373296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(maxBuffers >= minBuffers, E_INVALID_STATE);
374296177Sjhibbits    SANITY_CHECK_RETURN_ERROR((p_BmPool->shadowMode ||
375296177Sjhibbits                              ((maxBuffers * 2) <= p_BmPool->numOfBuffers)),
376296177Sjhibbits                              E_INVALID_STATE);
377296177Sjhibbits
378296177Sjhibbits    p_BmPool->p_BmPoolDriverParams->useStockpile = TRUE;
379296177Sjhibbits    p_BmPool->spMaxBufs     = maxBuffers;
380296177Sjhibbits    p_BmPool->spMinBufs     = minBuffers;
381296177Sjhibbits    p_BmPool->spBufsCmd     = DEFAULT_numOfBufsPerCmd;
382296177Sjhibbits
383296177Sjhibbits    SANITY_CHECK_RETURN_ERROR((p_BmPool->spMaxBufs >=
384296177Sjhibbits                               (p_BmPool->spMinBufs + p_BmPool->spBufsCmd)),
385296177Sjhibbits                              E_INVALID_STATE);
386296177Sjhibbits
387296177Sjhibbits    return E_OK;
388296177Sjhibbits}
389296177Sjhibbits
390296177Sjhibbitst_Error  BM_POOL_ConfigBuffContextMode(t_Handle h_BmPool, bool en)
391296177Sjhibbits{
392296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
393296177Sjhibbits
394296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
395296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
396296177Sjhibbits
397296177Sjhibbits    p_BmPool->noBuffCtxt = !en;
398296177Sjhibbits
399296177Sjhibbits    return E_OK;
400296177Sjhibbits}
401296177Sjhibbits
402296177Sjhibbitsvoid * BM_POOL_GetBuf(t_Handle h_BmPool, t_Handle h_BmPortal)
403296177Sjhibbits{
404296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
405296177Sjhibbits    struct bm_buffer    bufs[1];
406296177Sjhibbits    uint8_t             retBufsNum;
407296177Sjhibbits    uint64_t            physAddr;
408296177Sjhibbits    uint32_t            flags = 0;
409296177Sjhibbits
410296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
411296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
412296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool->bufferPoolInfo.f_PhysToVirt, E_INVALID_STATE, NULL);
413296177Sjhibbits
414296177Sjhibbits    if (!h_BmPortal)
415296177Sjhibbits    {
416296177Sjhibbits        if (p_BmPool->h_BmPortal)
417296177Sjhibbits            h_BmPortal = p_BmPool->h_BmPortal;
418296177Sjhibbits        else
419296177Sjhibbits        {
420296177Sjhibbits            SANITY_CHECK_RETURN_VALUE(p_BmPool->h_Bm, E_INVALID_HANDLE, NULL);
421296177Sjhibbits            h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
422296177Sjhibbits            SANITY_CHECK_RETURN_VALUE(h_BmPortal, E_INVALID_HANDLE, NULL);
423296177Sjhibbits        }
424296177Sjhibbits    }
425296177Sjhibbits
426296177Sjhibbits    retBufsNum = (uint8_t)BmPoolAcquire(p_BmPool, h_BmPortal, bufs, 1, flags);
427296177Sjhibbits    if (!retBufsNum)
428296177Sjhibbits    {
429296177Sjhibbits        REPORT_ERROR(TRACE, E_NOT_AVAILABLE, ("buffer"));
430296177Sjhibbits        return NULL;
431296177Sjhibbits    }
432296177Sjhibbits    physAddr  = (uint64_t)bufs[0].lo;
433296177Sjhibbits    physAddr |= (uint64_t)(((uint64_t)bufs[0].hi << 32) & 0x000000ff00000000LL);
434296177Sjhibbits    DBG(TRACE,("Get Buffer : poolId %d, address 0x%016llx",
435296177Sjhibbits               p_BmPool->bpid,
436296177Sjhibbits               p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr)));
437296177Sjhibbits
438296177Sjhibbits    return p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr);
439296177Sjhibbits}
440296177Sjhibbits
441296177Sjhibbitst_Error BM_POOL_PutBuf(t_Handle h_BmPool, t_Handle h_BmPortal, void *p_Buff)
442296177Sjhibbits{
443296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
444296177Sjhibbits    uint64_t            physAddress;
445296177Sjhibbits    struct bm_buffer    bufs[1];
446296177Sjhibbits
447296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
448296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
449296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_Buff, E_NULL_POINTER);
450296177Sjhibbits
451296177Sjhibbits    physAddress = (uint64_t)(XX_VirtToPhys(p_Buff));
452296177Sjhibbits
453296177Sjhibbits    bufs[0].bpid = p_BmPool->bpid;
454296177Sjhibbits    bufs[0].hi = (uint8_t)((physAddress & 0x000000ff00000000LL) >> 32);
455296177Sjhibbits    bufs[0].lo = (uint32_t)(physAddress & 0xffffffff);
456296177Sjhibbits
457296177Sjhibbits    DBG(TRACE,("Put Buffer : poolId %d, address 0x%016llx, phys 0x%016llx",
458296177Sjhibbits               p_BmPool->bpid, (uint64_t)PTR_TO_UINT(p_Buff), physAddress));
459296177Sjhibbits
460296177Sjhibbits    if (!h_BmPortal)
461296177Sjhibbits    {
462296177Sjhibbits        if (p_BmPool->h_BmPortal)
463296177Sjhibbits            h_BmPortal = p_BmPool->h_BmPortal;
464296177Sjhibbits        else
465296177Sjhibbits        {
466296177Sjhibbits            SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
467296177Sjhibbits            h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
468296177Sjhibbits            SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
469296177Sjhibbits        }
470296177Sjhibbits    }
471296177Sjhibbits
472296177Sjhibbits    return BmPoolRelease(p_BmPool, h_BmPortal, bufs, 1, BMAN_RELEASE_FLAG_WAIT);
473296177Sjhibbits}
474296177Sjhibbits
475296177Sjhibbitst_Error BM_POOL_FillBufs(t_Handle h_BmPool, t_Handle h_BmPortal, uint32_t numBufs)
476296177Sjhibbits{
477296177Sjhibbits    t_BmPool    *p_BmPool   = (t_BmPool *)h_BmPool;
478296177Sjhibbits
479296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
480296177Sjhibbits    SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
481296177Sjhibbits
482296177Sjhibbits    if (!h_BmPortal)
483296177Sjhibbits    {
484296177Sjhibbits        if (p_BmPool->h_BmPortal)
485296177Sjhibbits            h_BmPortal = p_BmPool->h_BmPortal;
486296177Sjhibbits        else
487296177Sjhibbits        {
488296177Sjhibbits            SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
489296177Sjhibbits            h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
490296177Sjhibbits            SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
491296177Sjhibbits        }
492296177Sjhibbits    }
493296177Sjhibbits
494296177Sjhibbits    while (numBufs--)
495296177Sjhibbits    {
496296177Sjhibbits        uint8_t             *p_Data;
497296177Sjhibbits        t_Error             res;
498296177Sjhibbits        t_Handle            h_BufContext;
499296177Sjhibbits
500296177Sjhibbits        p_Data = p_BmPool->bufferPoolInfo.f_GetBuf(p_BmPool->bufferPoolInfo.h_BufferPool, &h_BufContext);
501296177Sjhibbits        if(!p_Data)
502296177Sjhibbits            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("run-out of buffers for bpid %d",p_BmPool->bpid));
503296177Sjhibbits
504296177Sjhibbits        if (!p_BmPool->noBuffCtxt)
505296177Sjhibbits            *(t_Handle *)(p_Data - sizeof(t_Handle)) = h_BufContext;
506296177Sjhibbits
507296177Sjhibbits        if ((res = BM_POOL_PutBuf(p_BmPool, h_BmPortal, p_Data)) != E_OK)
508296177Sjhibbits            RETURN_ERROR(CRITICAL, res, ("Seeding reserved buffer pool failed"));
509296177Sjhibbits    }
510296177Sjhibbits
511296177Sjhibbits    return E_OK;
512296177Sjhibbits}
513296177Sjhibbits
514296177Sjhibbitsuint8_t BM_POOL_GetId(t_Handle h_BmPool)
515296177Sjhibbits{
516296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
517296177Sjhibbits
518296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
519296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
520296177Sjhibbits
521296177Sjhibbits    return p_BmPool->bpid;
522296177Sjhibbits}
523296177Sjhibbits
524296177Sjhibbitsuint16_t BM_POOL_GetBufferSize(t_Handle h_BmPool)
525296177Sjhibbits{
526296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
527296177Sjhibbits
528296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
529296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
530296177Sjhibbits
531296177Sjhibbits    return p_BmPool->bufferPoolInfo.bufferSize;
532296177Sjhibbits}
533296177Sjhibbits
534296177Sjhibbitst_Handle BM_POOL_GetBufferContext(t_Handle h_BmPool, void *p_Buff)
535296177Sjhibbits{
536296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
537296177Sjhibbits
538296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
539296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
540296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_Buff, E_NULL_POINTER, NULL);
541296177Sjhibbits
542296177Sjhibbits    if (p_BmPool->noBuffCtxt)
543296177Sjhibbits        return NULL;
544296177Sjhibbits
545296177Sjhibbits    return *(t_Handle *)PTR_MOVE(p_Buff, -(sizeof(t_Handle)));
546296177Sjhibbits}
547296177Sjhibbits
548296177Sjhibbitsvoid * BM_POOL_PhysToVirt(t_Handle h_BmPool, physAddress_t addr)
549296177Sjhibbits{
550296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
551296177Sjhibbits
552296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
553296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
554296177Sjhibbits
555296177Sjhibbits    return p_BmPool->bufferPoolInfo.f_PhysToVirt(addr);
556296177Sjhibbits}
557296177Sjhibbits
558296177SjhibbitsphysAddress_t BM_POOL_VirtToPhys(t_Handle h_BmPool, void *p_Buff)
559296177Sjhibbits{
560296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
561296177Sjhibbits
562296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, (physAddress_t)0);
563296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, (physAddress_t)0);
564296177Sjhibbits
565296177Sjhibbits    return p_BmPool->bufferPoolInfo.f_VirtToPhys(p_Buff);
566296177Sjhibbits}
567296177Sjhibbits
568296177Sjhibbitsuint32_t BM_POOL_GetCounter(t_Handle h_BmPool, e_BmPoolCounters counter)
569296177Sjhibbits{
570296177Sjhibbits    t_BmPool            *p_BmPool   = (t_BmPool *)h_BmPool;
571296177Sjhibbits
572296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
573296177Sjhibbits    SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
574296177Sjhibbits
575296177Sjhibbits    switch(counter)
576296177Sjhibbits    {
577296177Sjhibbits        case(e_BM_POOL_COUNTERS_CONTENT):
578296177Sjhibbits            return BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_CONTENT, p_BmPool->bpid);
579296177Sjhibbits        case(e_BM_POOL_COUNTERS_SW_DEPLETION):
580296177Sjhibbits            return (p_BmPool->swDepletionCount +=
581296177Sjhibbits                BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_SW_DEPLETION, p_BmPool->bpid));
582296177Sjhibbits        case(e_BM_POOL_COUNTERS_HW_DEPLETION):
583296177Sjhibbits            return (p_BmPool->hwDepletionCount +=
584296177Sjhibbits                BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_HW_DEPLETION, p_BmPool->bpid));
585296177Sjhibbits        default:
586296177Sjhibbits            break;
587296177Sjhibbits    }
588296177Sjhibbits
589296177Sjhibbits    /* should never get here */
590296177Sjhibbits    ASSERT_COND(FALSE);
591296177Sjhibbits
592296177Sjhibbits    return 0;
593296177Sjhibbits}
594