1 /*
2 * Copyright 2008-2012 Freescale Semiconductor Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Freescale Semiconductor nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34 /******************************************************************************
35 @File fm_sp.c
36
37 @Description FM PCD Storage profile ...
38 *//***************************************************************************/
39
40 #include "std_ext.h"
41 #include "error_ext.h"
42 #include "string_ext.h"
43 #include "debug_ext.h"
44 #include "net_ext.h"
45
46 #include "fm_vsp_ext.h"
47 #include "fm_sp.h"
48 #include "fm_common.h"
49 #include "fsl_fman_sp.h"
50
51
52 #if (DPAA_VERSION >= 11)
CheckParamsGeneratedInternally(t_FmVspEntry * p_FmVspEntry)53 static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
54 {
55 t_Error err = E_OK;
56
57 if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
58 RETURN_ERROR(MAJOR, err, NO_MSG);
59 if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
60 RETURN_ERROR(MAJOR, err, NO_MSG);
61 return err;
62
63 }
64
CheckParams(t_FmVspEntry * p_FmVspEntry)65 static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
66 {
67 t_Error err = E_OK;
68
69 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
70 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
71 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
72
73 if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
74 p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
75 p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
76
77 RETURN_ERROR(MAJOR, err, NO_MSG);
78
79 if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
80 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
81
82 err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
83 p_FmVspEntry->portType,
84 p_FmVspEntry->portId,
85 p_FmVspEntry->relativeProfileId);
86
87 return err;
88 }
89 #endif /* (DPAA_VERSION >= 11) */
90
91
92 /*****************************************************************************/
93 /* Inter-module API routines */
94 /*****************************************************************************/
FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools * p_FmExtPools,uint8_t * orderedArray,uint16_t * sizesArray)95 void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
96 uint8_t *orderedArray,
97 uint16_t *sizesArray)
98 {
99 uint16_t bufSize = 0;
100 int i=0, j=0, k=0;
101
102 /* First we copy the external buffers pools information to an ordered local array */
103 for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
104 {
105 /* get pool size */
106 bufSize = p_FmExtPools->extBufPool[i].size;
107
108 /* keep sizes in an array according to poolId for direct access */
109 sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
110
111 /* save poolId in an ordered array according to size */
112 for (j=0;j<=i;j++)
113 {
114 /* this is the next free place in the array */
115 if (j==i)
116 orderedArray[i] = p_FmExtPools->extBufPool[i].id;
117 else
118 {
119 /* find the right place for this poolId */
120 if (bufSize < sizesArray[orderedArray[j]])
121 {
122 /* move the poolIds one place ahead to make room for this poolId */
123 for (k=i;k>j;k--)
124 orderedArray[k] = orderedArray[k-1];
125
126 /* now k==j, this is the place for the new size */
127 orderedArray[k] = p_FmExtPools->extBufPool[i].id;
128 break;
129 }
130 }
131 }
132 }
133 }
134
FmSpCheckBufPoolsParams(t_FmExtPools * p_FmExtPools,t_FmBackupBmPools * p_FmBackupBmPools,t_FmBufPoolDepletion * p_FmBufPoolDepletion)135 t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
136 t_FmBackupBmPools *p_FmBackupBmPools,
137 t_FmBufPoolDepletion *p_FmBufPoolDepletion)
138 {
139
140 int i = 0, j = 0;
141 bool found;
142 uint8_t count = 0;
143
144 if (p_FmExtPools)
145 {
146 if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
147 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
148
149 for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
150 {
151 if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
152 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
153 if (!p_FmExtPools->extBufPool[i].size)
154 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
155 }
156 }
157 if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
158 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
159
160 /* backup BM pools indication is valid only for some chip derivatives
161 (limited by the config routine) */
162 if (p_FmBackupBmPools)
163 {
164 if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
165 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
166 found = FALSE;
167 for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
168 {
169
170 for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
171 {
172 if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
173 {
174 found = TRUE;
175 break;
176 }
177 }
178 if (!found)
179 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
180 else
181 found = FALSE;
182 }
183 }
184
185 /* up to extBufPools.numOfPoolsUsed pools may be defined */
186 if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
187 {
188 if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
189 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools can't be larger than %d and can't be larger than numOfPoolsUsed", FM_PORT_MAX_NUM_OF_EXT_POOLS));
190
191 if (!p_FmBufPoolDepletion->numOfPools)
192 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
193
194 found = FALSE;
195 count = 0;
196 /* for each pool that is in poolsToConsider, check if it is defined
197 in extBufPool */
198 for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
199 {
200 if (p_FmBufPoolDepletion->poolsToConsider[i])
201 {
202 for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
203 {
204 if (i == p_FmExtPools->extBufPool[j].id)
205 {
206 found = TRUE;
207 count++;
208 break;
209 }
210 }
211 if (!found)
212 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
213 else
214 found = FALSE;
215 }
216 }
217 /* check that the number of pools that we have checked is equal to the number announced by the user */
218 if (count != p_FmBufPoolDepletion->numOfPools)
219 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
220 }
221
222 if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
223 {
224 /* calculate vector for number of pools depletion */
225 found = FALSE;
226 count = 0;
227 for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
228 {
229 if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
230 {
231 for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
232 {
233 if (i == p_FmExtPools->extBufPool[j].id)
234 {
235 found = TRUE;
236 count++;
237 break;
238 }
239 }
240 if (!found)
241 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
242 else
243 found = FALSE;
244 }
245 }
246 if (!count)
247 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
248 }
249
250 return E_OK;
251 }
252
FmSpCheckIntContextParams(t_FmSpIntContextDataCopy * p_FmSpIntContextDataCopy)253 t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
254 {
255 /* Check that divisible by 16 and not larger than 240 */
256 if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
257 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
258 if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
259 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
260
261 /* check that ic size+ic internal offset, does not exceed ic block size */
262 if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
263 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
264 /* Check that divisible by 16 and not larger than 256 */
265 if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
266 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
267
268 /* Check that divisible by 16 and not larger than 4K */
269 if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
270 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
271 if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
272 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
273
274 return E_OK;
275 }
276
FmSpCheckBufMargins(t_FmSpBufMargins * p_FmSpBufMargins)277 t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
278 {
279 /* Check the margin definition */
280 if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
281 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
282 if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
283 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
284
285 return E_OK;
286 }
287
FmSpBuildBufferStructure(t_FmSpIntContextDataCopy * p_FmSpIntContextDataCopy,t_FmBufferPrefixContent * p_BufferPrefixContent,t_FmSpBufMargins * p_FmSpBufMargins,t_FmSpBufferOffsets * p_FmSpBufferOffsets,uint8_t * internalBufferOffset)288 t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
289 t_FmBufferPrefixContent *p_BufferPrefixContent,
290 t_FmSpBufMargins *p_FmSpBufMargins,
291 t_FmSpBufferOffsets *p_FmSpBufferOffsets,
292 uint8_t *internalBufferOffset)
293 {
294 uint32_t tmp;
295
296 SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
297 ASSERT_COND(p_FmSpIntContextDataCopy);
298 ASSERT_COND(p_BufferPrefixContent);
299 ASSERT_COND(p_FmSpBufMargins);
300 ASSERT_COND(p_FmSpBufferOffsets);
301
302 /* Align start of internal context data to 16 byte */
303 p_FmSpIntContextDataCopy->extBufOffset =
304 (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
305 ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
306 p_BufferPrefixContent->privDataSize);
307
308 /* Translate margin and intContext params to FM parameters */
309 /* Initialize with illegal value. Later we'll set legal values. */
310 p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
311 p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
312 p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
313 p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
314
315 /* Internally the driver supports 4 options
316 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
317 relate to it as 1).
318 2. All IC context (from AD) not including debug.*/
319
320 /* This 'if' covers option 2. We copy from beginning of context. */
321 if (p_BufferPrefixContent->passAllOtherPCDInfo)
322 {
323 p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
324 /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
325 p_FmSpIntContextDataCopy->intContextOffset = 16;
326
327 if (p_BufferPrefixContent->passAllOtherPCDInfo)
328 p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
329 if (p_BufferPrefixContent->passPrsResult)
330 p_FmSpBufferOffsets->prsResultOffset =
331 (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
332 if (p_BufferPrefixContent->passTimeStamp)
333 p_FmSpBufferOffsets->timeStampOffset =
334 (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
335 if (p_BufferPrefixContent->passHashResult)
336 p_FmSpBufferOffsets->hashResultOffset =
337 (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
338 }
339 else
340 {
341 /* This case covers the options under 1 */
342 /* Copy size must be in 16-byte granularity. */
343 p_FmSpIntContextDataCopy->size =
344 (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
345 ((p_BufferPrefixContent->passTimeStamp ||
346 p_BufferPrefixContent->passHashResult) ? 16 : 0));
347
348 /* Align start of internal context data to 16 byte */
349 p_FmSpIntContextDataCopy->intContextOffset =
350 (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
351 ((p_BufferPrefixContent->passTimeStamp ||
352 p_BufferPrefixContent->passHashResult) ? 64 : 0));
353
354 if (p_BufferPrefixContent->passPrsResult)
355 p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
356 if (p_BufferPrefixContent->passTimeStamp)
357 p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
358 (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
359 p_FmSpIntContextDataCopy->extBufOffset;
360 if (p_BufferPrefixContent->passHashResult)
361 /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
362 p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
363 (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
364 p_FmSpIntContextDataCopy->extBufOffset + 8;
365 }
366
367 if (p_FmSpIntContextDataCopy->size)
368 p_FmSpBufMargins->startMargins =
369 (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
370 p_FmSpIntContextDataCopy->size);
371 else
372 /* No Internal Context passing, STartMargin is immediately after privateInfo */
373 p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
374
375 /* save extra space for manip in both external and internal buffers */
376 if (p_BufferPrefixContent->manipExtraSpace)
377 {
378 uint8_t extraSpace;
379 #ifdef FM_CAPWAP_SUPPORT
380 if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
381 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
382 ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
383 256-CAPWAP_FRAG_EXTRA_SPACE));
384 extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
385 #else
386 extraSpace = p_BufferPrefixContent->manipExtraSpace;
387 #endif /* FM_CAPWAP_SUPPORT */
388 p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
389 p_FmSpBufMargins->startMargins += extraSpace;
390 *internalBufferOffset = extraSpace;
391 }
392
393 /* align data start */
394 tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
395 if (tmp)
396 p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
397 p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
398
399 return E_OK;
400 }
401 /*********************** End of inter-module routines ************************/
402
403
404 #if (DPAA_VERSION >= 11)
405 /*****************************************************************************/
406 /* API routines */
407 /*****************************************************************************/
FM_VSP_Config(t_FmVspParams * p_FmVspParams)408 t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
409 {
410 t_FmVspEntry *p_FmVspEntry = NULL;
411 struct fm_storage_profile_params fm_vsp_params;
412
413 p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
414 if (!p_FmVspEntry)
415 {
416 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
417 return NULL;
418 }
419 memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
420
421 p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
422 if (!p_FmVspEntry->p_FmVspEntryDriverParams)
423 {
424 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
425 XX_Free(p_FmVspEntry);
426 return NULL;
427 }
428 memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
429 fman_vsp_defconfig(&fm_vsp_params);
430 p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
431 p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
432 p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
433 p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
434 p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
435 p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
436 p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
437 p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
438 p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
439 p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
440 = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
441 p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
442 p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
443
444 memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
445 p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
446 p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
447 p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
448
449 p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
450
451 return p_FmVspEntry;
452 }
453
FM_VSP_Init(t_Handle h_FmVsp)454 t_Error FM_VSP_Init(t_Handle h_FmVsp)
455 {
456
457 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
458 struct fm_storage_profile_params fm_vsp_params;
459 uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
460 uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
461 t_Error err;
462 uint16_t absoluteProfileId = 0;
463 int i = 0;
464
465 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
466 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
467
468 CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
469
470 memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
471 memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
472
473 err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
474 &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
475 &p_FmVspEntry->bufMargins,
476 &p_FmVspEntry->bufferOffsets,
477 &p_FmVspEntry->internalBufferOffset);
478 if (err != E_OK)
479 RETURN_ERROR(MAJOR, err, NO_MSG);
480
481
482 err = CheckParamsGeneratedInternally(p_FmVspEntry);
483 if (err != E_OK)
484 RETURN_ERROR(MAJOR, err, NO_MSG);
485
486
487 p_FmVspEntry->p_FmSpRegsBase =
488 (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
489 if (!p_FmVspEntry->p_FmSpRegsBase)
490 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
491
492 /* order external buffer pools in ascending order of buffer pools sizes */
493 FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
494 orderedArray,
495 sizesArray);
496
497 p_FmVspEntry->extBufPools.numOfPoolsUsed =
498 p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
499 for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
500 {
501 p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
502 p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
503 }
504
505 /* on user responsibility to fill it according requirement */
506 memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
507 fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
508 fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
509 fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
510 fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
511 fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
512 fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
513 fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
514
515 if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
516 {
517 fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
518 fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
519 fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
520 fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
521 fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
522 fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
523 fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
524 fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
525 }
526 else
527 fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
528
529 if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
530 {
531 fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
532 fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
533 }
534 else
535 fm_vsp_params.backup_pools.num_backup_pools = 0;
536
537 fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
538 fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
539 fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
540 fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
541
542 /* no check on err - it was checked earlier */
543 FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
544 p_FmVspEntry->portType,
545 p_FmVspEntry->portId,
546 p_FmVspEntry->relativeProfileId,
547 &absoluteProfileId);
548
549 ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
550 ASSERT_COND(fm_vsp_params.int_context);
551 ASSERT_COND(fm_vsp_params.buf_margins);
552 ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
553
554 /* Set all registers related to VSP */
555 fman_vsp_init(p_FmVspEntry->p_FmSpRegsBase, absoluteProfileId, &fm_vsp_params,FM_PORT_MAX_NUM_OF_EXT_POOLS, BM_MAX_NUM_OF_POOLS, FM_MAX_NUM_OF_PFC_PRIORITIES);
556
557 p_FmVspEntry->absoluteSpId = absoluteProfileId;
558
559 if (p_FmVspEntry->p_FmVspEntryDriverParams)
560 XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
561 p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
562
563 return E_OK;
564 }
565
FM_VSP_Free(t_Handle h_FmVsp)566 t_Error FM_VSP_Free(t_Handle h_FmVsp)
567 {
568 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
569 SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
570 XX_Free(p_FmVspEntry);
571 return E_OK;
572 }
573
FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,t_FmBufferPrefixContent * p_FmBufferPrefixContent)574 t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
575 {
576 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
577
578 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
579 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
580
581 memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
582 /* if dataAlign was not initialized by user, we return to driver's default */
583 if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
584 p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
585
586 return E_OK;
587 }
588
FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp,e_FmDmaSwapOption swapData)589 t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
590 {
591 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
592
593 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
594 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
595
596 p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
597
598 return E_OK;
599 }
600
FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,e_FmDmaCacheOption intContextCacheAttr)601 t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
602 {
603 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
604
605 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
606 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
607
608 p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
609
610 return E_OK;
611 }
612
FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp,e_FmDmaCacheOption headerCacheAttr)613 t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
614 {
615 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
616
617 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
618 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
619
620 p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
621
622 return E_OK;
623 }
624
FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,e_FmDmaCacheOption scatterGatherCacheAttr)625 t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
626 {
627 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
628
629 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
630 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
631
632 p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
633
634 return E_OK;
635 }
636
FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp,bool optimize)637 t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
638 {
639 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
640
641 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
642 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
643
644
645 p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
646
647 return E_OK;
648 }
649
FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp,bool noScatherGather)650 t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
651 {
652 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
653
654 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
655 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
656
657
658 p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
659
660 return E_OK;
661 }
662
FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp,t_FmBufPoolDepletion * p_BufPoolDepletion)663 t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
664 {
665 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
666
667 SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
668 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
669 SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
670
671 p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
672 if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
673 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
674 memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
675
676 return E_OK;
677 }
678
FM_VSP_ConfigBackupPools(t_Handle h_FmVsp,t_FmBackupBmPools * p_BackupBmPools)679 t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
680 {
681 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
682
683 SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
684 SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
685 SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
686
687 p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
688 if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
689 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
690 memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
691
692 return E_OK;
693 }
694
FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)695 uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
696 {
697 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
698
699 SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
700 SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
701
702 return p_FmVspEntry->bufferOffsets.dataOffset;
703 }
704
FM_VSP_GetBufferICInfo(t_Handle h_FmVsp,char * p_Data)705 uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
706 {
707 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
708
709 SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
710 SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
711
712 if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
713 return NULL;
714
715 return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
716 }
717
FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp,char * p_Data)718 t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
719 {
720 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
721
722 SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
723 SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
724
725 if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
726 return NULL;
727
728 return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
729 }
730
FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp,char * p_Data)731 uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
732 {
733 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
734
735 SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
736 SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
737
738 if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
739 return NULL;
740
741 return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
742 }
743
FM_VSP_GetBufferHashResult(t_Handle h_FmVsp,char * p_Data)744 uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
745 {
746 t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
747
748 SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
749 SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
750
751 if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
752 return NULL;
753
754 return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
755 }
756
757 #endif /* (DPAA_VERSION >= 11) */
758