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 */
depletion_link(t_BmPool * p_BmPool)58 static 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
depletion_unlink(t_BmPool * p_BmPool)68 static 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
BmPoolRelease(t_BmPool * p_BmPool,t_Handle h_BmPortal,struct bm_buffer * bufs,uint8_t num,uint32_t flags)78 static 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
BmPoolAcquire(t_BmPool * p_BmPool,t_Handle h_BmPortal,struct bm_buffer * bufs,uint8_t num,uint32_t flags)133 static 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
BmPoolFree(t_BmPool * p_BmPool,bool discardBuffers)163 static 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
BM_POOL_Config(t_BmPoolParam * p_BmPoolParam)201 t_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
BM_POOL_Init(t_Handle h_BmPool)261 t_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
BM_POOL_Free(t_Handle h_BmPool)327 t_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
BM_POOL_ConfigBpid(t_Handle h_BmPool,uint8_t bpid)334 t_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
BM_POOL_ConfigDepletion(t_Handle h_BmPool,t_BmDepletionCallback * f_Depletion,uint32_t * p_Thresholds)349 t_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
BM_POOL_ConfigStockpile(t_Handle h_BmPool,uint16_t maxBuffers,uint16_t minBuffers)366 t_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
BM_POOL_ConfigBuffContextMode(t_Handle h_BmPool,bool en)390 t_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
BM_POOL_GetBuf(t_Handle h_BmPool,t_Handle h_BmPortal)402 void * 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
BM_POOL_PutBuf(t_Handle h_BmPool,t_Handle h_BmPortal,void * p_Buff)441 t_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
BM_POOL_FillBufs(t_Handle h_BmPool,t_Handle h_BmPortal,uint32_t numBufs)475 t_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
BM_POOL_GetId(t_Handle h_BmPool)514 uint8_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
BM_POOL_GetBufferSize(t_Handle h_BmPool)524 uint16_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
BM_POOL_GetBufferContext(t_Handle h_BmPool,void * p_Buff)534 t_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
BM_POOL_GetCounter(t_Handle h_BmPool,e_BmPoolCounters counter)548 uint32_t BM_POOL_GetCounter(t_Handle h_BmPool, e_BmPoolCounters counter)
549 {
550 t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
551
552 SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
553 SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
554
555 switch(counter)
556 {
557 case(e_BM_POOL_COUNTERS_CONTENT):
558 return BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_CONTENT, p_BmPool->bpid);
559 case(e_BM_POOL_COUNTERS_SW_DEPLETION):
560 return (p_BmPool->swDepletionCount +=
561 BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_SW_DEPLETION, p_BmPool->bpid));
562 case(e_BM_POOL_COUNTERS_HW_DEPLETION):
563 return (p_BmPool->hwDepletionCount +=
564 BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_HW_DEPLETION, p_BmPool->bpid));
565 default:
566 break;
567 }
568
569 /* should never get here */
570 ASSERT_COND(FALSE);
571
572 return 0;
573 }
574