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