xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/SP/fm_sp.c (revision 0957b409)
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)
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 
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 /*****************************************************************************/
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 
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 
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 
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 
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 /*****************************************************************************/
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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