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_port.c 36 37 @Description FM driver routines implementation. 38 *//***************************************************************************/ 39 #include "error_ext.h" 40 #include "std_ext.h" 41 #include "string_ext.h" 42 #include "sprint_ext.h" 43 #include "debug_ext.h" 44 #include "fm_muram_ext.h" 45 46 #include "fman_common.h" 47 #include "fm_port.h" 48 #include "fm_port_dsar.h" 49 #include "common/general.h" 50 51 /****************************************/ 52 /* static functions */ 53 /****************************************/ 54 static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort); 55 56 static t_Error CheckInitParameters(t_FmPort *p_FmPort) 57 { 58 t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; 59 struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg; 60 t_Error ans = E_OK; 61 uint32_t unusedMask; 62 63 if (p_FmPort->imEn) 64 { 65 if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 66 if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 67 > 2) 68 RETURN_ERROR( 69 MAJOR, 70 E_INVALID_VALUE, 71 ("fifoDeqPipelineDepth for IM 10G can't be larger than 2")); 72 73 if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK) 74 return ERROR_CODE(ans); 75 } 76 else 77 { 78 /****************************************/ 79 /* Rx only */ 80 /****************************************/ 81 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 82 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 83 { 84 /* external buffer pools */ 85 if (!p_Params->extBufPools.numOfPoolsUsed) 86 RETURN_ERROR( 87 MAJOR, 88 E_INVALID_VALUE, 89 ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined")); 90 91 if (FmSpCheckBufPoolsParams(&p_Params->extBufPools, 92 p_Params->p_BackupBmPools, 93 &p_Params->bufPoolDepletion) != E_OK) 94 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 95 96 /* Check that part of IC that needs copying is small enough to enter start margin */ 97 if (p_Params->intContext.size 98 && (p_Params->intContext.size 99 + p_Params->intContext.extBufOffset 100 > p_Params->bufMargins.startMargins)) 101 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 102 ("intContext.size is larger than start margins")); 103 104 if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE) 105 && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK)) 106 RETURN_ERROR( 107 MAJOR, 108 E_INVALID_VALUE, 109 ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); 110 111 #ifdef FM_NO_BACKUP_POOLS 112 if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6)) 113 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 114 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools")); 115 #endif /* FM_NO_BACKUP_POOLS */ 116 } 117 118 /****************************************/ 119 /* Non Rx ports */ 120 /****************************************/ 121 else 122 { 123 if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS) 124 RETURN_ERROR( 125 MAJOR, 126 E_INVALID_VALUE, 127 (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS)); 128 129 /* to protect HW internal-context from overwrite */ 130 if ((p_Params->intContext.size) 131 && (p_Params->intContext.intContextOffset 132 < MIN_TX_INT_OFFSET)) 133 RETURN_ERROR( 134 MAJOR, 135 E_INVALID_VALUE, 136 ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET)); 137 138 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 139 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 140 /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */ 141 || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 142 != DEFAULT_notSupported)) 143 { 144 /* Check that not larger than 8 */ 145 if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth) 146 || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 147 > MAX_FIFO_PIPELINE_DEPTH)) 148 RETURN_ERROR( 149 MAJOR, 150 E_INVALID_VALUE, 151 ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH)); 152 } 153 } 154 155 /****************************************/ 156 /* Rx Or Offline Parsing */ 157 /****************************************/ 158 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 159 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 160 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 161 { 162 if (!p_Params->dfltFqid) 163 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 164 ("dfltFqid must be between 1 and 2^24-1")); 165 #if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004) 166 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16) 167 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16")); 168 #endif /* defined(FM_CAPWAP_SUPPORT) && ... */ 169 } 170 171 /****************************************/ 172 /* All ports */ 173 /****************************************/ 174 /* common BMI registers values */ 175 /* Check that Queue Id is not larger than 2^24, and is not 0 */ 176 if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid) 177 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 178 ("errFqid must be between 1 and 2^24-1")); 179 if (p_Params->dfltFqid & ~0x00FFFFFF) 180 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 181 ("dfltFqid must be between 1 and 2^24-1")); 182 } 183 184 /****************************************/ 185 /* Rx only */ 186 /****************************************/ 187 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 188 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 189 { 190 if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS) 191 RETURN_ERROR( 192 MAJOR, 193 E_INVALID_VALUE, 194 ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS)); 195 if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS) 196 || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE)) 197 RETURN_ERROR( 198 MAJOR, 199 E_INVALID_VALUE, 200 ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 201 if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS) 202 RETURN_ERROR( 203 MAJOR, 204 E_INVALID_VALUE, 205 ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS)); 206 if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS) 207 || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE)) 208 RETURN_ERROR( 209 MAJOR, 210 E_INVALID_VALUE, 211 ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 212 213 /* Check that not larger than 16 */ 214 if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE) 215 RETURN_ERROR( 216 MAJOR, 217 E_INVALID_VALUE, 218 ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); 219 220 if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK) 221 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 222 223 /* extra FIFO size (allowed only to Rx ports) */ 224 if (p_Params->setSizeOfFifo 225 && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS)) 226 RETURN_ERROR( 227 MAJOR, 228 E_INVALID_VALUE, 229 ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS)); 230 231 if (p_Params->bufPoolDepletion.poolsGrpModeEnable 232 && !p_Params->bufPoolDepletion.numOfPools) 233 RETURN_ERROR( 234 MAJOR, 235 E_INVALID_VALUE, 236 ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE")); 237 #ifdef FM_CSI_CFED_LIMIT 238 if (p_FmPort->fmRevInfo.majorRev == 4) 239 { 240 /* Check that not larger than 16 */ 241 if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE) 242 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); 243 } 244 #endif /* FM_CSI_CFED_LIMIT */ 245 } 246 247 /****************************************/ 248 /* Non Rx ports */ 249 /****************************************/ 250 /* extra FIFO size (allowed only to Rx ports) */ 251 else 252 if (p_FmPort->fifoBufs.extra) 253 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 254 (" No fifoBufs.extra for non Rx ports")); 255 256 /****************************************/ 257 /* Tx only */ 258 /****************************************/ 259 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 260 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) 261 { 262 if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS) 263 RETURN_ERROR( 264 MAJOR, 265 E_INVALID_VALUE, 266 ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS)); 267 if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256)) 268 RETURN_ERROR( 269 MAJOR, 270 E_INVALID_VALUE, 271 ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256))); 272 if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS) 273 RETURN_ERROR( 274 MAJOR, 275 E_INVALID_VALUE, 276 ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS)); 277 if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS) 278 || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE)) 279 RETURN_ERROR( 280 MAJOR, 281 E_INVALID_VALUE, 282 ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 283 284 if (p_FmPort->portType == e_FM_PORT_TYPE_TX) 285 if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 286 > 2) 287 RETURN_ERROR( 288 MAJOR, E_INVALID_VALUE, 289 ("fifoDeqPipelineDepth for 1G can't be larger than 2")); 290 } 291 292 /****************************************/ 293 /* Non Tx Ports */ 294 /****************************************/ 295 /* If discard override was selected , no frames may be discarded. */ 296 else 297 if (p_DfltConfig->discard_override && p_Params->errorsToDiscard) 298 RETURN_ERROR( 299 MAJOR, 300 E_CONFLICT, 301 ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue).")); 302 303 /****************************************/ 304 /* Rx and Offline parsing */ 305 /****************************************/ 306 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 307 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 308 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 309 { 310 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 311 unusedMask = BMI_STATUS_OP_MASK_UNUSED; 312 else 313 unusedMask = BMI_STATUS_RX_MASK_UNUSED; 314 315 /* Check that no common bits with BMI_STATUS_MASK_UNUSED */ 316 if (p_Params->errorsToDiscard & unusedMask) 317 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, 318 ("errorsToDiscard contains undefined bits")); 319 } 320 321 /****************************************/ 322 /* Offline Ports */ 323 /****************************************/ 324 #ifdef FM_OP_OPEN_DMA_MIN_LIMIT 325 if ((p_FmPort->fmRevInfo.majorRev >= 6) 326 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 327 && p_Params->setNumOfOpenDmas 328 && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS)) 329 RETURN_ERROR( 330 MAJOR, 331 E_INVALID_VALUE, 332 ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS)); 333 #endif /* FM_OP_OPEN_DMA_MIN_LIMIT */ 334 335 /****************************************/ 336 /* Offline & HC Ports */ 337 /****************************************/ 338 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 339 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 340 { 341 #ifndef FM_FRAME_END_PARAMS_FOR_OP 342 if ((p_FmPort->fmRevInfo.majorRev < 6) && 343 (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported)) 344 /* this is an indication that user called config for this mode which is not supported in this integration */ 345 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only")); 346 #endif /* !FM_FRAME_END_PARAMS_FOR_OP */ 347 348 #ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP 349 if ((!((p_FmPort->fmRevInfo.majorRev == 4) || 350 (p_FmPort->fmRevInfo.majorRev >= 6))) && 351 (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported)) 352 /* this is an indication that user called config for this mode which is not supported in this integration */ 353 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only")); 354 #endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ 355 } 356 357 /****************************************/ 358 /* All ports */ 359 /****************************************/ 360 /* Check that not larger than 16 */ 361 if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) 362 && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported))) 363 RETURN_ERROR( 364 MAJOR, 365 E_INVALID_VALUE, 366 ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE)); 367 368 if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK) 369 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 370 371 /* common BMI registers values */ 372 if (p_Params->setNumOfTasks 373 && ((!p_FmPort->tasks.num) 374 || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS))) 375 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 376 ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS)); 377 if (p_Params->setNumOfTasks 378 && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS)) 379 RETURN_ERROR( 380 MAJOR, 381 E_INVALID_VALUE, 382 ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); 383 if (p_Params->setNumOfOpenDmas 384 && ((!p_FmPort->openDmas.num) 385 || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS))) 386 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 387 ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS)); 388 if (p_Params->setNumOfOpenDmas 389 && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS)) 390 RETURN_ERROR( 391 MAJOR, 392 E_INVALID_VALUE, 393 ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); 394 if (p_Params->setSizeOfFifo 395 && (!p_FmPort->fifoBufs.num 396 || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE))) 397 RETURN_ERROR( 398 MAJOR, 399 E_INVALID_VALUE, 400 ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 401 if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS)) 402 RETURN_ERROR( 403 MAJOR, E_INVALID_VALUE, 404 ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS)); 405 406 #ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT 407 if (p_FmPort->fmRevInfo.majorRev == 4) 408 if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported) 409 /* this is an indication that user called config for this mode which is not supported in this integration */ 410 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption")); 411 #endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ 412 413 return E_OK; 414 } 415 416 static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort) 417 { 418 uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0; 419 420 /*************************/ 421 /* TX PORTS */ 422 /*************************/ 423 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 424 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) 425 { 426 minFifoSizeRequired = 427 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 428 + (3 * BMI_FIFO_UNITS)); 429 if (!p_FmPort->imEn) 430 minFifoSizeRequired += 431 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 432 * BMI_FIFO_UNITS; 433 434 optFifoSizeForB2B = minFifoSizeRequired; 435 436 /* Add some margin for back-to-back capability to improve performance, 437 allows the hardware to pipeline new frame dma while the previous 438 frame not yet transmitted. */ 439 if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 440 optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; 441 else 442 optFifoSizeForB2B += 2 * BMI_FIFO_UNITS; 443 } 444 445 /*************************/ 446 /* RX IM PORTS */ 447 /*************************/ 448 else 449 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) 450 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 451 && p_FmPort->imEn) 452 { 453 optFifoSizeForB2B = 454 minFifoSizeRequired = 455 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 456 + (4 * BMI_FIFO_UNITS)); 457 } 458 459 /*************************/ 460 /* RX non-IM PORTS */ 461 /*************************/ 462 else 463 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) 464 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 465 && !p_FmPort->imEn) 466 { 467 if (p_FmPort->fmRevInfo.majorRev == 4) 468 { 469 if (p_FmPort->rxPoolsParams.numOfPools == 1) 470 minFifoSizeRequired = 8 * BMI_FIFO_UNITS; 471 else 472 minFifoSizeRequired = 473 (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS) 474 + (7 * BMI_FIFO_UNITS)); 475 } 476 else 477 { 478 #if (DPAA_VERSION >= 11) 479 minFifoSizeRequired = 480 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 481 + (5 * BMI_FIFO_UNITS)); 482 /* 4 according to spec + 1 for FOF>0 */ 483 #else 484 minFifoSizeRequired = (uint32_t) 485 (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS) 486 + (7*BMI_FIFO_UNITS)); 487 #endif /* (DPAA_VERSION >= 11) */ 488 } 489 490 optFifoSizeForB2B = minFifoSizeRequired; 491 492 /* Add some margin for back-to-back capability to improve performance, 493 allows the hardware to pipeline new frame dma while the previous 494 frame not yet transmitted. */ 495 if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 496 optFifoSizeForB2B += 8 * BMI_FIFO_UNITS; 497 else 498 optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; 499 } 500 501 /* For O/H ports, check fifo size and update if necessary */ 502 else 503 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 504 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 505 { 506 #if (DPAA_VERSION >= 11) 507 optFifoSizeForB2B = 508 minFifoSizeRequired = 509 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 510 + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 511 + 5) * BMI_FIFO_UNITS)); 512 /* 4 according to spec + 1 for FOF>0 */ 513 #else 514 optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS); 515 #endif /* (DPAA_VERSION >= 11) */ 516 } 517 518 ASSERT_COND(minFifoSizeRequired > 0); 519 ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired); 520 521 /* Verify the size */ 522 if (p_FmPort->fifoBufs.num < minFifoSizeRequired) 523 DBG(INFO, 524 ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired)); 525 else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B) 526 DBG(INFO, 527 ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B)); 528 529 return E_OK; 530 } 531 532 static void FmPortDriverParamFree(t_FmPort *p_FmPort) 533 { 534 if (p_FmPort->p_FmPortDriverParam) 535 { 536 XX_Free(p_FmPort->p_FmPortDriverParam); 537 p_FmPort->p_FmPortDriverParam = NULL; 538 } 539 } 540 541 static t_Error SetExtBufferPools(t_FmPort *p_FmPort) 542 { 543 t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools; 544 t_FmBufPoolDepletion *p_BufPoolDepletion = 545 &p_FmPort->p_FmPortDriverParam->bufPoolDepletion; 546 uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; 547 uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; 548 int i = 0, j = 0, err; 549 struct fman_port_bpools bpools; 550 551 memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS); 552 memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS); 553 memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools)); 554 555 FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray, 556 sizesArray); 557 558 /* Prepare flibs bpools structure */ 559 memset(&bpools, 0, sizeof(struct fman_port_bpools)); 560 bpools.count = p_ExtBufPools->numOfPoolsUsed; 561 bpools.counters_enable = TRUE; 562 for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++) 563 { 564 bpools.bpool[i].bpid = orderedArray[i]; 565 bpools.bpool[i].size = sizesArray[orderedArray[i]]; 566 /* functionality available only for some derivatives (limited by config) */ 567 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 568 for (j = 0; 569 j 570 < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools; 571 j++) 572 if (orderedArray[i] 573 == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j]) 574 { 575 bpools.bpool[i].is_backup = TRUE; 576 break; 577 } 578 } 579 580 /* save pools parameters for later use */ 581 p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed; 582 p_FmPort->rxPoolsParams.largestBufSize = 583 sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]]; 584 p_FmPort->rxPoolsParams.secondLargestBufSize = 585 sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]]; 586 587 /* FMBM_RMPD reg. - pool depletion */ 588 if (p_BufPoolDepletion->poolsGrpModeEnable) 589 { 590 bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools; 591 for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++) 592 { 593 if (p_BufPoolDepletion->poolsToConsider[i]) 594 { 595 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) 596 { 597 if (i == orderedArray[j]) 598 { 599 bpools.bpool[j].grp_bp_depleted = TRUE; 600 break; 601 } 602 } 603 } 604 } 605 } 606 607 if (p_BufPoolDepletion->singlePoolModeEnable) 608 { 609 for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++) 610 { 611 if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i]) 612 { 613 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) 614 { 615 if (i == orderedArray[j]) 616 { 617 bpools.bpool[j].single_bp_depleted = TRUE; 618 break; 619 } 620 } 621 } 622 } 623 } 624 625 #if (DPAA_VERSION >= 11) 626 /* fill QbbPEV */ 627 if (p_BufPoolDepletion->poolsGrpModeEnable 628 || p_BufPoolDepletion->singlePoolModeEnable) 629 { 630 for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++) 631 { 632 if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE) 633 { 634 bpools.bpool[i].pfc_priorities_en = TRUE; 635 } 636 } 637 } 638 #endif /* (DPAA_VERSION >= 11) */ 639 640 /* Issue flibs function */ 641 err = fman_port_set_bpools(&p_FmPort->port, &bpools); 642 if (err != 0) 643 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools")); 644 645 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 646 XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools); 647 648 return E_OK; 649 } 650 651 static t_Error ClearPerfCnts(t_FmPort *p_FmPort) 652 { 653 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 654 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0); 655 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0); 656 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0); 657 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0); 658 return E_OK; 659 } 660 661 static t_Error InitLowLevelDriver(t_FmPort *p_FmPort) 662 { 663 t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam; 664 struct fman_port_params portParams; 665 uint32_t tmpVal; 666 t_Error err; 667 668 /* Set up flibs parameters and issue init function */ 669 670 memset(&portParams, 0, sizeof(struct fman_port_params)); 671 portParams.discard_mask = p_DriverParams->errorsToDiscard; 672 portParams.dflt_fqid = p_DriverParams->dfltFqid; 673 portParams.err_fqid = p_DriverParams->errFqid; 674 portParams.deq_sp = p_DriverParams->deqSubPortal; 675 portParams.dont_release_buf = p_DriverParams->dontReleaseBuf; 676 switch (p_FmPort->portType) 677 { 678 case (e_FM_PORT_TYPE_RX_10G): 679 case (e_FM_PORT_TYPE_RX): 680 portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask); 681 if (!p_FmPort->imEn) 682 { 683 if (p_DriverParams->forwardReuseIntContext) 684 p_DriverParams->dfltCfg.rx_fd_bits = 685 (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24); 686 } 687 break; 688 689 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 690 portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask); 691 break; 692 break; 693 694 default: 695 break; 696 } 697 698 tmpVal = 699 (uint32_t)( 700 (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset 701 / OFFSET_UNITS + 1) : 702 (p_FmPort->internalBufferOffset / OFFSET_UNITS)); 703 p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS); 704 p_DriverParams->dfltCfg.int_buf_start_margin = 705 p_FmPort->internalBufferOffset; 706 707 p_DriverParams->dfltCfg.ext_buf_start_margin = 708 p_DriverParams->bufMargins.startMargins; 709 p_DriverParams->dfltCfg.ext_buf_end_margin = 710 p_DriverParams->bufMargins.endMargins; 711 712 p_DriverParams->dfltCfg.ic_ext_offset = 713 p_DriverParams->intContext.extBufOffset; 714 p_DriverParams->dfltCfg.ic_int_offset = 715 p_DriverParams->intContext.intContextOffset; 716 p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size; 717 718 p_DriverParams->dfltCfg.stats_counters_enable = TRUE; 719 p_DriverParams->dfltCfg.perf_counters_enable = TRUE; 720 p_DriverParams->dfltCfg.queue_counters_enable = TRUE; 721 722 p_DriverParams->dfltCfg.perf_cnt_params.task_val = 723 (uint8_t)p_FmPort->tasks.num; 724 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING || 725 p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0; 726 else 727 p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1; 728 p_DriverParams->dfltCfg.perf_cnt_params.dma_val = 729 (uint8_t)p_FmPort->openDmas.num; 730 p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num; 731 732 if (0 733 != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg, 734 &portParams)) 735 RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init")); 736 737 if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK)) 738 RETURN_ERROR(MAJOR, err, NO_MSG); 739 else 740 { 741 // from QMIInit 742 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 743 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 744 { 745 if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH) 746 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, 747 FALSE); 748 else 749 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, 750 TRUE); 751 } 752 } 753 /* The code bellow is a trick so the FM will not release the buffer 754 to BM nor will try to enqueue the frame to QM */ 755 if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 756 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn)) 757 { 758 if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf) 759 { 760 /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to 761 * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release 762 * buffers to BM regardless of fmbm_tfene 763 */ 764 WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF); 765 WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene, 766 NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); 767 } 768 } 769 770 return E_OK; 771 } 772 773 static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) 774 { 775 UNUSED(p_FmPort); 776 777 switch (counter) 778 { 779 case (e_FM_PORT_COUNTERS_CYCLE): 780 case (e_FM_PORT_COUNTERS_TASK_UTIL): 781 case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 782 case (e_FM_PORT_COUNTERS_DMA_UTIL): 783 case (e_FM_PORT_COUNTERS_FIFO_UTIL): 784 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 785 case (e_FM_PORT_COUNTERS_FRAME): 786 case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 787 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): 788 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 789 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 790 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 791 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 792 case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 793 case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER): 794 return TRUE; 795 default: 796 return FALSE; 797 } 798 } 799 800 static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) 801 { 802 UNUSED(p_FmPort); 803 804 switch (counter) 805 { 806 case (e_FM_PORT_COUNTERS_CYCLE): 807 case (e_FM_PORT_COUNTERS_TASK_UTIL): 808 case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 809 case (e_FM_PORT_COUNTERS_DMA_UTIL): 810 case (e_FM_PORT_COUNTERS_FIFO_UTIL): 811 case (e_FM_PORT_COUNTERS_FRAME): 812 case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 813 case (e_FM_PORT_COUNTERS_LENGTH_ERR): 814 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 815 case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 816 return TRUE; 817 default: 818 return FALSE; 819 } 820 } 821 822 static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) 823 { 824 switch (counter) 825 { 826 case (e_FM_PORT_COUNTERS_CYCLE): 827 case (e_FM_PORT_COUNTERS_TASK_UTIL): 828 case (e_FM_PORT_COUNTERS_DMA_UTIL): 829 case (e_FM_PORT_COUNTERS_FIFO_UTIL): 830 case (e_FM_PORT_COUNTERS_FRAME): 831 case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 832 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 833 case (e_FM_PORT_COUNTERS_WRED_DISCARD): 834 case (e_FM_PORT_COUNTERS_LENGTH_ERR): 835 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 836 case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 837 return TRUE; 838 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 839 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 840 return FALSE; 841 else 842 return TRUE; 843 default: 844 return FALSE; 845 } 846 } 847 848 static t_Error BmiPortCheckAndGetCounterType( 849 t_FmPort *p_FmPort, e_FmPortCounters counter, 850 enum fman_port_stats_counters *p_StatsType, 851 enum fman_port_perf_counters *p_PerfType, bool *p_IsStats) 852 { 853 volatile uint32_t *p_Reg; 854 bool isValid; 855 856 switch (p_FmPort->portType) 857 { 858 case (e_FM_PORT_TYPE_RX_10G): 859 case (e_FM_PORT_TYPE_RX): 860 p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc; 861 isValid = CheckRxBmiCounter(p_FmPort, counter); 862 break; 863 case (e_FM_PORT_TYPE_TX_10G): 864 case (e_FM_PORT_TYPE_TX): 865 p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc; 866 isValid = CheckTxBmiCounter(p_FmPort, counter); 867 break; 868 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 869 case (e_FM_PORT_TYPE_OH_HOST_COMMAND): 870 p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc; 871 isValid = CheckOhBmiCounter(p_FmPort, counter); 872 break; 873 default: 874 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); 875 } 876 877 if (!isValid) 878 RETURN_ERROR(MINOR, E_INVALID_STATE, 879 ("Requested counter is not available for this port type")); 880 881 /* check that counters are enabled */ 882 switch (counter) 883 { 884 case (e_FM_PORT_COUNTERS_CYCLE): 885 case (e_FM_PORT_COUNTERS_TASK_UTIL): 886 case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 887 case (e_FM_PORT_COUNTERS_DMA_UTIL): 888 case (e_FM_PORT_COUNTERS_FIFO_UTIL): 889 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 890 /* performance counters - may be read when disabled */ 891 *p_IsStats = FALSE; 892 break; 893 case (e_FM_PORT_COUNTERS_FRAME): 894 case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 895 case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 896 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): 897 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 898 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 899 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 900 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 901 case (e_FM_PORT_COUNTERS_LENGTH_ERR): 902 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 903 case (e_FM_PORT_COUNTERS_WRED_DISCARD): 904 *p_IsStats = TRUE; 905 if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN)) 906 RETURN_ERROR(MINOR, E_INVALID_STATE, 907 ("Requested counter was not enabled")); 908 break; 909 default: 910 break; 911 } 912 913 /* Set counter */ 914 switch (counter) 915 { 916 case (e_FM_PORT_COUNTERS_CYCLE): 917 *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE; 918 break; 919 case (e_FM_PORT_COUNTERS_TASK_UTIL): 920 *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL; 921 break; 922 case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 923 *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL; 924 break; 925 case (e_FM_PORT_COUNTERS_DMA_UTIL): 926 *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL; 927 break; 928 case (e_FM_PORT_COUNTERS_FIFO_UTIL): 929 *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL; 930 break; 931 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 932 *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE; 933 break; 934 case (e_FM_PORT_COUNTERS_FRAME): 935 *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME; 936 break; 937 case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 938 *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD; 939 break; 940 case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 941 *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF; 942 break; 943 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): 944 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME; 945 break; 946 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 947 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME; 948 break; 949 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 950 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF; 951 break; 952 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 953 *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME; 954 break; 955 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 956 *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR; 957 break; 958 case (e_FM_PORT_COUNTERS_WRED_DISCARD): 959 *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD; 960 break; 961 case (e_FM_PORT_COUNTERS_LENGTH_ERR): 962 *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR; 963 break; 964 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 965 *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT; 966 break; 967 default: 968 break; 969 } 970 971 return E_OK; 972 } 973 974 static t_Error AdditionalPrsParams(t_FmPort *p_FmPort, 975 t_FmPcdPrsAdditionalHdrParams *p_HdrParams, 976 uint32_t *p_SoftSeqAttachReg) 977 { 978 uint8_t hdrNum, Ipv4HdrNum; 979 u_FmPcdHdrPrsOpts *p_prsOpts; 980 uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset; 981 982 if (IS_PRIVATE_HEADER(p_HdrParams->hdr) 983 || IS_SPECIAL_HEADER(p_HdrParams->hdr)) 984 RETURN_ERROR( 985 MAJOR, E_NOT_SUPPORTED, 986 ("No additional parameters for private or special headers.")); 987 988 if (p_HdrParams->errDisable) 989 tmpReg |= PRS_HDR_ERROR_DIS; 990 991 /* Set parser options */ 992 if (p_HdrParams->usePrsOpts) 993 { 994 p_prsOpts = &p_HdrParams->prsOpts; 995 switch (p_HdrParams->hdr) 996 { 997 case (HEADER_TYPE_MPLS): 998 if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable) 999 tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN; 1000 hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse); 1001 if (hdrNum == ILLEGAL_HDR_NUM) 1002 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1003 Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1004 if (hdrNum < Ipv4HdrNum) 1005 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1006 ("Header must be equal or higher than IPv4")); 1007 tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE) 1008 << PRS_HDR_MPLS_NEXT_HDR_SHIFT; 1009 break; 1010 case (HEADER_TYPE_PPPoE): 1011 if (p_prsOpts->pppoePrsOptions.enableMTUCheck) 1012 tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN; 1013 break; 1014 case (HEADER_TYPE_IPv6): 1015 if (p_prsOpts->ipv6PrsOptions.routingHdrEnable) 1016 tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN; 1017 break; 1018 case (HEADER_TYPE_TCP): 1019 if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum) 1020 tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; 1021 else 1022 tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL; 1023 break; 1024 case (HEADER_TYPE_UDP): 1025 if (p_prsOpts->udpPrsOptions.padIgnoreChecksum) 1026 tmpReg |= PRS_HDR_UDP_PAD_REMOVAL; 1027 else 1028 tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL; 1029 break; 1030 default: 1031 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header")); 1032 } 1033 } 1034 1035 /* set software parsing (address is divided in 2 since parser uses 2 byte access. */ 1036 if (p_HdrParams->swPrsEnable) 1037 { 1038 tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr, 1039 p_HdrParams->indexPerHdr); 1040 if (tmpPrsOffset == ILLEGAL_BASE) 1041 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1042 tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset); 1043 } 1044 *p_SoftSeqAttachReg = tmpReg; 1045 1046 return E_OK; 1047 } 1048 1049 static uint32_t GetPortSchemeBindParams( 1050 t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) 1051 { 1052 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1053 uint32_t walking1Mask = 0x80000000, tmp; 1054 uint8_t idx = 0; 1055 1056 p_SchemeBind->netEnvId = p_FmPort->netEnvId; 1057 p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId; 1058 p_SchemeBind->useClsPlan = p_FmPort->useClsPlan; 1059 p_SchemeBind->numOfSchemes = 0; 1060 tmp = p_FmPort->schemesPerPortVector; 1061 if (tmp) 1062 { 1063 while (tmp) 1064 { 1065 if (tmp & walking1Mask) 1066 { 1067 p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx; 1068 p_SchemeBind->numOfSchemes++; 1069 tmp &= ~walking1Mask; 1070 } 1071 walking1Mask >>= 1; 1072 idx++; 1073 } 1074 } 1075 1076 return tmp; 1077 } 1078 1079 static void FmPortCheckNApplyMacsec(t_Handle h_FmPort) 1080 { 1081 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1082 volatile uint32_t *p_BmiCfgReg = NULL; 1083 uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC; 1084 uint32_t lcv, walking1Mask = 0x80000000; 1085 uint8_t cnt = 0; 1086 1087 ASSERT_COND(p_FmPort); 1088 ASSERT_COND(p_FmPort->h_FmPcd); 1089 ASSERT_COND(!p_FmPort->p_FmPortDriverParam); 1090 1091 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 1092 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 1093 return; 1094 1095 p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg; 1096 /* get LCV for MACSEC */ 1097 if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId)) 1098 != 0) 1099 { 1100 while (!(lcv & walking1Mask)) 1101 { 1102 cnt++; 1103 walking1Mask >>= 1; 1104 } 1105 1106 macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT; 1107 WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn); 1108 } 1109 } 1110 1111 static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams) 1112 { 1113 t_Error err = E_OK; 1114 uint32_t tmpReg; 1115 volatile uint32_t *p_BmiNia = NULL; 1116 volatile uint32_t *p_BmiPrsNia = NULL; 1117 volatile uint32_t *p_BmiPrsStartOffset = NULL; 1118 volatile uint32_t *p_BmiInitPrsResult = NULL; 1119 volatile uint32_t *p_BmiCcBase = NULL; 1120 uint16_t hdrNum, L3HdrNum, greHdrNum; 1121 int i; 1122 bool isEmptyClsPlanGrp; 1123 uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS]; 1124 uint16_t absoluteProfileId; 1125 uint8_t physicalSchemeId; 1126 uint32_t ccTreePhysOffset; 1127 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 1128 uint32_t initialSwPrs = 0; 1129 1130 ASSERT_COND(p_FmPort); 1131 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1132 1133 if (p_FmPort->imEn) 1134 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1135 ("available for non-independant mode ports only")); 1136 1137 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 1138 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 1139 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1140 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1141 ("available for Rx and offline parsing ports only")); 1142 1143 p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv); 1144 1145 p_FmPort->pcdEngines = 0; 1146 1147 /* initialize p_FmPort->pcdEngines field in port's structure */ 1148 switch (p_PcdParams->pcdSupport) 1149 { 1150 case (e_FM_PORT_PCD_SUPPORT_NONE): 1151 RETURN_ERROR( 1152 MAJOR, 1153 E_INVALID_STATE, 1154 ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected")); 1155 case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): 1156 p_FmPort->pcdEngines |= FM_PCD_PRS; 1157 break; 1158 case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY): 1159 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1160 break; 1161 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): 1162 p_FmPort->pcdEngines |= FM_PCD_PRS; 1163 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1164 break; 1165 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): 1166 p_FmPort->pcdEngines |= FM_PCD_PRS; 1167 p_FmPort->pcdEngines |= FM_PCD_KG; 1168 break; 1169 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): 1170 p_FmPort->pcdEngines |= FM_PCD_PRS; 1171 p_FmPort->pcdEngines |= FM_PCD_CC; 1172 p_FmPort->pcdEngines |= FM_PCD_KG; 1173 break; 1174 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): 1175 p_FmPort->pcdEngines |= FM_PCD_PRS; 1176 p_FmPort->pcdEngines |= FM_PCD_KG; 1177 p_FmPort->pcdEngines |= FM_PCD_CC; 1178 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1179 break; 1180 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): 1181 p_FmPort->pcdEngines |= FM_PCD_PRS; 1182 p_FmPort->pcdEngines |= FM_PCD_CC; 1183 break; 1184 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): 1185 p_FmPort->pcdEngines |= FM_PCD_PRS; 1186 p_FmPort->pcdEngines |= FM_PCD_CC; 1187 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1188 break; 1189 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): 1190 p_FmPort->pcdEngines |= FM_PCD_PRS; 1191 p_FmPort->pcdEngines |= FM_PCD_KG; 1192 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1193 break; 1194 case (e_FM_PORT_PCD_SUPPORT_CC_ONLY): 1195 p_FmPort->pcdEngines |= FM_PCD_CC; 1196 break; 1197 #ifdef FM_CAPWAP_SUPPORT 1198 case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG): 1199 p_FmPort->pcdEngines |= FM_PCD_CC; 1200 p_FmPort->pcdEngines |= FM_PCD_KG; 1201 break; 1202 case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR): 1203 p_FmPort->pcdEngines |= FM_PCD_CC; 1204 p_FmPort->pcdEngines |= FM_PCD_KG; 1205 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1206 break; 1207 #endif /* FM_CAPWAP_SUPPORT */ 1208 1209 default: 1210 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport")); 1211 } 1212 1213 if ((p_FmPort->pcdEngines & FM_PCD_PRS) 1214 && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams 1215 > FM_PCD_PRS_NUM_OF_HDRS)) 1216 RETURN_ERROR( 1217 MAJOR, 1218 E_INVALID_VALUE, 1219 ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS)); 1220 1221 /* check that parameters exist for each and only each defined engine */ 1222 if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams) 1223 || (!!(p_FmPort->pcdEngines & FM_PCD_KG) 1224 != !!p_PcdParams->p_KgParams) 1225 || (!!(p_FmPort->pcdEngines & FM_PCD_CC) 1226 != !!p_PcdParams->p_CcParams)) 1227 RETURN_ERROR( 1228 MAJOR, 1229 E_INVALID_STATE, 1230 ("PCD initialization structure is not consistent with pcdSupport")); 1231 1232 /* get PCD registers pointers */ 1233 switch (p_FmPort->portType) 1234 { 1235 case (e_FM_PORT_TYPE_RX_10G): 1236 case (e_FM_PORT_TYPE_RX): 1237 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1238 p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; 1239 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; 1240 p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0]; 1241 p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb; 1242 break; 1243 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1244 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1245 p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; 1246 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; 1247 p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0]; 1248 p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb; 1249 break; 1250 default: 1251 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 1252 } 1253 1254 /* set PCD port parameter */ 1255 if (p_FmPort->pcdEngines & FM_PCD_CC) 1256 { 1257 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams, 1258 p_PcdParams->p_CcParams->h_CcTree, 1259 &ccTreePhysOffset, p_FmPort); 1260 if (err) 1261 RETURN_ERROR(MAJOR, err, NO_MSG); 1262 1263 WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); 1264 p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree; 1265 } 1266 1267 if (p_FmPort->pcdEngines & FM_PCD_KG) 1268 { 1269 if (p_PcdParams->p_KgParams->numOfSchemes == 0) 1270 RETURN_ERROR( 1271 MAJOR, 1272 E_INVALID_VALUE, 1273 ("For ports using Keygen, at least one scheme must be bound. ")); 1274 1275 err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd, 1276 p_FmPort->hardwarePortId, 1277 p_FmPort->netEnvId, 1278 p_FmPort->optArray, 1279 &p_FmPort->clsPlanGrpId, 1280 &isEmptyClsPlanGrp); 1281 if (err) 1282 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1283 ("FmPcdKgSetOrBindToClsPlanGrp failed. ")); 1284 1285 p_FmPort->useClsPlan = !isEmptyClsPlanGrp; 1286 1287 schemeBind.netEnvId = p_FmPort->netEnvId; 1288 schemeBind.hardwarePortId = p_FmPort->hardwarePortId; 1289 schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes; 1290 schemeBind.useClsPlan = p_FmPort->useClsPlan; 1291 1292 /* for each scheme */ 1293 for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) 1294 { 1295 ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]); 1296 physicalSchemeId = FmPcdKgGetSchemeId( 1297 p_PcdParams->p_KgParams->h_Schemes[i]); 1298 schemeBind.schemesIds[i] = physicalSchemeId; 1299 /* build vector */ 1300 p_FmPort->schemesPerPortVector |= 1 1301 << (31 - (uint32_t)physicalSchemeId); 1302 #if (DPAA_VERSION >= 11) 1303 /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement 1304 if !VSPE - in port, for relevant scheme VSPE can not be set*/ 1305 if (!p_FmPort->vspe 1306 && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i]))) 1307 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1308 ("VSPE is not at port level")); 1309 #endif /* (DPAA_VERSION >= 11) */ 1310 } 1311 1312 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 1313 if (err) 1314 RETURN_ERROR(MAJOR, err, NO_MSG); 1315 } 1316 1317 /***************************/ 1318 /* configure NIA after BMI */ 1319 /***************************/ 1320 /* rfne may contain FDCS bits, so first we read them. */ 1321 p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; 1322 1323 /* If policer is used directly after BMI or PRS */ 1324 if ((p_FmPort->pcdEngines & FM_PCD_PLCR) 1325 && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY) 1326 || (p_PcdParams->pcdSupport 1327 == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR))) 1328 { 1329 if (!p_PcdParams->p_PlcrParams->h_Profile) 1330 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1331 ("Profile should be initialized")); 1332 1333 absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId( 1334 p_PcdParams->p_PlcrParams->h_Profile); 1335 1336 if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) 1337 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1338 ("Private port profile not valid.")); 1339 1340 tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE); 1341 1342 if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ 1343 /* update BMI HPNIA */ 1344 WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg)); 1345 else 1346 /* e_FM_PCD_SUPPORT_PLCR_ONLY */ 1347 /* update BMI NIA */ 1348 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR); 1349 } 1350 1351 /* if CC is used directly after BMI */ 1352 if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) 1353 #ifdef FM_CAPWAP_SUPPORT 1354 || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) 1355 || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR) 1356 #endif /* FM_CAPWAP_SUPPORT */ 1357 ) 1358 { 1359 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1360 RETURN_ERROR( 1361 MAJOR, 1362 E_INVALID_OPERATION, 1363 ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only")); 1364 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); 1365 /* check that prs start offset == RIM[FOF] */ 1366 } 1367 1368 if (p_FmPort->pcdEngines & FM_PCD_PRS) 1369 { 1370 ASSERT_COND(p_PcdParams->p_PrsParams); 1371 #if (DPAA_VERSION >= 11) 1372 if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP) 1373 hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL; 1374 else 1375 { 1376 #endif /* (DPAA_VERSION >= 11) */ 1377 /* if PRS is used it is always first */ 1378 hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr); 1379 if (hdrNum == ILLEGAL_HDR_NUM) 1380 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); 1381 #if (DPAA_VERSION >= 11) 1382 } 1383 #endif /* (DPAA_VERSION >= 11) */ 1384 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum)); 1385 /* set after parser NIA */ 1386 tmpReg = 0; 1387 switch (p_PcdParams->pcdSupport) 1388 { 1389 case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): 1390 WRITE_UINT32(*p_BmiPrsNia, 1391 GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd)); 1392 break; 1393 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): 1394 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): 1395 tmpReg = NIA_KG_CC_EN; 1396 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): 1397 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): 1398 if (p_PcdParams->p_KgParams->directScheme) 1399 { 1400 physicalSchemeId = FmPcdKgGetSchemeId( 1401 p_PcdParams->p_KgParams->h_DirectScheme); 1402 /* check that this scheme was bound to this port */ 1403 for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) 1404 if (p_PcdParams->p_KgParams->h_DirectScheme 1405 == p_PcdParams->p_KgParams->h_Schemes[i]) 1406 break; 1407 if (i == p_PcdParams->p_KgParams->numOfSchemes) 1408 RETURN_ERROR( 1409 MAJOR, 1410 E_INVALID_VALUE, 1411 ("Direct scheme is not one of the port selected schemes.")); 1412 tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId); 1413 } 1414 WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg); 1415 break; 1416 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): 1417 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): 1418 WRITE_UINT32(*p_BmiPrsNia, 1419 (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); 1420 break; 1421 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): 1422 break; 1423 default: 1424 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support")); 1425 } 1426 1427 /* set start parsing offset */ 1428 WRITE_UINT32(*p_BmiPrsStartOffset, 1429 p_PcdParams->p_PrsParams->parsingOffset); 1430 1431 /************************************/ 1432 /* Parser port parameters */ 1433 /************************************/ 1434 /* stop before configuring */ 1435 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); 1436 /* wait for parser to be in idle state */ 1437 while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) 1438 ; 1439 1440 /* set soft seq attachment register */ 1441 memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t)); 1442 1443 /* set protocol options */ 1444 for (i = 0; p_FmPort->optArray[i]; i++) 1445 switch (p_FmPort->optArray[i]) 1446 { 1447 case (ETH_BROADCAST): 1448 hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); 1449 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT; 1450 break; 1451 case (ETH_MULTICAST): 1452 hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); 1453 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT; 1454 break; 1455 case (VLAN_STACKED): 1456 hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN); 1457 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT; 1458 break; 1459 case (MPLS_STACKED): 1460 hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); 1461 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT; 1462 break; 1463 case (IPV4_BROADCAST_1): 1464 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1465 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT; 1466 break; 1467 case (IPV4_MULTICAST_1): 1468 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1469 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT; 1470 break; 1471 case (IPV4_UNICAST_2): 1472 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1473 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT; 1474 break; 1475 case (IPV4_MULTICAST_BROADCAST_2): 1476 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1477 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT; 1478 break; 1479 case (IPV6_MULTICAST_1): 1480 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1481 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT; 1482 break; 1483 case (IPV6_UNICAST_2): 1484 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1485 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT; 1486 break; 1487 case (IPV6_MULTICAST_2): 1488 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1489 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT; 1490 break; 1491 } 1492 1493 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, 1494 HEADER_TYPE_UDP_ENCAP_ESP)) 1495 { 1496 if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS) 1497 RETURN_ERROR( 1498 MINOR, E_INVALID_VALUE, 1499 ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1")); 1500 1501 p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr = 1502 HEADER_TYPE_UDP; 1503 p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable = 1504 TRUE; 1505 p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++; 1506 } 1507 1508 /* set MPLS default next header - HW reset workaround */ 1509 hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); 1510 tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN; 1511 L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3); 1512 tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT; 1513 1514 /* for GRE, disable errors */ 1515 greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE); 1516 tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS; 1517 1518 /* For UDP remove PAD from L4 checksum calculation */ 1519 hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP); 1520 tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL; 1521 /* For TCP remove PAD from L4 checksum calculation */ 1522 hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP); 1523 tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL; 1524 1525 /* config additional params for specific headers */ 1526 for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams; 1527 i++) 1528 { 1529 /* case for using sw parser as the initial NIA address, before 1530 * HW parsing 1531 */ 1532 if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) && 1533 p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable) 1534 { 1535 initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE, 1536 p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr); 1537 if (initialSwPrs == ILLEGAL_BASE) 1538 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1539 1540 /* clear parser first HXS */ 1541 p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */ 1542 /* rewrite with soft parser start */ 1543 p_FmPort->savedBmiNia |= initialSwPrs; 1544 continue; 1545 } 1546 1547 hdrNum = 1548 GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr); 1549 if (hdrNum == ILLEGAL_HDR_NUM) 1550 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1551 if (hdrNum == NO_HDR_NUM) 1552 RETURN_ERROR( 1553 MAJOR, E_INVALID_VALUE, 1554 ("Private headers may not use additional parameters")); 1555 1556 err = AdditionalPrsParams( 1557 p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i], 1558 &tmpHxs[hdrNum]); 1559 if (err) 1560 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1561 } 1562 1563 /* Check if ip-reassembly port - need to link sw-parser code */ 1564 if (p_FmPort->h_IpReassemblyManip) 1565 { 1566 /* link to sw parser code for IP Frag - only if no other code is applied. */ 1567 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1568 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1569 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL); 1570 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1571 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1572 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL); 1573 } else { 1574 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE)) 1575 { 1576 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1577 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1578 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); 1579 } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) 1580 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))) 1581 { 1582 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1583 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1584 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); 1585 } 1586 } 1587 1588 #if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) 1589 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, 1590 HEADER_TYPE_UDP_LITE)) 1591 { 1592 /* link to sw parser code for udp lite - only if no other code is applied. */ 1593 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1594 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1595 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL); 1596 } 1597 #endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ 1598 for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++) 1599 { 1600 /* For all header set LCV as taken from netEnv*/ 1601 WRITE_UINT32( 1602 p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv, 1603 FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i)); 1604 /* set HXS register according to default+Additional params+protocol options */ 1605 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach, 1606 tmpHxs[i]); 1607 } 1608 1609 /* set tpid. */ 1610 tmpReg = PRS_TPID_DFLT; 1611 if (p_PcdParams->p_PrsParams->setVlanTpid1) 1612 { 1613 tmpReg &= PRS_TPID2_MASK; 1614 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1 1615 << PRS_PCTPID_SHIFT; 1616 } 1617 if (p_PcdParams->p_PrsParams->setVlanTpid2) 1618 { 1619 tmpReg &= PRS_TPID1_MASK; 1620 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2; 1621 }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg); 1622 1623 /* enable parser */ 1624 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0); 1625 1626 if (p_PcdParams->p_PrsParams->prsResultPrivateInfo) 1627 p_FmPort->privateInfo = 1628 p_PcdParams->p_PrsParams->prsResultPrivateInfo; 1629 1630 } /* end parser */ 1631 else { 1632 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) 1633 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1634 { 1635 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1636 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach, 1637 (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL)); 1638 } 1639 1640 WRITE_UINT32(*p_BmiPrsStartOffset, 0); 1641 1642 p_FmPort->privateInfo = 0; 1643 } 1644 1645 FmPortCheckNApplyMacsec(p_FmPort); 1646 1647 WRITE_UINT32( 1648 *p_BmiPrsStartOffset, 1649 GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset); 1650 1651 /* set initial parser result - used for all engines */ 1652 for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++) 1653 { 1654 if (!i) 1655 WRITE_UINT32( 1656 *(p_BmiInitPrsResult), 1657 (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH)); 1658 else 1659 { 1660 if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2) 1661 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH); 1662 else 1663 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW); 1664 } 1665 } 1666 1667 return E_OK; 1668 } 1669 1670 static t_Error DeletePcd(t_FmPort *p_FmPort) 1671 { 1672 t_Error err = E_OK; 1673 volatile uint32_t *p_BmiNia = NULL; 1674 volatile uint32_t *p_BmiPrsStartOffset = NULL; 1675 1676 ASSERT_COND(p_FmPort); 1677 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1678 1679 if (p_FmPort->imEn) 1680 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1681 ("available for non-independant mode ports only")); 1682 1683 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 1684 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 1685 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1686 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 1687 ("available for Rx and offline parsing ports only")); 1688 1689 if (!p_FmPort->pcdEngines) 1690 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port")); 1691 1692 /* get PCD registers pointers */ 1693 switch (p_FmPort->portType) 1694 { 1695 case (e_FM_PORT_TYPE_RX_10G): 1696 case (e_FM_PORT_TYPE_RX): 1697 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1698 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; 1699 break; 1700 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1701 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1702 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; 1703 break; 1704 default: 1705 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 1706 } 1707 1708 if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) 1709 != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) 1710 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1711 ("port has to be detached previousely")); 1712 1713 WRITE_UINT32(*p_BmiPrsStartOffset, 0); 1714 1715 /* "cut" PCD out of the port's flow - go to BMI */ 1716 /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */ 1717 1718 if (p_FmPort->pcdEngines & FM_PCD_PRS) 1719 { 1720 /* stop parser */ 1721 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); 1722 /* wait for parser to be in idle state */ 1723 while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) 1724 ; 1725 } 1726 1727 if (p_FmPort->pcdEngines & FM_PCD_KG) 1728 { 1729 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 1730 1731 /* unbind all schemes */ 1732 p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort, 1733 &schemeBind); 1734 1735 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 1736 if (err) 1737 RETURN_ERROR(MAJOR, err, NO_MSG); 1738 1739 err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, 1740 p_FmPort->hardwarePortId, 1741 p_FmPort->clsPlanGrpId); 1742 if (err) 1743 RETURN_ERROR(MAJOR, err, NO_MSG); 1744 p_FmPort->useClsPlan = FALSE; 1745 } 1746 1747 if (p_FmPort->pcdEngines & FM_PCD_CC) 1748 { 1749 /* unbind - we need to get the treeId too */ 1750 err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId); 1751 if (err) 1752 RETURN_ERROR(MAJOR, err, NO_MSG); 1753 } 1754 1755 p_FmPort->pcdEngines = 0; 1756 1757 return E_OK; 1758 } 1759 1760 static t_Error AttachPCD(t_FmPort *p_FmPort) 1761 { 1762 volatile uint32_t *p_BmiNia = NULL; 1763 1764 ASSERT_COND(p_FmPort); 1765 1766 /* get PCD registers pointers */ 1767 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1768 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1769 else 1770 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1771 1772 /* check that current NIA is BMI to BMI */ 1773 if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) 1774 != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) 1775 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 1776 ("may be called only for ports in BMI-to-BMI state.")); 1777 1778 if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) 1779 if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1, 1780 p_FmPort->orFmanCtrl) != E_OK) 1781 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 1782 1783 if (p_FmPort->requiredAction & UPDATE_NIA_CMNE) 1784 { 1785 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1786 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne, 1787 p_FmPort->savedBmiCmne); 1788 else 1789 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne, 1790 p_FmPort->savedBmiCmne); 1791 } 1792 1793 if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) 1794 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, 1795 p_FmPort->savedQmiPnen); 1796 1797 if (p_FmPort->requiredAction & UPDATE_NIA_FENE) 1798 { 1799 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1800 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, 1801 p_FmPort->savedBmiFene); 1802 else 1803 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, 1804 p_FmPort->savedBmiFene); 1805 } 1806 1807 if (p_FmPort->requiredAction & UPDATE_NIA_FPNE) 1808 { 1809 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1810 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne, 1811 p_FmPort->savedBmiFpne); 1812 else 1813 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne, 1814 p_FmPort->savedBmiFpne); 1815 } 1816 1817 if (p_FmPort->requiredAction & UPDATE_OFP_DPTE) 1818 { 1819 ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING); 1820 1821 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp, 1822 p_FmPort->savedBmiOfp); 1823 } 1824 1825 WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia); 1826 1827 if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) 1828 { 1829 p_FmPort->origNonRxQmiRegsPndn = 1830 GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn); 1831 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, 1832 p_FmPort->savedNonRxQmiRegsPndn); 1833 } 1834 1835 return E_OK; 1836 } 1837 1838 static t_Error DetachPCD(t_FmPort *p_FmPort) 1839 { 1840 volatile uint32_t *p_BmiNia = NULL; 1841 1842 ASSERT_COND(p_FmPort); 1843 1844 /* get PCD registers pointers */ 1845 if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) 1846 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, 1847 p_FmPort->origNonRxQmiRegsPndn); 1848 1849 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1850 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1851 else 1852 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1853 1854 WRITE_UINT32( 1855 *p_BmiNia, 1856 (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()); 1857 1858 if (FmPcdGetHcHandle(p_FmPort->h_FmPcd)) 1859 FmPcdHcSync(p_FmPort->h_FmPcd); 1860 1861 if (p_FmPort->requiredAction & UPDATE_NIA_FENE) 1862 { 1863 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1864 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, 1865 NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); 1866 else 1867 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, 1868 NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); 1869 } 1870 1871 if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) 1872 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen, 1873 NIA_ENG_BMI | NIA_BMI_AC_RELEASE); 1874 1875 if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) 1876 if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2, 1877 p_FmPort->orFmanCtrl) != E_OK) 1878 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 1879 1880 p_FmPort->requiredAction = 0; 1881 1882 return E_OK; 1883 } 1884 1885 /*****************************************************************************/ 1886 /* Inter-module API routines */ 1887 /*****************************************************************************/ 1888 void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci) 1889 { 1890 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1891 volatile uint32_t *p_BmiCfgReg = NULL; 1892 uint32_t tmpReg; 1893 1894 SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); 1895 SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1896 1897 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) 1898 && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 1899 { 1900 REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only")); 1901 return; 1902 } 1903 1904 p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca; 1905 tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK; 1906 tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED; 1907 tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT) 1908 & BMI_CMD_ATTR_MACCMD_SC_MASK); 1909 1910 WRITE_UINT32(*p_BmiCfgReg, tmpReg); 1911 } 1912 1913 uint8_t FmPortGetNetEnvId(t_Handle h_FmPort) 1914 { 1915 return ((t_FmPort*)h_FmPort)->netEnvId; 1916 } 1917 1918 uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort) 1919 { 1920 return ((t_FmPort*)h_FmPort)->hardwarePortId; 1921 } 1922 1923 uint32_t FmPortGetPcdEngines(t_Handle h_FmPort) 1924 { 1925 return ((t_FmPort*)h_FmPort)->pcdEngines; 1926 } 1927 1928 #if (DPAA_VERSION >= 11) 1929 t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, 1930 void **p_Value) 1931 { 1932 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1933 uint32_t muramPageOffset; 1934 1935 ASSERT_COND(p_FmPort); 1936 ASSERT_COND(p_Value); 1937 1938 if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY) 1939 { 1940 if (p_FmPort->gprFunc != gprFunc) 1941 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1942 ("gpr was assigned with different func")); 1943 } 1944 else 1945 { 1946 switch (gprFunc) 1947 { 1948 case (e_FM_PORT_GPR_MURAM_PAGE): 1949 p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, 1950 256, 8); 1951 if (!p_FmPort->p_ParamsPage) 1952 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page")); 1953 1954 IOMemSet32(p_FmPort->p_ParamsPage, 0, 256); 1955 muramPageOffset = 1956 (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage) 1957 - p_FmPort->fmMuramPhysBaseAddr); 1958 switch (p_FmPort->portType) 1959 { 1960 case (e_FM_PORT_TYPE_RX_10G): 1961 case (e_FM_PORT_TYPE_RX): 1962 WRITE_UINT32( 1963 p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr, 1964 muramPageOffset); 1965 break; 1966 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1967 WRITE_UINT32( 1968 p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr, 1969 muramPageOffset); 1970 break; 1971 default: 1972 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1973 ("Invalid port type")); 1974 } 1975 break; 1976 default: 1977 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1978 } 1979 p_FmPort->gprFunc = gprFunc; 1980 } 1981 1982 switch (p_FmPort->gprFunc) 1983 { 1984 case (e_FM_PORT_GPR_MURAM_PAGE): 1985 *p_Value = p_FmPort->p_ParamsPage; 1986 break; 1987 default: 1988 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1989 } 1990 1991 return E_OK; 1992 } 1993 #endif /* (DPAA_VERSION >= 11) */ 1994 1995 t_Error FmPortGetSetCcParams(t_Handle h_FmPort, 1996 t_FmPortGetSetCcParams *p_CcParams) 1997 { 1998 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1999 uint32_t tmpInt; 2000 volatile uint32_t *p_BmiPrsStartOffset = NULL; 2001 2002 /* this function called from Cc for pass and receive parameters port params between CC and PORT*/ 2003 2004 if ((p_CcParams->getCcParams.type & OFFSET_OF_PR) 2005 && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE)) 2006 { 2007 p_CcParams->getCcParams.prOffset = 2008 (uint8_t)p_FmPort->bufferOffsets.prsResultOffset; 2009 p_CcParams->getCcParams.type &= ~OFFSET_OF_PR; 2010 } 2011 if (p_CcParams->getCcParams.type & HW_PORT_ID) 2012 { 2013 p_CcParams->getCcParams.hardwarePortId = 2014 (uint8_t)p_FmPort->hardwarePortId; 2015 p_CcParams->getCcParams.type &= ~HW_PORT_ID; 2016 } 2017 if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA) 2018 && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE)) 2019 { 2020 p_CcParams->getCcParams.dataOffset = 2021 (uint16_t)p_FmPort->bufferOffsets.dataOffset; 2022 p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA; 2023 } 2024 if (p_CcParams->getCcParams.type & NUM_OF_TASKS) 2025 { 2026 p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; 2027 p_CcParams->getCcParams.type &= ~NUM_OF_TASKS; 2028 } 2029 if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS) 2030 { 2031 p_CcParams->getCcParams.numOfExtraTasks = 2032 (uint8_t)p_FmPort->tasks.extra; 2033 p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS; 2034 } 2035 if (p_CcParams->getCcParams.type & FM_REV) 2036 { 2037 p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev; 2038 p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev; 2039 p_CcParams->getCcParams.type &= ~FM_REV; 2040 } 2041 if (p_CcParams->getCcParams.type & DISCARD_MASK) 2042 { 2043 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2044 p_CcParams->getCcParams.discardMask = 2045 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm); 2046 else 2047 p_CcParams->getCcParams.discardMask = 2048 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm); 2049 p_CcParams->getCcParams.type &= ~DISCARD_MASK; 2050 } 2051 if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE) 2052 { 2053 p_CcParams->getCcParams.internalBufferOffset = 2054 p_FmPort->internalBufferOffset; 2055 p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE; 2056 } 2057 if (p_CcParams->getCcParams.type & GET_NIA_FPNE) 2058 { 2059 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2060 p_CcParams->getCcParams.nia = 2061 GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne); 2062 else 2063 p_CcParams->getCcParams.nia = 2064 GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne); 2065 p_CcParams->getCcParams.type &= ~GET_NIA_FPNE; 2066 } 2067 if (p_CcParams->getCcParams.type & GET_NIA_PNDN) 2068 { 2069 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2070 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2071 p_CcParams->getCcParams.nia = 2072 GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn); 2073 p_CcParams->getCcParams.type &= ~GET_NIA_PNDN; 2074 } 2075 2076 if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) 2077 && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)) 2078 { 2079 p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; 2080 p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl; 2081 } 2082 2083 if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) 2084 && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN)) 2085 { 2086 p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia; 2087 p_FmPort->requiredAction |= UPDATE_NIA_PNEN; 2088 } 2089 else 2090 if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) 2091 { 2092 if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia) 2093 RETURN_ERROR(MAJOR, E_INVALID_STATE, 2094 ("PNEN was defined previously different")); 2095 } 2096 2097 if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) 2098 && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN)) 2099 { 2100 p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia; 2101 p_FmPort->requiredAction |= UPDATE_NIA_PNDN; 2102 } 2103 else 2104 if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) 2105 { 2106 if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia) 2107 RETURN_ERROR(MAJOR, E_INVALID_STATE, 2108 ("PNDN was defined previously different")); 2109 } 2110 2111 if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE) 2112 && (p_CcParams->setCcParams.overwrite 2113 || !(p_FmPort->requiredAction & UPDATE_NIA_FENE))) 2114 { 2115 p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia; 2116 p_FmPort->requiredAction |= UPDATE_NIA_FENE; 2117 } 2118 else 2119 if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE) 2120 { 2121 if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia) 2122 RETURN_ERROR( MAJOR, E_INVALID_STATE, 2123 ("xFENE was defined previously different")); 2124 } 2125 2126 if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE) 2127 && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE)) 2128 { 2129 p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia; 2130 p_FmPort->requiredAction |= UPDATE_NIA_FPNE; 2131 } 2132 else 2133 if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE) 2134 { 2135 if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia) 2136 RETURN_ERROR( MAJOR, E_INVALID_STATE, 2137 ("xFPNE was defined previously different")); 2138 } 2139 2140 if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE) 2141 && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE)) 2142 { 2143 p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia; 2144 p_FmPort->requiredAction |= UPDATE_NIA_CMNE; 2145 } 2146 else 2147 if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE) 2148 { 2149 if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia) 2150 RETURN_ERROR( MAJOR, E_INVALID_STATE, 2151 ("xCMNE was defined previously different")); 2152 } 2153 2154 if ((p_CcParams->setCcParams.type & UPDATE_PSO) 2155 && !(p_FmPort->requiredAction & UPDATE_PSO)) 2156 { 2157 /* get PCD registers pointers */ 2158 switch (p_FmPort->portType) 2159 { 2160 case (e_FM_PORT_TYPE_RX_10G): 2161 case (e_FM_PORT_TYPE_RX): 2162 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; 2163 break; 2164 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2165 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; 2166 break; 2167 default: 2168 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2169 } 2170 2171 /* set start parsing offset */ 2172 tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset) 2173 + p_CcParams->setCcParams.psoSize; 2174 if (tmpInt > 0) 2175 WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt); 2176 2177 p_FmPort->requiredAction |= UPDATE_PSO; 2178 p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize; 2179 } 2180 else 2181 if (p_CcParams->setCcParams.type & UPDATE_PSO) 2182 { 2183 if (p_FmPort->savedPrsStartOffset 2184 != p_CcParams->setCcParams.psoSize) 2185 RETURN_ERROR( 2186 MAJOR, 2187 E_INVALID_STATE, 2188 ("parser start offset was defoned previousley different")); 2189 } 2190 2191 if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE) 2192 && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE)) 2193 { 2194 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2195 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2196 p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp); 2197 p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK; 2198 p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde 2199 << BMI_FIFO_PIPELINE_DEPTH_SHIFT; 2200 p_FmPort->requiredAction |= UPDATE_OFP_DPTE; 2201 } 2202 2203 return E_OK; 2204 } 2205 /*********************** End of inter-module routines ************************/ 2206 2207 /****************************************/ 2208 /* API Init unit functions */ 2209 /****************************************/ 2210 2211 t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) 2212 { 2213 t_FmPort *p_FmPort; 2214 uintptr_t baseAddr = p_FmPortParams->baseAddr; 2215 uint32_t tmpReg; 2216 2217 /* Allocate FM structure */ 2218 p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort)); 2219 if (!p_FmPort) 2220 { 2221 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure")); 2222 return NULL; 2223 } 2224 memset(p_FmPort, 0, sizeof(t_FmPort)); 2225 2226 /* Allocate the FM driver's parameters structure */ 2227 p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc( 2228 sizeof(t_FmPortDriverParam)); 2229 if (!p_FmPort->p_FmPortDriverParam) 2230 { 2231 XX_Free(p_FmPort); 2232 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters")); 2233 return NULL; 2234 } 2235 memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam)); 2236 2237 /* Initialize FM port parameters which will be kept by the driver */ 2238 p_FmPort->portType = p_FmPortParams->portType; 2239 p_FmPort->portId = p_FmPortParams->portId; 2240 p_FmPort->pcdEngines = FM_PCD_NONE; 2241 p_FmPort->f_Exception = p_FmPortParams->f_Exception; 2242 p_FmPort->h_App = p_FmPortParams->h_App; 2243 p_FmPort->h_Fm = p_FmPortParams->h_Fm; 2244 2245 /* get FM revision */ 2246 FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo); 2247 2248 /* calculate global portId number */ 2249 p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType, 2250 p_FmPortParams->portId, 2251 p_FmPort->fmRevInfo.majorRev, 2252 p_FmPort->fmRevInfo.minorRev); 2253 2254 if (p_FmPort->fmRevInfo.majorRev >= 6) 2255 { 2256 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 2257 && (p_FmPortParams->portId != FM_OH_PORT_ID)) 2258 DBG(WARNING, 2259 ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.", 2260 FM_OH_PORT_ID)); 2261 2262 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2263 && (p_FmPortParams->portId == FM_OH_PORT_ID)) 2264 DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0.")); 2265 } 2266 2267 /* Set up FM port parameters for initialization phase only */ 2268 2269 /* First, fill in flibs struct */ 2270 fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg, 2271 (enum fman_port_type)p_FmPort->portType); 2272 /* Overwrite some integration specific parameters */ 2273 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = 2274 DEFAULT_PORT_rxFifoPriElevationLevel; 2275 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = 2276 DEFAULT_PORT_rxFifoThreshold; 2277 2278 #if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006) 2279 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE; 2280 #else 2281 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE; 2282 #endif 2283 if ((p_FmPort->fmRevInfo.majorRev == 6) 2284 && (p_FmPort->fmRevInfo.minorRev == 0)) 2285 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE; 2286 else 2287 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE; 2288 2289 /* Excessive Threshold register - exists for pre-FMv3 chips only */ 2290 if (p_FmPort->fmRevInfo.majorRev < 6) 2291 { 2292 #ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC 2293 p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register = 2294 TRUE; 2295 #endif 2296 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE; 2297 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE; 2298 } 2299 else 2300 { 2301 p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register = 2302 FALSE; 2303 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE; 2304 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE; 2305 } 2306 if (p_FmPort->fmRevInfo.majorRev == 4) 2307 p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE; 2308 else 2309 p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE; 2310 2311 /* Continue with other parameters */ 2312 p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr; 2313 /* set memory map pointers */ 2314 p_FmPort->p_FmPortQmiRegs = 2315 (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET); 2316 p_FmPort->p_FmPortBmiRegs = 2317 (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET); 2318 p_FmPort->p_FmPortPrsRegs = 2319 (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET); 2320 2321 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize = 2322 DEFAULT_PORT_bufferPrefixContent_privDataSize; 2323 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult = 2324 DEFAULT_PORT_bufferPrefixContent_passPrsResult; 2325 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp = 2326 DEFAULT_PORT_bufferPrefixContent_passTimeStamp; 2327 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo = 2328 DEFAULT_PORT_bufferPrefixContent_passTimeStamp; 2329 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = 2330 DEFAULT_PORT_bufferPrefixContent_dataAlign; 2331 /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData; 2332 p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr; 2333 p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr; 2334 p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr; 2335 p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize; 2336 */ 2337 p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase; 2338 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = 2339 DEFAULT_PORT_cheksumLastBytesIgnore; 2340 2341 p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength; 2342 /* resource distribution. */ 2343 p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType) 2344 * BMI_FIFO_UNITS; 2345 p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs 2346 * BMI_FIFO_UNITS; 2347 p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType); 2348 p_FmPort->openDmas.extra = 2349 DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType); 2350 p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType); 2351 p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType); 2352 2353 2354 #ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 2355 if ((p_FmPort->fmRevInfo.majorRev == 6) 2356 && (p_FmPort->fmRevInfo.minorRev == 0) 2357 && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2358 || (p_FmPort->portType == e_FM_PORT_TYPE_TX))) 2359 { 2360 p_FmPort->openDmas.num = 16; 2361 p_FmPort->openDmas.extra = 0; 2362 } 2363 #endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */ 2364 2365 /* Port type specific initialization: */ 2366 switch (p_FmPort->portType) 2367 { 2368 case (e_FM_PORT_TYPE_RX): 2369 case (e_FM_PORT_TYPE_RX_10G): 2370 /* Initialize FM port parameters for initialization phase only */ 2371 p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = 2372 DEFAULT_PORT_cutBytesFromEnd; 2373 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE; 2374 p_FmPort->p_FmPortDriverParam->frmDiscardOverride = 2375 DEFAULT_PORT_frmDiscardOverride; 2376 2377 tmpReg = 2378 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp); 2379 p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = 2380 (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK) 2381 >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1) 2382 * BMI_FIFO_UNITS; 2383 p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg 2384 & BMI_RX_FIFO_THRESHOLD_MASK) 2385 >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS; 2386 2387 p_FmPort->p_FmPortDriverParam->bufMargins.endMargins = 2388 DEFAULT_PORT_BufMargins_endMargins; 2389 p_FmPort->p_FmPortDriverParam->errorsToDiscard = 2390 DEFAULT_PORT_errorsToDiscard; 2391 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = 2392 DEFAULT_PORT_forwardIntContextReuse; 2393 #if (DPAA_VERSION >= 11) 2394 p_FmPort->p_FmPortDriverParam->noScatherGather = 2395 DEFAULT_PORT_noScatherGather; 2396 #endif /* (DPAA_VERSION >= 11) */ 2397 break; 2398 2399 case (e_FM_PORT_TYPE_TX): 2400 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE; 2401 #ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 2402 tmpReg = 0x00001013; 2403 WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp, 2404 tmpReg); 2405 #endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */ 2406 case (e_FM_PORT_TYPE_TX_10G): 2407 tmpReg = 2408 GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp); 2409 p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg 2410 & BMI_TX_FIFO_MIN_FILL_MASK) 2411 >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS; 2412 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = 2413 (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK) 2414 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1); 2415 p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg 2416 & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1) 2417 * BMI_FIFO_UNITS; 2418 2419 p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; 2420 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = 2421 DEFAULT_PORT_deqPrefetchOption; 2422 p_FmPort->p_FmPortDriverParam->deqHighPriority = 2423 (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G : 2424 DEFAULT_PORT_deqHighPriority_10G); 2425 p_FmPort->p_FmPortDriverParam->deqByteCnt = 2426 (uint16_t)( 2427 (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G : 2428 DEFAULT_PORT_deqByteCnt_10G); 2429 break; 2430 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2431 p_FmPort->p_FmPortDriverParam->errorsToDiscard = 2432 DEFAULT_PORT_errorsToDiscard; 2433 #if (DPAA_VERSION >= 11) 2434 p_FmPort->p_FmPortDriverParam->noScatherGather = 2435 DEFAULT_PORT_noScatherGather; 2436 #endif /* (DPAA_VERSION >= 11) */ 2437 case (e_FM_PORT_TYPE_OH_HOST_COMMAND): 2438 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = 2439 DEFAULT_PORT_deqPrefetchOption_HC; 2440 p_FmPort->p_FmPortDriverParam->deqHighPriority = 2441 DEFAULT_PORT_deqHighPriority_1G; 2442 p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; 2443 p_FmPort->p_FmPortDriverParam->deqByteCnt = 2444 DEFAULT_PORT_deqByteCnt_1G; 2445 2446 tmpReg = 2447 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp); 2448 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = 2449 (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK) 2450 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1); 2451 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 2452 && (p_FmPortParams->portId != FM_OH_PORT_ID)) 2453 { 2454 /* Overwrite HC defaults */ 2455 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = 2456 DEFAULT_PORT_fifoDeqPipelineDepth_OH; 2457 } 2458 2459 #ifndef FM_FRAME_END_PARAMS_FOR_OP 2460 if (p_FmPort->fmRevInfo.majorRev < 6) 2461 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported; 2462 #endif /* !FM_FRAME_END_PARAMS_FOR_OP */ 2463 2464 #ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP 2465 if (!((p_FmPort->fmRevInfo.majorRev == 4) || 2466 (p_FmPort->fmRevInfo.majorRev >= 6))) 2467 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported; 2468 #endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ 2469 break; 2470 2471 default: 2472 XX_Free(p_FmPort->p_FmPortDriverParam); 2473 XX_Free(p_FmPort); 2474 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2475 return NULL; 2476 } 2477 #ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT 2478 if (p_FmPort->fmRevInfo.majorRev == 4) 2479 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported; 2480 #endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ 2481 2482 p_FmPort->imEn = p_FmPortParams->independentModeEnable; 2483 2484 if (p_FmPort->imEn) 2485 { 2486 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 2487 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) 2488 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = 2489 DEFAULT_PORT_fifoDeqPipelineDepth_IM; 2490 FmPortConfigIM(p_FmPort, p_FmPortParams); 2491 } 2492 else 2493 { 2494 switch (p_FmPort->portType) 2495 { 2496 case (e_FM_PORT_TYPE_RX): 2497 case (e_FM_PORT_TYPE_RX_10G): 2498 /* Initialize FM port parameters for initialization phase only */ 2499 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, 2500 &p_FmPortParams->specificParams.rxParams.extBufPools, 2501 sizeof(t_FmExtPools)); 2502 p_FmPort->p_FmPortDriverParam->errFqid = 2503 p_FmPortParams->specificParams.rxParams.errFqid; 2504 p_FmPort->p_FmPortDriverParam->dfltFqid = 2505 p_FmPortParams->specificParams.rxParams.dfltFqid; 2506 p_FmPort->p_FmPortDriverParam->liodnOffset = 2507 p_FmPortParams->specificParams.rxParams.liodnOffset; 2508 break; 2509 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2510 case (e_FM_PORT_TYPE_TX): 2511 case (e_FM_PORT_TYPE_TX_10G): 2512 case (e_FM_PORT_TYPE_OH_HOST_COMMAND): 2513 p_FmPort->p_FmPortDriverParam->errFqid = 2514 p_FmPortParams->specificParams.nonRxParams.errFqid; 2515 p_FmPort->p_FmPortDriverParam->deqSubPortal = 2516 (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel 2517 & QMI_DEQ_CFG_SUBPORTAL_MASK); 2518 p_FmPort->p_FmPortDriverParam->dfltFqid = 2519 p_FmPortParams->specificParams.nonRxParams.dfltFqid; 2520 break; 2521 default: 2522 XX_Free(p_FmPort->p_FmPortDriverParam); 2523 XX_Free(p_FmPort); 2524 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2525 return NULL; 2526 } 2527 } 2528 2529 memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE); 2530 if (Sprint( 2531 p_FmPort->name, 2532 "FM-%d-port-%s-%d", 2533 FmGetId(p_FmPort->h_Fm), 2534 ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING 2535 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" : 2536 (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" : 2537 (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" : 2538 (p_FmPort->portType 2539 == e_FM_PORT_TYPE_RX_10G ? "10g-RX" : 2540 "10g-TX")))), 2541 p_FmPort->portId) == 0) 2542 { 2543 XX_Free(p_FmPort->p_FmPortDriverParam); 2544 XX_Free(p_FmPort); 2545 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 2546 return NULL; 2547 } 2548 2549 p_FmPort->h_Spinlock = XX_InitSpinlock(); 2550 if (!p_FmPort->h_Spinlock) 2551 { 2552 XX_Free(p_FmPort->p_FmPortDriverParam); 2553 XX_Free(p_FmPort); 2554 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 2555 return NULL; 2556 } 2557 2558 return p_FmPort; 2559 } 2560 2561 t_FmPort *rx_port = 0; 2562 t_FmPort *tx_port = 0; 2563 2564 /**************************************************************************//** 2565 @Function FM_PORT_Init 2566 2567 @Description Initializes the FM module 2568 2569 @Param[in] h_FmPort - FM module descriptor 2570 2571 @Return E_OK on success; Error code otherwise. 2572 *//***************************************************************************/ 2573 t_Error FM_PORT_Init(t_Handle h_FmPort) 2574 { 2575 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2576 t_FmPortDriverParam *p_DriverParams; 2577 t_Error errCode; 2578 t_FmInterModulePortInitParams fmParams; 2579 t_FmRevisionInfo revInfo; 2580 2581 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 2582 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2583 2584 errCode = FmSpBuildBufferStructure( 2585 &p_FmPort->p_FmPortDriverParam->intContext, 2586 &p_FmPort->p_FmPortDriverParam->bufferPrefixContent, 2587 &p_FmPort->p_FmPortDriverParam->bufMargins, 2588 &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset); 2589 if (errCode != E_OK) 2590 RETURN_ERROR(MAJOR, errCode, NO_MSG); 2591 #ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 2592 if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) && 2593 (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2594 { 2595 p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL; 2596 if (!p_FmPort->fifoBufs.num) 2597 p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS; 2598 p_FmPort->fifoBufs.num += 4*KILOBYTE; 2599 } 2600 #endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ 2601 2602 CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters); 2603 2604 p_DriverParams = p_FmPort->p_FmPortDriverParam; 2605 2606 /* Set up flibs port structure */ 2607 memset(&p_FmPort->port, 0, sizeof(struct fman_port)); 2608 p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType; 2609 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2610 p_FmPort->port.fm_rev_maj = revInfo.majorRev; 2611 p_FmPort->port.fm_rev_min = revInfo.minorRev; 2612 p_FmPort->port.bmi_regs = 2613 (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET); 2614 p_FmPort->port.qmi_regs = 2615 (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET); 2616 p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8); 2617 p_FmPort->port.im_en = p_FmPort->imEn; 2618 p_FmPort->p_FmPortPrsRegs = 2619 (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET); 2620 2621 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 2622 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn) 2623 { 2624 /* Call the external Buffer routine which also checks fifo 2625 size and updates it if necessary */ 2626 /* define external buffer pools and pool depletion*/ 2627 errCode = SetExtBufferPools(p_FmPort); 2628 if (errCode) 2629 RETURN_ERROR(MAJOR, errCode, NO_MSG); 2630 /* check if the largest external buffer pool is large enough */ 2631 if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE 2632 + p_DriverParams->bufMargins.endMargins 2633 > p_FmPort->rxPoolsParams.largestBufSize) 2634 RETURN_ERROR( 2635 MAJOR, 2636 E_INVALID_VALUE, 2637 ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", p_DriverParams->bufMargins.startMargins, p_DriverParams->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize)); 2638 } 2639 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2640 { 2641 { 2642 #ifdef FM_NO_OP_OBSERVED_POOLS 2643 t_FmRevisionInfo revInfo; 2644 2645 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2646 if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion)) 2647 #endif /* FM_NO_OP_OBSERVED_POOLS */ 2648 { 2649 /* define external buffer pools */ 2650 errCode = SetExtBufferPools(p_FmPort); 2651 if (errCode) 2652 RETURN_ERROR(MAJOR, errCode, NO_MSG); 2653 } 2654 } 2655 } 2656 2657 /************************************************************/ 2658 /* Call FM module routine for communicating parameters */ 2659 /************************************************************/ 2660 memset(&fmParams, 0, sizeof(fmParams)); 2661 fmParams.hardwarePortId = p_FmPort->hardwarePortId; 2662 fmParams.portType = (e_FmPortType)p_FmPort->portType; 2663 fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; 2664 fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra; 2665 fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num; 2666 fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra; 2667 2668 if (p_FmPort->fifoBufs.num) 2669 { 2670 errCode = VerifySizeOfFifo(p_FmPort); 2671 if (errCode != E_OK) 2672 RETURN_ERROR(MAJOR, errCode, NO_MSG); 2673 } 2674 fmParams.sizeOfFifo = p_FmPort->fifoBufs.num; 2675 fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra; 2676 fmParams.independentMode = p_FmPort->imEn; 2677 fmParams.liodnOffset = p_DriverParams->liodnOffset; 2678 fmParams.liodnBase = p_DriverParams->liodnBase; 2679 fmParams.deqPipelineDepth = 2680 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth; 2681 fmParams.maxFrameLength = p_FmPort->maxFrameLength; 2682 #ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP 2683 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || 2684 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 2685 { 2686 if (!((p_FmPort->fmRevInfo.majorRev == 4) || 2687 (p_FmPort->fmRevInfo.majorRev >= 6))) 2688 /* HC ports do not have fifoDeqPipelineDepth, but it is needed only 2689 * for deq threshold calculation. 2690 */ 2691 fmParams.deqPipelineDepth = 2; 2692 } 2693 #endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ 2694 2695 errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams); 2696 if (errCode) 2697 RETURN_ERROR(MAJOR, errCode, NO_MSG); 2698 2699 /* get params for use in init */ 2700 p_FmPort->fmMuramPhysBaseAddr = 2701 (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low) 2702 | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32)); 2703 p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm); 2704 2705 errCode = InitLowLevelDriver(p_FmPort); 2706 if (errCode != E_OK) 2707 RETURN_ERROR(MAJOR, errCode, NO_MSG); 2708 2709 FmPortDriverParamFree(p_FmPort); 2710 2711 #if (DPAA_VERSION >= 11) 2712 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 2713 || (p_FmPort->portType == e_FM_PORT_TYPE_RX) 2714 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 2715 { 2716 t_FmPcdCtrlParamsPage *p_ParamsPage; 2717 2718 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, 2719 (void**)&p_ParamsPage); 2720 ASSERT_COND(p_ParamsPage); 2721 2722 WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON); 2723 #ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 2724 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2725 { 2726 WRITE_UINT32( 2727 p_ParamsPage->misc, 2728 (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN)); 2729 WRITE_UINT32( 2730 p_ParamsPage->discardMask, 2731 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm)); 2732 } 2733 #endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */ 2734 #ifdef FM_ERROR_VSP_NO_MATCH_SW006 2735 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2736 WRITE_UINT32( 2737 p_ParamsPage->errorsDiscardMask, 2738 (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem))); 2739 else 2740 WRITE_UINT32( 2741 p_ParamsPage->errorsDiscardMask, 2742 (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem))); 2743 #endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ 2744 } 2745 #endif /* (DPAA_VERSION >= 11) */ 2746 2747 if (p_FmPort->deepSleepVars.autoResMaxSizes) 2748 FmPortConfigAutoResForDeepSleepSupport1(p_FmPort); 2749 return E_OK; 2750 } 2751 2752 /**************************************************************************//** 2753 @Function FM_PORT_Free 2754 2755 @Description Frees all resources that were assigned to FM module. 2756 2757 Calling this routine invalidates the descriptor. 2758 2759 @Param[in] h_FmPort - FM module descriptor 2760 2761 @Return E_OK on success; Error code otherwise. 2762 *//***************************************************************************/ 2763 t_Error FM_PORT_Free(t_Handle h_FmPort) 2764 { 2765 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2766 t_FmInterModulePortFreeParams fmParams; 2767 2768 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2769 2770 if (p_FmPort->pcdEngines) 2771 RETURN_ERROR( 2772 MAJOR, 2773 E_INVALID_STATE, 2774 ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first.")); 2775 2776 if (p_FmPort->enabled) 2777 { 2778 if (FM_PORT_Disable(p_FmPort) != E_OK) 2779 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED")); 2780 } 2781 2782 if (p_FmPort->imEn) 2783 FmPortImFree(p_FmPort); 2784 2785 FmPortDriverParamFree(p_FmPort); 2786 2787 memset(&fmParams, 0, sizeof(fmParams)); 2788 fmParams.hardwarePortId = p_FmPort->hardwarePortId; 2789 fmParams.portType = (e_FmPortType)p_FmPort->portType; 2790 fmParams.deqPipelineDepth = 2791 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth; 2792 2793 FmFreePortParams(p_FmPort->h_Fm, &fmParams); 2794 2795 #if (DPAA_VERSION >= 11) 2796 if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId) 2797 != E_OK) 2798 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED")); 2799 2800 if (p_FmPort->p_ParamsPage) 2801 FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage); 2802 #endif /* (DPAA_VERSION >= 11) */ 2803 2804 if (p_FmPort->h_Spinlock) 2805 XX_FreeSpinlock(p_FmPort->h_Spinlock); 2806 2807 XX_Free(p_FmPort); 2808 2809 return E_OK; 2810 } 2811 2812 /*************************************************/ 2813 /* API Advanced Init unit functions */ 2814 /*************************************************/ 2815 2816 t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas) 2817 { 2818 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2819 2820 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2821 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2822 2823 p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE; 2824 memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc)); 2825 2826 return E_OK; 2827 } 2828 2829 t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) 2830 { 2831 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2832 2833 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2834 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2835 2836 memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc)); 2837 p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE; 2838 return E_OK; 2839 } 2840 2841 t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo) 2842 { 2843 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2844 2845 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2846 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2847 2848 p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE; 2849 memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc)); 2850 2851 return E_OK; 2852 } 2853 2854 t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri) 2855 { 2856 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2857 2858 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2859 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2860 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 2861 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2862 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports")); 2863 2864 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri; 2865 2866 return E_OK; 2867 } 2868 2869 t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType) 2870 { 2871 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2872 2873 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2874 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2875 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 2876 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2877 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 2878 ("not available for Rx ports")); 2879 2880 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type = 2881 (enum fman_port_deq_type)deqType; 2882 2883 return E_OK; 2884 } 2885 2886 t_Error FM_PORT_ConfigDeqPrefetchOption( 2887 t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption) 2888 { 2889 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2890 2891 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2892 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2893 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 2894 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2895 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 2896 ("not available for Rx ports")); 2897 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt = 2898 (enum fman_port_deq_prefetch)deqPrefetchOption; 2899 2900 return E_OK; 2901 } 2902 2903 t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, 2904 t_FmBackupBmPools *p_BackupBmPools) 2905 { 2906 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2907 2908 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2909 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2910 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 2911 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2912 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 2913 ("available for Rx ports only")); 2914 2915 p_FmPort->p_FmPortDriverParam->p_BackupBmPools = 2916 (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools)); 2917 if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 2918 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed")); 2919 memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools, 2920 sizeof(t_FmBackupBmPools)); 2921 2922 return E_OK; 2923 } 2924 2925 t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt) 2926 { 2927 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2928 2929 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2930 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2931 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 2932 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2933 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 2934 ("not available for Rx ports")); 2935 2936 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt; 2937 2938 return E_OK; 2939 } 2940 2941 t_Error FM_PORT_ConfigBufferPrefixContent( 2942 t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent) 2943 { 2944 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2945 2946 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2947 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2948 2949 memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent, 2950 p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent)); 2951 /* if dataAlign was not initialized by user, we return to driver's default */ 2952 if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign) 2953 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = 2954 DEFAULT_PORT_bufferPrefixContent_dataAlign; 2955 2956 return E_OK; 2957 } 2958 2959 t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, 2960 uint8_t checksumLastBytesIgnore) 2961 { 2962 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2963 2964 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2965 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2966 2967 p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore = 2968 checksumLastBytesIgnore; 2969 2970 return E_OK; 2971 } 2972 2973 t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, 2974 uint8_t cutBytesFromEnd) 2975 { 2976 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2977 2978 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2979 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2980 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 2981 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2982 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 2983 ("available for Rx ports only")); 2984 2985 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd; 2986 2987 return E_OK; 2988 } 2989 2990 t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, 2991 t_FmBufPoolDepletion *p_BufPoolDepletion) 2992 { 2993 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2994 2995 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2996 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2997 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 2998 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2999 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3000 ("available for Rx ports only")); 3001 3002 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; 3003 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion, 3004 sizeof(t_FmBufPoolDepletion)); 3005 3006 return E_OK; 3007 } 3008 3009 t_Error FM_PORT_ConfigObservedPoolDepletion( 3010 t_Handle h_FmPort, 3011 t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion) 3012 { 3013 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3014 3015 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3016 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3017 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 3018 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3019 ("available for OP ports only")); 3020 3021 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; 3022 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, 3023 &p_FmPortObservedBufPoolDepletion->poolDepletionParams, 3024 sizeof(t_FmBufPoolDepletion)); 3025 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, 3026 &p_FmPortObservedBufPoolDepletion->poolsParams, 3027 sizeof(t_FmExtPools)); 3028 3029 return E_OK; 3030 } 3031 3032 t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools) 3033 { 3034 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3035 3036 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3037 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3038 3039 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 3040 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3041 ("available for OP ports only")); 3042 3043 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools, 3044 sizeof(t_FmExtPools)); 3045 3046 return E_OK; 3047 } 3048 3049 t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort) 3050 { 3051 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3052 3053 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3054 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3055 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) 3056 && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 3057 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3058 ("available for Tx ports only")); 3059 3060 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE; 3061 3062 return E_OK; 3063 } 3064 3065 t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color) 3066 { 3067 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3068 3069 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3070 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3071 p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color; 3072 3073 return E_OK; 3074 } 3075 3076 t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq) 3077 { 3078 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3079 3080 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3081 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3082 3083 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 3084 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) 3085 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3086 ("Not available for Tx ports")); 3087 3088 p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq; 3089 3090 return E_OK; 3091 } 3092 3093 t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override) 3094 { 3095 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3096 3097 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3098 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3099 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 3100 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) 3101 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3102 ("Not available for Tx ports")); 3103 3104 p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override; 3105 3106 return E_OK; 3107 } 3108 3109 t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, 3110 fmPortFrameErrSelect_t errs) 3111 { 3112 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3113 3114 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3115 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3116 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 3117 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 3118 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 3119 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 3120 ("available for Rx and offline parsing ports only")); 3121 3122 p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs; 3123 3124 return E_OK; 3125 } 3126 3127 t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData) 3128 { 3129 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3130 3131 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3132 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3133 3134 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data = 3135 (enum fman_port_dma_swap)swapData; 3136 3137 return E_OK; 3138 } 3139 3140 t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, 3141 e_FmDmaCacheOption intContextCacheAttr) 3142 { 3143 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3144 3145 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3146 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3147 3148 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on = 3149 (bool)(intContextCacheAttr == e_FM_DMA_STASH); 3150 3151 return E_OK; 3152 } 3153 3154 t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, 3155 e_FmDmaCacheOption headerCacheAttr) 3156 { 3157 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3158 3159 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3160 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3161 3162 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on = 3163 (bool)(headerCacheAttr == e_FM_DMA_STASH); 3164 3165 return E_OK; 3166 } 3167 3168 t_Error FM_PORT_ConfigDmaScatterGatherAttr( 3169 t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr) 3170 { 3171 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3172 3173 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3174 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3175 3176 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on = 3177 (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH); 3178 3179 return E_OK; 3180 } 3181 3182 t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize) 3183 { 3184 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3185 3186 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3187 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3188 3189 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 3190 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) 3191 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3192 ("Not available for Tx ports")); 3193 3194 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize; 3195 3196 return E_OK; 3197 } 3198 3199 #if (DPAA_VERSION >= 11) 3200 t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather) 3201 { 3202 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3203 3204 UNUSED(noScatherGather); 3205 UNUSED(p_FmPort); 3206 3207 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3208 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3209 3210 p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather; 3211 3212 return E_OK; 3213 } 3214 #endif /* (DPAA_VERSION >= 11) */ 3215 3216 t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, 3217 bool forwardReuse) 3218 { 3219 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3220 3221 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3222 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3223 3224 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 3225 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 3226 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3227 ("available for Rx ports only")); 3228 3229 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse; 3230 3231 return E_OK; 3232 } 3233 3234 t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length) 3235 { 3236 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3237 3238 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3239 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3240 3241 p_FmPort->maxFrameLength = length; 3242 3243 return E_OK; 3244 } 3245 3246 #ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 3247 t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort) 3248 { 3249 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3250 3251 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3252 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3253 3254 p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE; 3255 3256 return E_OK; 3257 } 3258 #endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ 3259 3260 /****************************************************/ 3261 /* Hidden-DEBUG Only API */ 3262 /****************************************************/ 3263 3264 t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, 3265 uint32_t minFillLevel) 3266 { 3267 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3268 3269 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3270 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3271 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) 3272 && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 3273 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3274 ("available for Tx ports only")); 3275 3276 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel; 3277 3278 return E_OK; 3279 } 3280 3281 t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, 3282 uint8_t deqPipelineDepth) 3283 { 3284 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3285 3286 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3287 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3288 3289 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 3290 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 3291 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3292 ("Not available for Rx ports")); 3293 3294 if (p_FmPort->imEn) 3295 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3296 ("Not available for IM ports!")); 3297 3298 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = 3299 deqPipelineDepth; 3300 3301 return E_OK; 3302 } 3303 3304 t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, 3305 uint32_t fifoLowComfLevel) 3306 { 3307 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3308 3309 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3310 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3311 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) 3312 && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 3313 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3314 ("available for Tx ports only")); 3315 3316 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level = 3317 fifoLowComfLevel; 3318 3319 return E_OK; 3320 } 3321 3322 t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold) 3323 { 3324 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3325 3326 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3327 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3328 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 3329 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 3330 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3331 ("available for Rx ports only")); 3332 3333 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold; 3334 3335 return E_OK; 3336 } 3337 3338 t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, 3339 uint32_t priElevationLevel) 3340 { 3341 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3342 3343 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3344 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3345 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 3346 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 3347 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3348 ("available for Rx ports only")); 3349 3350 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel; 3351 3352 return E_OK; 3353 } 3354 /****************************************************/ 3355 /* API Run-time Control unit functions */ 3356 /****************************************************/ 3357 3358 t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, 3359 t_FmPortRsrc *p_NumOfOpenDmas) 3360 { 3361 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3362 t_Error err; 3363 3364 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3365 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3366 3367 if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS)) 3368 RETURN_ERROR( MAJOR, E_INVALID_VALUE, 3369 ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS)); 3370 if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS) 3371 RETURN_ERROR( 3372 MAJOR, 3373 E_INVALID_VALUE, 3374 ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); 3375 err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 3376 (uint8_t*)&p_NumOfOpenDmas->num, 3377 (uint8_t*)&p_NumOfOpenDmas->extra, FALSE); 3378 if (err) 3379 RETURN_ERROR(MAJOR, err, NO_MSG); 3380 3381 memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc)); 3382 3383 return E_OK; 3384 } 3385 3386 t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) 3387 { 3388 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3389 t_Error err; 3390 3391 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3392 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3393 3394 /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */ 3395 ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND); 3396 3397 if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS)) 3398 RETURN_ERROR( 3399 MAJOR, E_INVALID_VALUE, 3400 ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS)); 3401 if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS) 3402 RETURN_ERROR( 3403 MAJOR, 3404 E_INVALID_VALUE, 3405 ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); 3406 3407 err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 3408 (uint8_t*)&p_NumOfTasks->num, 3409 (uint8_t*)&p_NumOfTasks->extra, FALSE); 3410 if (err) 3411 RETURN_ERROR(MAJOR, err, NO_MSG); 3412 3413 /* update driver's struct */ 3414 memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc)); 3415 return E_OK; 3416 } 3417 3418 t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo) 3419 { 3420 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3421 t_Error err; 3422 3423 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3424 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3425 3426 if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE)) 3427 RETURN_ERROR( 3428 MAJOR, 3429 E_INVALID_VALUE, 3430 ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 3431 if (p_SizeOfFifo->num % BMI_FIFO_UNITS) 3432 RETURN_ERROR( 3433 MAJOR, E_INVALID_VALUE, 3434 ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS)); 3435 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 3436 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 3437 { 3438 /* extra FIFO size (allowed only to Rx ports) */ 3439 if (p_SizeOfFifo->extra % BMI_FIFO_UNITS) 3440 RETURN_ERROR( 3441 MAJOR, 3442 E_INVALID_VALUE, 3443 ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS)); 3444 } 3445 else 3446 if (p_SizeOfFifo->extra) 3447 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3448 (" No SizeOfFifo-extra for non Rx ports")); 3449 3450 memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc)); 3451 3452 /* we do not change user's parameter */ 3453 err = VerifySizeOfFifo(p_FmPort); 3454 if (err) 3455 RETURN_ERROR(MAJOR, err, NO_MSG); 3456 3457 err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 3458 &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE); 3459 if (err) 3460 RETURN_ERROR(MAJOR, err, NO_MSG); 3461 3462 return E_OK; 3463 } 3464 3465 uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort) 3466 { 3467 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3468 3469 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 3470 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 3471 0); 3472 3473 return p_FmPort->bufferOffsets.dataOffset; 3474 } 3475 3476 uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data) 3477 { 3478 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3479 3480 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); 3481 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 3482 NULL); 3483 3484 if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE) 3485 return NULL; 3486 3487 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset); 3488 } 3489 3490 t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data) 3491 { 3492 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3493 3494 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); 3495 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 3496 NULL); 3497 3498 if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE) 3499 return NULL; 3500 3501 return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset); 3502 } 3503 3504 uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data) 3505 { 3506 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3507 3508 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); 3509 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 3510 NULL); 3511 3512 if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE) 3513 return NULL; 3514 3515 return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset); 3516 } 3517 3518 uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data) 3519 { 3520 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3521 3522 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); 3523 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 3524 NULL); 3525 3526 if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE) 3527 return NULL; 3528 3529 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset); 3530 } 3531 3532 t_Error FM_PORT_Disable(t_Handle h_FmPort) 3533 { 3534 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3535 int err; 3536 3537 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3538 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3539 3540 if (p_FmPort->imEn) 3541 FmPortImDisable(p_FmPort); 3542 3543 err = fman_port_disable(&p_FmPort->port); 3544 if (err == -EBUSY) 3545 { 3546 DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down", 3547 p_FmPort->name)); 3548 } 3549 else 3550 if (err != 0) 3551 { 3552 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable")); 3553 } 3554 3555 p_FmPort->enabled = FALSE; 3556 3557 return E_OK; 3558 } 3559 3560 t_Error FM_PORT_Enable(t_Handle h_FmPort) 3561 { 3562 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3563 int err; 3564 3565 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3566 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3567 3568 /* Used by FM_PORT_Free routine as indication 3569 if to disable port. Thus set it to TRUE prior 3570 to enabling itself. This way if part of enable 3571 process fails there will be still things 3572 to disable during Free. For example, if BMI 3573 enable succeeded but QMI failed, still BMI 3574 needs to be disabled by Free. */ 3575 p_FmPort->enabled = TRUE; 3576 3577 if (p_FmPort->imEn) 3578 FmPortImEnable(p_FmPort); 3579 3580 err = fman_port_enable(&p_FmPort->port); 3581 if (err != 0) 3582 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable")); 3583 3584 return E_OK; 3585 } 3586 3587 t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit) 3588 { 3589 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3590 uint8_t factor, countUnitBit; 3591 uint16_t baseGran; 3592 struct fman_port_rate_limiter params; 3593 int err; 3594 3595 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3596 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3597 3598 switch (p_FmPort->portType) 3599 { 3600 case (e_FM_PORT_TYPE_TX_10G): 3601 case (e_FM_PORT_TYPE_TX): 3602 baseGran = BMI_RATE_LIMIT_GRAN_TX; 3603 break; 3604 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3605 baseGran = BMI_RATE_LIMIT_GRAN_OP; 3606 break; 3607 default: 3608 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 3609 ("available for Tx and Offline parsing ports only")); 3610 } 3611 3612 countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */ 3613 /* normally, we use 1 usec as the reference count */ 3614 factor = 1; 3615 /* if ratelimit is too small for a 1usec factor, multiply the factor */ 3616 while (p_RateLimit->rateLimit < baseGran / factor) 3617 { 3618 if (countUnitBit == 31) 3619 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small")); 3620 3621 countUnitBit++; 3622 factor <<= 1; 3623 } 3624 /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/ 3625 if (p_RateLimit->rateLimit 3626 > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor)) 3627 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large")); 3628 3629 if (!p_RateLimit->maxBurstSize 3630 || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE)) 3631 RETURN_ERROR( 3632 MAJOR, 3633 E_INVALID_VALUE, 3634 ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE)); 3635 3636 params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); 3637 params.high_burst_size_gran = FALSE; 3638 params.burst_size = p_RateLimit->maxBurstSize; 3639 params.rate = p_RateLimit->rateLimit; 3640 params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE; 3641 3642 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 3643 { 3644 #ifndef FM_NO_ADVANCED_RATE_LIMITER 3645 3646 if ((p_FmPort->fmRevInfo.majorRev == 4) 3647 || (p_FmPort->fmRevInfo.majorRev >= 6)) 3648 { 3649 params.high_burst_size_gran = TRUE; 3650 } 3651 else 3652 #endif /* ! FM_NO_ADVANCED_RATE_LIMITER */ 3653 { 3654 if (p_RateLimit->rateLimitDivider 3655 != e_FM_PORT_DUAL_RATE_LIMITER_NONE) 3656 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 3657 ("FM_PORT_ConfigDualRateLimitScaleDown")); 3658 3659 if (p_RateLimit->maxBurstSize % 1000) 3660 { 3661 p_RateLimit->maxBurstSize = 3662 (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1); 3663 DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000)); 3664 } 3665 else 3666 p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize 3667 / 1000); 3668 } 3669 params.rate_factor = 3670 (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider; 3671 params.burst_size = p_RateLimit->maxBurstSize; 3672 } 3673 3674 err = fman_port_set_rate_limiter(&p_FmPort->port, ¶ms); 3675 if (err != 0) 3676 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter")); 3677 3678 return E_OK; 3679 } 3680 3681 t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort) 3682 { 3683 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3684 int err; 3685 3686 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3687 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3688 3689 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 3690 || (p_FmPort->portType == e_FM_PORT_TYPE_RX) 3691 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 3692 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 3693 ("available for Tx and Offline parsing ports only")); 3694 3695 err = fman_port_delete_rate_limiter(&p_FmPort->port); 3696 if (err != 0) 3697 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter")); 3698 return E_OK; 3699 } 3700 3701 t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, 3702 uint8_t wq) 3703 { 3704 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3705 uint32_t tmpReg; 3706 uint32_t wqTmpReg; 3707 3708 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3709 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3710 3711 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX) 3712 && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) 3713 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 3714 ("PFC mapping is available for Tx ports only")); 3715 3716 if (prio > 7) 3717 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, 3718 ("PFC priority (%d) is out of range (0-7)", prio)); 3719 if (wq > 7) 3720 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, 3721 ("WQ (%d) is out of range (0-7)", wq)); 3722 3723 tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]); 3724 tmpReg &= ~(0xf << ((7 - prio) * 4)); 3725 wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4)); 3726 tmpReg |= wqTmpReg; 3727 3728 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0], 3729 tmpReg); 3730 3731 return E_OK; 3732 } 3733 3734 t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable) 3735 { 3736 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3737 3738 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3739 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3740 3741 fman_port_set_queue_cnt_mode(&p_FmPort->port, enable); 3742 3743 return E_OK; 3744 } 3745 3746 t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable) 3747 { 3748 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3749 int err; 3750 3751 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3752 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3753 3754 err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable); 3755 if (err != 0) 3756 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode")); 3757 return E_OK; 3758 } 3759 3760 t_Error FM_PORT_SetPerformanceCountersParams( 3761 t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt) 3762 { 3763 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3764 struct fman_port_perf_cnt_params params; 3765 int err; 3766 3767 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3768 3769 /* check parameters */ 3770 if (!p_FmPortPerformanceCnt->taskCompVal 3771 || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num)) 3772 RETURN_ERROR( 3773 MAJOR, 3774 E_INVALID_VALUE, 3775 ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num)); 3776 if (!p_FmPortPerformanceCnt->dmaCompVal 3777 || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num)) 3778 RETURN_ERROR( 3779 MAJOR, 3780 E_INVALID_VALUE, 3781 ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num)); 3782 if (!p_FmPortPerformanceCnt->fifoCompVal 3783 || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num)) 3784 RETURN_ERROR( 3785 MAJOR, 3786 E_INVALID_VALUE, 3787 ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num)); 3788 if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS) 3789 RETURN_ERROR( 3790 MAJOR, 3791 E_INVALID_VALUE, 3792 ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS)); 3793 3794 switch (p_FmPort->portType) 3795 { 3796 case (e_FM_PORT_TYPE_RX_10G): 3797 case (e_FM_PORT_TYPE_RX): 3798 if (!p_FmPortPerformanceCnt->queueCompVal 3799 || (p_FmPortPerformanceCnt->queueCompVal 3800 > MAX_PERFORMANCE_RX_QUEUE_COMP)) 3801 RETURN_ERROR( 3802 MAJOR, 3803 E_INVALID_VALUE, 3804 ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP)); 3805 break; 3806 case (e_FM_PORT_TYPE_TX_10G): 3807 case (e_FM_PORT_TYPE_TX): 3808 if (!p_FmPortPerformanceCnt->queueCompVal 3809 || (p_FmPortPerformanceCnt->queueCompVal 3810 > MAX_PERFORMANCE_TX_QUEUE_COMP)) 3811 RETURN_ERROR( 3812 MAJOR, 3813 E_INVALID_VALUE, 3814 ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP)); 3815 break; 3816 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3817 case (e_FM_PORT_TYPE_OH_HOST_COMMAND): 3818 if (p_FmPortPerformanceCnt->queueCompVal) 3819 RETURN_ERROR( 3820 MAJOR, 3821 E_INVALID_VALUE, 3822 ("performanceCnt.queueCompVal is not relevant for H/O ports.")); 3823 break; 3824 default: 3825 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3826 } 3827 3828 params.task_val = p_FmPortPerformanceCnt->taskCompVal; 3829 params.queue_val = p_FmPortPerformanceCnt->queueCompVal; 3830 params.dma_val = p_FmPortPerformanceCnt->dmaCompVal; 3831 params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal; 3832 3833 err = fman_port_set_perf_cnt_params(&p_FmPort->port, ¶ms); 3834 if (err != 0) 3835 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params")); 3836 3837 return E_OK; 3838 } 3839 3840 t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort) 3841 { 3842 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3843 t_FmPortPerformanceCnt currParams, savedParams; 3844 t_Error err; 3845 bool underTest, failed = FALSE; 3846 3847 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3848 3849 XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n", 3850 p_FmPort->portType, p_FmPort->portId); 3851 3852 currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; 3853 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 3854 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 3855 currParams.queueCompVal = 0; 3856 else 3857 currParams.queueCompVal = 1; 3858 currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; 3859 currParams.fifoCompVal = p_FmPort->fifoBufs.num; 3860 3861 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); 3862 ClearPerfCnts(p_FmPort); 3863 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) 3864 != E_OK) 3865 RETURN_ERROR(MAJOR, err, NO_MSG); 3866 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); 3867 XX_UDelay(1000000); 3868 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); 3869 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) 3870 { 3871 XX_Print( 3872 "Max num of defined port tasks (%d) utilized - Please enlarge\n", 3873 p_FmPort->tasks.num); 3874 failed = TRUE; 3875 } 3876 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) 3877 { 3878 XX_Print( 3879 "Max num of defined port openDmas (%d) utilized - Please enlarge\n", 3880 p_FmPort->openDmas.num); 3881 failed = TRUE; 3882 } 3883 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) 3884 { 3885 XX_Print( 3886 "Max size of defined port fifo (%d) utilized - Please enlarge\n", 3887 p_FmPort->fifoBufs.num); 3888 failed = TRUE; 3889 } 3890 if (failed) 3891 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 3892 3893 memset(&savedParams, 0, sizeof(savedParams)); 3894 while (TRUE) 3895 { 3896 underTest = FALSE; 3897 if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal) 3898 { 3899 currParams.taskCompVal--; 3900 underTest = TRUE; 3901 } 3902 if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal) 3903 { 3904 currParams.dmaCompVal--; 3905 underTest = TRUE; 3906 } 3907 if ((currParams.fifoCompVal != BMI_FIFO_UNITS) 3908 && !savedParams.fifoCompVal) 3909 { 3910 currParams.fifoCompVal -= BMI_FIFO_UNITS; 3911 underTest = TRUE; 3912 } 3913 if (!underTest) 3914 break; 3915 3916 ClearPerfCnts(p_FmPort); 3917 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) 3918 != E_OK) 3919 RETURN_ERROR(MAJOR, err, NO_MSG); 3920 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); 3921 XX_UDelay(1000000); 3922 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); 3923 3924 if (!savedParams.taskCompVal 3925 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) 3926 savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2); 3927 if (!savedParams.dmaCompVal 3928 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) 3929 savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2); 3930 if (!savedParams.fifoCompVal 3931 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) 3932 savedParams.fifoCompVal = currParams.fifoCompVal 3933 + (2 * BMI_FIFO_UNITS); 3934 } 3935 3936 XX_Print("best vals: tasks %d, dmas %d, fifos %d\n", 3937 savedParams.taskCompVal, savedParams.dmaCompVal, 3938 savedParams.fifoCompVal); 3939 return E_OK; 3940 } 3941 3942 t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable) 3943 { 3944 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3945 int err; 3946 3947 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3948 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3949 3950 err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable); 3951 if (err != 0) 3952 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode")); 3953 return E_OK; 3954 } 3955 3956 t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs) 3957 { 3958 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3959 volatile uint32_t *p_ErrDiscard = NULL; 3960 int err; 3961 3962 UNUSED(p_ErrDiscard); 3963 err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs); 3964 if (err != 0) 3965 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask")); 3966 3967 #ifdef FM_ERROR_VSP_NO_MATCH_SW006 3968 if (p_FmPort->fmRevInfo.majorRev >= 6) 3969 { 3970 t_FmPcdCtrlParamsPage *p_ParamsPage; 3971 3972 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, 3973 (void**)&p_ParamsPage); 3974 ASSERT_COND(p_ParamsPage); 3975 switch (p_FmPort->portType) 3976 { 3977 case (e_FM_PORT_TYPE_RX_10G): 3978 case (e_FM_PORT_TYPE_RX): 3979 p_ErrDiscard = 3980 &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm; 3981 break; 3982 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3983 p_ErrDiscard = 3984 &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm; 3985 break; 3986 default: 3987 RETURN_ERROR( 3988 MAJOR, E_INVALID_OPERATION, 3989 ("available for Rx and offline parsing ports only")); 3990 } 3991 WRITE_UINT32(p_ParamsPage->errorsDiscardMask, 3992 GET_UINT32(*p_ErrDiscard) | errs); 3993 } 3994 #endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ 3995 3996 return E_OK; 3997 } 3998 3999 t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, 4000 bool enable) 4001 { 4002 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4003 int err; 4004 4005 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4006 SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE); 4007 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4008 4009 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 4010 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 4011 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 4012 ("available for Rx ports only")); 4013 4014 err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable); 4015 if (err != 0) 4016 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode")); 4017 return E_OK; 4018 } 4019 4020 t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats) 4021 { 4022 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4023 4024 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 4025 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){ 4026 p_BmiStats->cntCycle = 4027 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); 4028 /* fmbm_rccn */ 4029 p_BmiStats->cntTaskUtil = 4030 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); 4031 /* fmbm_rtuc */ 4032 p_BmiStats->cntQueueUtil = 4033 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL); 4034 /* fmbm_rrquc */ 4035 p_BmiStats->cntDmaUtil = 4036 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); 4037 /* fmbm_rduc */ 4038 p_BmiStats->cntFifoUtil = 4039 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); 4040 /* fmbm_rfuc */ 4041 p_BmiStats->cntRxPauseActivation = 4042 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION); 4043 /* fmbm_rpac */ 4044 p_BmiStats->cntFrame = 4045 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); 4046 /* fmbm_rfrc */ 4047 p_BmiStats->cntDiscardFrame = 4048 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); 4049 /* fmbm_rfdc */ 4050 p_BmiStats->cntDeallocBuf = 4051 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); 4052 /* fmbm_rbdc */ 4053 p_BmiStats->cntRxBadFrame = 4054 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME); 4055 /* fmbm_rfbc */ 4056 p_BmiStats->cntRxLargeFrame = 4057 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME); 4058 /* fmbm_rlfc */ 4059 p_BmiStats->cntRxFilterFrame = 4060 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME); 4061 /* fmbm_rffc */ 4062 p_BmiStats->cntRxListDmaErr = 4063 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR); 4064 /* fmbm_rfldec */ 4065 p_BmiStats->cntRxOutOfBuffersDiscard = 4066 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD); 4067 /* fmbm_rodc */ 4068 p_BmiStats->cntWredDiscard = 0; 4069 p_BmiStats->cntLengthErr = 0; 4070 p_BmiStats->cntUnsupportedFormat = 0; 4071 } 4072 else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 4073 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){ 4074 p_BmiStats->cntCycle = 4075 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); 4076 /* fmbm_tccn */ 4077 p_BmiStats->cntTaskUtil = 4078 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); 4079 /* fmbm_ttuc */ 4080 p_BmiStats->cntQueueUtil = 4081 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL); 4082 /* fmbm_ttcquc */ 4083 p_BmiStats->cntDmaUtil = 4084 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); 4085 /* fmbm_tduc */ 4086 p_BmiStats->cntFifoUtil = 4087 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); 4088 /* fmbm_tfuc */ 4089 p_BmiStats->cntRxPauseActivation = 0; 4090 p_BmiStats->cntFrame = 4091 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); 4092 /* fmbm_tfrc */ 4093 p_BmiStats->cntDiscardFrame = 4094 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); 4095 /* fmbm_tfdc */ 4096 p_BmiStats->cntDeallocBuf = 4097 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); 4098 /* fmbm_tbdc */ 4099 p_BmiStats->cntRxBadFrame = 0; 4100 p_BmiStats->cntRxLargeFrame = 0; 4101 p_BmiStats->cntRxFilterFrame = 0; 4102 p_BmiStats->cntRxListDmaErr = 0; 4103 p_BmiStats->cntRxOutOfBuffersDiscard = 0; 4104 p_BmiStats->cntWredDiscard = 0; 4105 p_BmiStats->cntLengthErr = 4106 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR); 4107 /* fmbm_tfledc */ 4108 p_BmiStats->cntUnsupportedFormat = 4109 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT); 4110 /* fmbm_tfufdc */ 4111 } 4112 else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) { 4113 p_BmiStats->cntCycle = 4114 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); 4115 /* fmbm_occn */ 4116 p_BmiStats->cntTaskUtil = 4117 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); 4118 /* fmbm_otuc */ 4119 p_BmiStats->cntQueueUtil = 0; 4120 p_BmiStats->cntDmaUtil = 4121 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); 4122 /* fmbm_oduc */ 4123 p_BmiStats->cntFifoUtil = 4124 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); 4125 /* fmbm_ofuc*/ 4126 p_BmiStats->cntRxPauseActivation = 0; 4127 p_BmiStats->cntFrame = 4128 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); 4129 /* fmbm_ofrc */ 4130 p_BmiStats->cntDiscardFrame = 4131 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); 4132 /* fmbm_ofdc */ 4133 p_BmiStats->cntDeallocBuf = 4134 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); 4135 /* fmbm_obdc*/ 4136 p_BmiStats->cntRxBadFrame = 0; 4137 p_BmiStats->cntRxLargeFrame = 0; 4138 p_BmiStats->cntRxFilterFrame = 4139 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME); 4140 /* fmbm_offc */ 4141 p_BmiStats->cntRxListDmaErr = 4142 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR); 4143 /* fmbm_ofldec */ 4144 p_BmiStats->cntRxOutOfBuffersDiscard = 4145 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD); 4146 /* fmbm_rodc */ 4147 p_BmiStats->cntWredDiscard = 4148 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD); 4149 /* fmbm_ofwdc */ 4150 p_BmiStats->cntLengthErr = 4151 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR); 4152 /* fmbm_ofledc */ 4153 p_BmiStats->cntUnsupportedFormat = 4154 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT); 4155 /* fmbm_ofufdc */ 4156 } 4157 return E_OK; 4158 } 4159 4160 uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter) 4161 { 4162 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4163 bool bmiCounter = FALSE; 4164 enum fman_port_stats_counters statsType; 4165 enum fman_port_perf_counters perfType; 4166 enum fman_port_qmi_counters queueType; 4167 bool isStats; 4168 t_Error errCode; 4169 4170 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 4171 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4172 4173 switch (counter) 4174 { 4175 case (e_FM_PORT_COUNTERS_DEQ_TOTAL): 4176 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 4177 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): 4178 /* check that counter is available for the port type */ 4179 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 4180 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 4181 { 4182 REPORT_ERROR(MINOR, E_INVALID_STATE, 4183 ("Requested counter is not available for Rx ports")); 4184 return 0; 4185 } 4186 bmiCounter = FALSE; 4187 break; 4188 case (e_FM_PORT_COUNTERS_ENQ_TOTAL): 4189 bmiCounter = FALSE; 4190 break; 4191 default: /* BMI counters (or error - will be checked in BMI routine )*/ 4192 bmiCounter = TRUE; 4193 break; 4194 } 4195 4196 if (bmiCounter) 4197 { 4198 errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType, 4199 &perfType, &isStats); 4200 if (errCode != E_OK) 4201 { 4202 REPORT_ERROR(MINOR, errCode, NO_MSG); 4203 return 0; 4204 } 4205 if (isStats) 4206 return fman_port_get_stats_counter(&p_FmPort->port, statsType); 4207 else 4208 return fman_port_get_perf_counter(&p_FmPort->port, perfType); 4209 } 4210 else /* QMI counter */ 4211 { 4212 /* check that counters are enabled */ 4213 if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc) 4214 & QMI_PORT_CFG_EN_COUNTERS)) 4215 4216 { 4217 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 4218 return 0; 4219 } 4220 4221 /* Set counter */ 4222 switch (counter) 4223 { 4224 case (e_FM_PORT_COUNTERS_ENQ_TOTAL): 4225 queueType = E_FMAN_PORT_ENQ_TOTAL; 4226 break; 4227 case (e_FM_PORT_COUNTERS_DEQ_TOTAL): 4228 queueType = E_FMAN_PORT_DEQ_TOTAL; 4229 break; 4230 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 4231 queueType = E_FMAN_PORT_DEQ_FROM_DFLT; 4232 break; 4233 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): 4234 queueType = E_FMAN_PORT_DEQ_CONFIRM; 4235 break; 4236 default: 4237 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); 4238 return 0; 4239 } 4240 4241 return fman_port_get_qmi_counter(&p_FmPort->port, queueType); 4242 } 4243 4244 return 0; 4245 } 4246 4247 t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, 4248 uint32_t value) 4249 { 4250 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4251 bool bmiCounter = FALSE; 4252 enum fman_port_stats_counters statsType; 4253 enum fman_port_perf_counters perfType; 4254 enum fman_port_qmi_counters queueType; 4255 bool isStats; 4256 t_Error errCode; 4257 4258 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4259 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4260 4261 switch (counter) 4262 { 4263 case (e_FM_PORT_COUNTERS_DEQ_TOTAL): 4264 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 4265 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): 4266 /* check that counter is available for the port type */ 4267 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 4268 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 4269 RETURN_ERROR( 4270 MINOR, E_INVALID_STATE, 4271 ("Requested counter is not available for Rx ports")); 4272 case (e_FM_PORT_COUNTERS_ENQ_TOTAL): 4273 bmiCounter = FALSE; 4274 break; 4275 default: /* BMI counters (or error - will be checked in BMI routine )*/ 4276 bmiCounter = TRUE; 4277 break; 4278 } 4279 4280 if (bmiCounter) 4281 { 4282 errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType, 4283 &perfType, &isStats); 4284 if (errCode != E_OK) 4285 { 4286 RETURN_ERROR(MINOR, errCode, NO_MSG); 4287 } 4288 if (isStats) 4289 fman_port_set_stats_counter(&p_FmPort->port, statsType, value); 4290 else 4291 fman_port_set_perf_counter(&p_FmPort->port, perfType, value); 4292 } 4293 else /* QMI counter */ 4294 { 4295 /* check that counters are enabled */ 4296 if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc) 4297 & QMI_PORT_CFG_EN_COUNTERS)) 4298 { 4299 RETURN_ERROR(MINOR, E_INVALID_STATE, 4300 ("Requested counter was not enabled")); 4301 } 4302 4303 /* Set counter */ 4304 switch (counter) 4305 { 4306 case (e_FM_PORT_COUNTERS_ENQ_TOTAL): 4307 queueType = E_FMAN_PORT_ENQ_TOTAL; 4308 break; 4309 case (e_FM_PORT_COUNTERS_DEQ_TOTAL): 4310 queueType = E_FMAN_PORT_DEQ_TOTAL; 4311 break; 4312 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 4313 queueType = E_FMAN_PORT_DEQ_FROM_DFLT; 4314 break; 4315 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): 4316 queueType = E_FMAN_PORT_DEQ_CONFIRM; 4317 break; 4318 default: 4319 RETURN_ERROR(MAJOR, E_INVALID_STATE, 4320 ("Requested counter is not available")); 4321 } 4322 4323 fman_port_set_qmi_counter(&p_FmPort->port, queueType, value); 4324 } 4325 4326 return E_OK; 4327 } 4328 4329 uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId) 4330 { 4331 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4332 4333 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 4334 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4335 4336 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) 4337 && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 4338 { 4339 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports")); 4340 return 0; 4341 } 4342 return fman_port_get_bpool_counter(&p_FmPort->port, poolId); 4343 } 4344 4345 t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, 4346 uint32_t value) 4347 { 4348 t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; 4349 4350 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4351 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4352 4353 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) 4354 && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 4355 RETURN_ERROR( MINOR, E_INVALID_STATE, 4356 ("Requested counter is not available for non-Rx ports")); 4357 4358 fman_port_set_bpool_counter(&p_FmPort->port, poolId, value); 4359 return E_OK; 4360 } 4361 bool FM_PORT_IsStalled(t_Handle h_FmPort) 4362 { 4363 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4364 t_Error err; 4365 bool isStalled; 4366 4367 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE); 4368 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 4369 FALSE); 4370 4371 err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled); 4372 if (err != E_OK) 4373 { 4374 REPORT_ERROR(MAJOR, err, NO_MSG); 4375 return TRUE; 4376 } 4377 return isStalled; 4378 } 4379 4380 t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort) 4381 { 4382 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4383 4384 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4385 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4386 4387 return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId); 4388 } 4389 4390 t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum) 4391 { 4392 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4393 int err; 4394 4395 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4396 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4397 4398 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 4399 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 4400 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 4401 ("available for Rx ports only")); 4402 4403 if (l4Checksum) 4404 err = fman_port_modify_rx_fd_bits( 4405 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24), 4406 TRUE); 4407 else 4408 err = fman_port_modify_rx_fd_bits( 4409 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24), 4410 FALSE); 4411 if (err != 0) 4412 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits")); 4413 4414 return E_OK; 4415 } 4416 4417 /*****************************************************************************/ 4418 /* API Run-time PCD Control unit functions */ 4419 /*****************************************************************************/ 4420 4421 #if (DPAA_VERSION >= 11) 4422 t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams) 4423 { 4424 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4425 t_Error err = E_OK; 4426 volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL; 4427 uint32_t tmpReg = 0, tmp = 0; 4428 uint16_t hwStoragePrflId; 4429 4430 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4431 SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE); 4432 /*for numOfProfiles = 0 don't call this function*/ 4433 SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE); 4434 /*dfltRelativeId should be in the range of numOfProfiles*/ 4435 SANITY_CHECK_RETURN_ERROR( 4436 p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles, 4437 E_INVALID_VALUE); 4438 /*p_FmPort should be from Rx type or OP*/ 4439 SANITY_CHECK_RETURN_ERROR( 4440 ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)), 4441 E_INVALID_VALUE); 4442 /*port should be disabled*/ 4443 SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE); 4444 /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/ 4445 SANITY_CHECK_RETURN_ERROR( 4446 ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)), 4447 E_INVALID_VALUE); 4448 /*should be called before SetPCD - this port should be without PCD*/ 4449 SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE); 4450 4451 /*alloc window of VSPs for this port*/ 4452 err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType, 4453 p_FmPort->portId, p_VSPParams->numOfProfiles); 4454 if (err != E_OK) 4455 RETURN_ERROR(MAJOR, err, NO_MSG); 4456 4457 /*get absolute VSP ID for dfltRelative*/ 4458 err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType, 4459 p_FmPort->portId, 4460 p_VSPParams->dfltRelativeId, 4461 &hwStoragePrflId); 4462 if (err != E_OK) 4463 RETURN_ERROR(MAJOR, err, NO_MSG); 4464 4465 /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/ 4466 switch (p_FmPort->portType) 4467 { 4468 case (e_FM_PORT_TYPE_RX_10G): 4469 case (e_FM_PORT_TYPE_RX): 4470 p_BmiStorageProfileId = 4471 &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid); 4472 p_BmiVspe = 4473 &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne); 4474 4475 tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK; 4476 tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT; 4477 WRITE_UINT32(*p_BmiStorageProfileId, tmpReg); 4478 4479 tmpReg = GET_UINT32(*p_BmiVspe); 4480 WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN); 4481 4482 p_BmiStorageProfileId = 4483 &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid; 4484 p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp; 4485 hwStoragePrflId = p_VSPParams->dfltRelativeId; 4486 break; 4487 4488 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4489 tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME; 4490 WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, 4491 tmpReg); 4492 4493 p_BmiStorageProfileId = 4494 &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid; 4495 p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp; 4496 tmp |= BMI_EBD_EN; 4497 break; 4498 4499 default: 4500 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4501 ("available for Rx and offline parsing ports only")); 4502 } 4503 4504 p_FmPort->vspe = TRUE; 4505 p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId; 4506 4507 tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK; 4508 tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT; 4509 WRITE_UINT32(*p_BmiStorageProfileId, tmpReg); 4510 4511 tmpReg = GET_UINT32(*p_BmiVspe); 4512 WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp); 4513 return E_OK; 4514 } 4515 #endif /* (DPAA_VERSION >= 11) */ 4516 4517 t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles) 4518 { 4519 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4520 t_Error err = E_OK; 4521 4522 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); 4523 ASSERT_COND(p_FmPort->h_FmPcd); 4524 4525 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4526 { 4527 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4528 return ERROR_CODE(E_BUSY); 4529 } 4530 4531 if (numOfProfiles) 4532 { 4533 err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd, 4534 p_FmPort->hardwarePortId, numOfProfiles); 4535 if (err) 4536 RETURN_ERROR(MAJOR, err, NO_MSG); 4537 } 4538 /* set the port handle within the PCD policer, even if no profiles defined */ 4539 FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId); 4540 4541 RELEASE_LOCK(p_FmPort->lock); 4542 4543 return E_OK; 4544 } 4545 4546 t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort) 4547 { 4548 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4549 t_Error err = E_OK; 4550 4551 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4552 { 4553 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4554 return ERROR_CODE(E_BUSY); 4555 } 4556 4557 err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId); 4558 4559 RELEASE_LOCK(p_FmPort->lock); 4560 4561 if (err) 4562 RETURN_ERROR(MAJOR, err, NO_MSG); 4563 4564 return E_OK; 4565 } 4566 4567 t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort, 4568 t_FmPcdKgSchemeSelect *p_FmPcdKgScheme) 4569 { 4570 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4571 volatile uint32_t *p_BmiHpnia = NULL; 4572 uint32_t tmpReg; 4573 uint8_t relativeSchemeId; 4574 uint8_t physicalSchemeId; 4575 4576 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4577 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4578 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, 4579 E_INVALID_STATE); 4580 4581 tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0); 4582 switch (p_FmPort->portType) 4583 { 4584 case (e_FM_PORT_TYPE_RX_10G): 4585 case (e_FM_PORT_TYPE_RX): 4586 p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; 4587 break; 4588 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4589 p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; 4590 break; 4591 default: 4592 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4593 ("available for Rx and offline parsing ports only")); 4594 } 4595 4596 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4597 { 4598 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4599 return ERROR_CODE(E_BUSY); 4600 } 4601 4602 /* if we want to change to direct scheme, we need to check that this scheme is valid */ 4603 if (p_FmPcdKgScheme->direct) 4604 { 4605 physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme); 4606 /* check that this scheme is bound to this port */ 4607 if (!(p_FmPort->schemesPerPortVector 4608 & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId)))) 4609 { 4610 RELEASE_LOCK(p_FmPort->lock); 4611 RETURN_ERROR( 4612 MAJOR, E_INVALID_STATE, 4613 ("called with a scheme that is not bound to this port")); 4614 } 4615 4616 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd, 4617 physicalSchemeId); 4618 if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 4619 { 4620 RELEASE_LOCK(p_FmPort->lock); 4621 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, 4622 ("called with invalid Scheme ")); 4623 } 4624 4625 if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme)) 4626 { 4627 RELEASE_LOCK(p_FmPort->lock); 4628 RETURN_ERROR(MAJOR, E_INVALID_STATE, 4629 ("called with uninitialized Scheme ")); 4630 } 4631 4632 WRITE_UINT32( 4633 *p_BmiHpnia, 4634 NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId); 4635 } 4636 else 4637 /* change to indirect scheme */ 4638 WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg); 4639 RELEASE_LOCK(p_FmPort->lock); 4640 4641 return E_OK; 4642 } 4643 4644 t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort, 4645 t_Handle h_Profile) 4646 { 4647 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4648 volatile uint32_t *p_BmiNia; 4649 volatile uint32_t *p_BmiHpnia; 4650 uint32_t tmpReg; 4651 uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); 4652 4653 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4654 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4655 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR, 4656 E_INVALID_STATE); 4657 4658 /* check relevance of this routine - only when policer is used 4659 directly after BMI or Parser */ 4660 if ((p_FmPort->pcdEngines & FM_PCD_KG) 4661 || (p_FmPort->pcdEngines & FM_PCD_CC)) 4662 RETURN_ERROR( 4663 MAJOR, 4664 E_INVALID_STATE, 4665 ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR")); 4666 4667 switch (p_FmPort->portType) 4668 { 4669 case (e_FM_PORT_TYPE_RX_10G): 4670 case (e_FM_PORT_TYPE_RX): 4671 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 4672 p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; 4673 tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; 4674 break; 4675 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4676 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 4677 p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; 4678 tmpReg = 0; 4679 break; 4680 default: 4681 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4682 ("available for Rx and offline parsing ports only")); 4683 } 4684 4685 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4686 { 4687 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4688 return ERROR_CODE(E_BUSY); 4689 } 4690 4691 if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) 4692 { 4693 RELEASE_LOCK(p_FmPort->lock); 4694 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile")); 4695 } 4696 4697 tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId); 4698 4699 if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ 4700 { 4701 /* update BMI HPNIA */ 4702 WRITE_UINT32(*p_BmiHpnia, tmpReg); 4703 } 4704 else /* e_FM_PCD_SUPPORT_PLCR_ONLY */ 4705 { 4706 /* rfne may contain FDCS bits, so first we read them. */ 4707 tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK); 4708 /* update BMI NIA */ 4709 WRITE_UINT32(*p_BmiNia, tmpReg); 4710 }RELEASE_LOCK(p_FmPort->lock); 4711 4712 return E_OK; 4713 } 4714 4715 t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree) 4716 { 4717 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4718 t_Error err = E_OK; 4719 volatile uint32_t *p_BmiCcBase = NULL; 4720 volatile uint32_t *p_BmiNia = NULL; 4721 uint32_t ccTreePhysOffset; 4722 4723 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4724 SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE); 4725 4726 if (p_FmPort->imEn) 4727 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 4728 ("available for non-independent mode ports only")); 4729 4730 /* get PCD registers pointers */ 4731 switch (p_FmPort->portType) 4732 { 4733 case (e_FM_PORT_TYPE_RX_10G): 4734 case (e_FM_PORT_TYPE_RX): 4735 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 4736 break; 4737 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4738 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 4739 break; 4740 default: 4741 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4742 ("available for Rx and offline parsing ports only")); 4743 } 4744 4745 /* check that current NIA is BMI to BMI */ 4746 if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) 4747 != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd)) 4748 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4749 ("may be called only for ports in BMI-to-BMI state.")); 4750 4751 if (p_FmPort->pcdEngines & FM_PCD_CC) 4752 { 4753 if (p_FmPort->h_IpReassemblyManip) 4754 { 4755 err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL, 4756 p_FmPort->h_IpReassemblyManip, FALSE); 4757 if (err != E_OK) 4758 { 4759 RETURN_ERROR(MAJOR, err, NO_MSG); 4760 } 4761 } 4762 else 4763 if (p_FmPort->h_CapwapReassemblyManip) 4764 { 4765 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL, 4766 p_FmPort->h_CapwapReassemblyManip, 4767 FALSE); 4768 if (err != E_OK) 4769 { 4770 RETURN_ERROR(MAJOR, err, NO_MSG); 4771 } 4772 } 4773 switch (p_FmPort->portType) 4774 { 4775 case (e_FM_PORT_TYPE_RX_10G): 4776 case (e_FM_PORT_TYPE_RX): 4777 p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb; 4778 break; 4779 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4780 p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb; 4781 break; 4782 default: 4783 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 4784 } 4785 4786 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4787 { 4788 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4789 return ERROR_CODE(E_BUSY); 4790 } 4791 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree, 4792 &ccTreePhysOffset, h_FmPort); 4793 if (err) 4794 { 4795 RELEASE_LOCK(p_FmPort->lock); 4796 RETURN_ERROR(MAJOR, err, NO_MSG); 4797 }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); 4798 4799 p_FmPort->ccTreeId = h_CcTree; 4800 RELEASE_LOCK(p_FmPort->lock); 4801 } 4802 else 4803 RETURN_ERROR( MAJOR, E_INVALID_STATE, 4804 ("Coarse Classification not defined for this port.")); 4805 4806 return E_OK; 4807 } 4808 4809 t_Error FM_PORT_AttachPCD(t_Handle h_FmPort) 4810 { 4811 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4812 t_Error err = E_OK; 4813 4814 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4815 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4816 4817 if (p_FmPort->imEn) 4818 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 4819 ("available for non-independent mode ports only")); 4820 4821 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 4822 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 4823 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 4824 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4825 ("available for Rx and offline parsing ports only")); 4826 4827 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4828 { 4829 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4830 return ERROR_CODE(E_BUSY); 4831 } 4832 4833 if (p_FmPort->h_ReassemblyTree) 4834 p_FmPort->pcdEngines |= FM_PCD_CC; 4835 4836 err = AttachPCD(h_FmPort); 4837 RELEASE_LOCK(p_FmPort->lock); 4838 4839 return err; 4840 } 4841 4842 t_Error FM_PORT_DetachPCD(t_Handle h_FmPort) 4843 { 4844 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4845 t_Error err = E_OK; 4846 4847 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4848 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4849 4850 if (p_FmPort->imEn) 4851 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 4852 ("available for non-independent mode ports only")); 4853 4854 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 4855 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 4856 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 4857 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4858 ("available for Rx and offline parsing ports only")); 4859 4860 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4861 { 4862 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4863 return ERROR_CODE(E_BUSY); 4864 } 4865 4866 err = DetachPCD(h_FmPort); 4867 if (err != E_OK) 4868 { 4869 RELEASE_LOCK(p_FmPort->lock); 4870 RETURN_ERROR(MAJOR, err, NO_MSG); 4871 } 4872 4873 if (p_FmPort->h_ReassemblyTree) 4874 p_FmPort->pcdEngines &= ~FM_PCD_CC; 4875 RELEASE_LOCK(p_FmPort->lock); 4876 4877 return E_OK; 4878 } 4879 4880 t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam) 4881 { 4882 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4883 t_Error err = E_OK; 4884 t_FmPortPcdParams modifiedPcdParams, *p_PcdParams; 4885 t_FmPcdCcTreeParams *p_FmPcdCcTreeParams; 4886 t_FmPortPcdCcParams fmPortPcdCcParams; 4887 t_FmPortGetSetCcParams fmPortGetSetCcParams; 4888 4889 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4890 SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER); 4891 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4892 4893 if (p_FmPort->imEn) 4894 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 4895 ("available for non-independent mode ports only")); 4896 4897 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 4898 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 4899 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 4900 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 4901 ("available for Rx and offline parsing ports only")); 4902 4903 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4904 { 4905 DBG(TRACE, ("FM Port Try Lock - BUSY")); 4906 return ERROR_CODE(E_BUSY); 4907 } 4908 4909 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); 4910 ASSERT_COND(p_FmPort->h_FmPcd); 4911 4912 if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree) 4913 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, 4914 ("Tree handle must be given if CC is required")); 4915 4916 memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams)); 4917 p_PcdParams = &modifiedPcdParams; 4918 if ((p_PcdParams->h_IpReassemblyManip) 4919 #if (DPAA_VERSION >= 11) 4920 || (p_PcdParams->h_CapwapReassemblyManip) 4921 #endif /* (DPAA_VERSION >= 11) */ 4922 ) 4923 { 4924 if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) 4925 && (p_PcdParams->pcdSupport 4926 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC) 4927 && (p_PcdParams->pcdSupport 4928 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR) 4929 && (p_PcdParams->pcdSupport 4930 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)) 4931 { 4932 RELEASE_LOCK(p_FmPort->lock); 4933 RETURN_ERROR( MAJOR, E_INVALID_STATE, 4934 ("pcdSupport must have KG for supporting Reassembly")); 4935 } 4936 p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip; 4937 #if (DPAA_VERSION >= 11) 4938 if ((p_PcdParams->h_IpReassemblyManip) 4939 && (p_PcdParams->h_CapwapReassemblyManip)) 4940 RETURN_ERROR(MAJOR, E_INVALID_STATE, 4941 ("Either IP-R or CAPWAP-R is allowed")); 4942 if ((p_PcdParams->h_CapwapReassemblyManip) 4943 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 4944 RETURN_ERROR(MAJOR, E_INVALID_STATE, 4945 ("CAPWAP-R is allowed only on offline-port")); 4946 if (p_PcdParams->h_CapwapReassemblyManip) 4947 p_FmPort->h_CapwapReassemblyManip = 4948 p_PcdParams->h_CapwapReassemblyManip; 4949 #endif /* (DPAA_VERSION >= 11) */ 4950 4951 if (!p_PcdParams->p_CcParams) 4952 { 4953 if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) 4954 || (p_PcdParams->pcdSupport 4955 == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))) 4956 { 4957 RELEASE_LOCK(p_FmPort->lock); 4958 RETURN_ERROR( 4959 MAJOR, 4960 E_INVALID_STATE, 4961 ("PCD initialization structure is not consistent with pcdSupport")); 4962 } 4963 4964 /* No user-tree, need to build internal tree */ 4965 p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc( 4966 sizeof(t_FmPcdCcTreeParams)); 4967 if (!p_FmPcdCcTreeParams) 4968 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams")); 4969 memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams)); 4970 p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv; 4971 p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild( 4972 p_FmPort->h_FmPcd, p_FmPcdCcTreeParams); 4973 4974 if (!p_FmPort->h_ReassemblyTree) 4975 { 4976 RELEASE_LOCK(p_FmPort->lock); 4977 XX_Free(p_FmPcdCcTreeParams); 4978 RETURN_ERROR( MAJOR, E_INVALID_HANDLE, 4979 ("FM_PCD_CcBuildTree for Reassembly failed")); 4980 } 4981 if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) 4982 p_PcdParams->pcdSupport = 4983 e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC; 4984 else 4985 p_PcdParams->pcdSupport = 4986 e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR; 4987 4988 memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams)); 4989 fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree; 4990 p_PcdParams->p_CcParams = &fmPortPcdCcParams; 4991 XX_Free(p_FmPcdCcTreeParams); 4992 } 4993 4994 if (p_FmPort->h_IpReassemblyManip) 4995 err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, 4996 p_PcdParams->p_CcParams->h_CcTree, 4997 p_PcdParams->h_NetEnv, 4998 p_FmPort->h_IpReassemblyManip, TRUE); 4999 #if (DPAA_VERSION >= 11) 5000 else 5001 if (p_FmPort->h_CapwapReassemblyManip) 5002 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, 5003 p_PcdParams->p_CcParams->h_CcTree, 5004 p_PcdParams->h_NetEnv, 5005 p_FmPort->h_CapwapReassemblyManip, 5006 TRUE); 5007 #endif /* (DPAA_VERSION >= 11) */ 5008 5009 if (err != E_OK) 5010 { 5011 if (p_FmPort->h_ReassemblyTree) 5012 { 5013 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5014 p_FmPort->h_ReassemblyTree = NULL; 5015 }RELEASE_LOCK(p_FmPort->lock); 5016 RETURN_ERROR(MAJOR, err, NO_MSG); 5017 } 5018 } 5019 5020 if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd)) 5021 { 5022 if (p_FmPort->h_ReassemblyTree) 5023 { 5024 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5025 p_FmPort->h_ReassemblyTree = NULL; 5026 }RELEASE_LOCK(p_FmPort->lock); 5027 DBG(TRACE, ("Try LockAll - BUSY")); 5028 return ERROR_CODE(E_BUSY); 5029 } 5030 5031 err = SetPcd(h_FmPort, p_PcdParams); 5032 if (err) 5033 { 5034 if (p_FmPort->h_ReassemblyTree) 5035 { 5036 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5037 p_FmPort->h_ReassemblyTree = NULL; 5038 } 5039 FmPcdLockUnlockAll(p_FmPort->h_FmPcd); 5040 RELEASE_LOCK(p_FmPort->lock); 5041 RETURN_ERROR(MAJOR, err, NO_MSG); 5042 } 5043 5044 if ((p_FmPort->pcdEngines & FM_PCD_PRS) 5045 && (p_PcdParams->p_PrsParams->includeInPrsStatistics)) 5046 { 5047 err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, 5048 p_FmPort->hardwarePortId, TRUE); 5049 if (err) 5050 { 5051 DeletePcd(p_FmPort); 5052 if (p_FmPort->h_ReassemblyTree) 5053 { 5054 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5055 p_FmPort->h_ReassemblyTree = NULL; 5056 } 5057 FmPcdLockUnlockAll(p_FmPort->h_FmPcd); 5058 RELEASE_LOCK(p_FmPort->lock); 5059 RETURN_ERROR(MAJOR, err, NO_MSG); 5060 } 5061 p_FmPort->includeInPrsStatistics = TRUE; 5062 } 5063 5064 FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); 5065 5066 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) 5067 { 5068 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); 5069 5070 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 5071 { 5072 #ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 5073 if ((p_FmPort->fmRevInfo.majorRev < 6) && 5074 (p_FmPort->pcdEngines & FM_PCD_KG)) 5075 { 5076 int i; 5077 for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++) 5078 /* The following function must be locked */ 5079 FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, 5080 p_PcdParams->p_KgParams->h_Schemes[i], 5081 UPDATE_KG_NIA_CC_WA, 5082 0); 5083 } 5084 #endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */ 5085 5086 #if (DPAA_VERSION >= 11) 5087 { 5088 t_FmPcdCtrlParamsPage *p_ParamsPage; 5089 5090 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, 5091 (void**)&p_ParamsPage); 5092 ASSERT_COND(p_ParamsPage); 5093 WRITE_UINT32(p_ParamsPage->postBmiFetchNia, 5094 p_FmPort->savedBmiNia); 5095 } 5096 #endif /* (DPAA_VERSION >= 11) */ 5097 5098 /* Set post-bmi-fetch nia */ 5099 p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK; 5100 p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH 5101 | NIA_ENG_FM_CTL); 5102 5103 /* Set pre-bmi-fetch nia */ 5104 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; 5105 #if (DPAA_VERSION >= 11) 5106 fmPortGetSetCcParams.setCcParams.nia = 5107 (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL); 5108 #else 5109 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL); 5110 #endif /* (DPAA_VERSION >= 11) */ 5111 if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams)) 5112 != E_OK) 5113 { 5114 DeletePcd(p_FmPort); 5115 if (p_FmPort->h_ReassemblyTree) 5116 { 5117 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5118 p_FmPort->h_ReassemblyTree = NULL; 5119 } 5120 FmPcdLockUnlockAll(p_FmPort->h_FmPcd); 5121 RELEASE_LOCK(p_FmPort->lock); 5122 RETURN_ERROR(MAJOR, err, NO_MSG); 5123 } 5124 } 5125 5126 FmPcdLockUnlockAll(p_FmPort->h_FmPcd); 5127 5128 /* Set pop-to-next-step nia */ 5129 #if (DPAA_VERSION == 10) 5130 if (p_FmPort->fmRevInfo.majorRev < 6) 5131 { 5132 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; 5133 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; 5134 } 5135 else 5136 { 5137 #endif /* (DPAA_VERSION == 10) */ 5138 fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE; 5139 #if (DPAA_VERSION == 10) 5140 } 5141 #endif /* (DPAA_VERSION == 10) */ 5142 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) 5143 != E_OK) 5144 { 5145 DeletePcd(p_FmPort); 5146 if (p_FmPort->h_ReassemblyTree) 5147 { 5148 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5149 p_FmPort->h_ReassemblyTree = NULL; 5150 }RELEASE_LOCK(p_FmPort->lock); 5151 RETURN_ERROR(MAJOR, err, NO_MSG); 5152 } 5153 5154 /* Set post-bmi-prepare-to-enq nia */ 5155 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE; 5156 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ 5157 | NIA_ENG_FM_CTL); 5158 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) 5159 != E_OK) 5160 { 5161 DeletePcd(p_FmPort); 5162 if (p_FmPort->h_ReassemblyTree) 5163 { 5164 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5165 p_FmPort->h_ReassemblyTree = NULL; 5166 }RELEASE_LOCK(p_FmPort->lock); 5167 RETURN_ERROR(MAJOR, err, NO_MSG); 5168 } 5169 5170 if ((p_FmPort->h_IpReassemblyManip) 5171 || (p_FmPort->h_CapwapReassemblyManip)) 5172 { 5173 #if (DPAA_VERSION == 10) 5174 if (p_FmPort->fmRevInfo.majorRev < 6) 5175 { 5176 /* Overwrite post-bmi-prepare-to-enq nia */ 5177 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE; 5178 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR); 5179 fmPortGetSetCcParams.setCcParams.overwrite = TRUE; 5180 } 5181 else 5182 { 5183 #endif /* (DPAA_VERSION == 10) */ 5184 /* Set the ORR bit (for order-restoration) */ 5185 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE; 5186 fmPortGetSetCcParams.setCcParams.nia = 5187 fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR; 5188 #if (DPAA_VERSION == 10) 5189 } 5190 #endif /* (DPAA_VERSION == 10) */ 5191 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) 5192 != E_OK) 5193 { 5194 DeletePcd(p_FmPort); 5195 if (p_FmPort->h_ReassemblyTree) 5196 { 5197 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5198 p_FmPort->h_ReassemblyTree = NULL; 5199 }RELEASE_LOCK(p_FmPort->lock); 5200 RETURN_ERROR(MAJOR, err, NO_MSG); 5201 } 5202 } 5203 } 5204 else 5205 FmPcdLockUnlockAll(p_FmPort->h_FmPcd); 5206 5207 #if (DPAA_VERSION >= 11) 5208 { 5209 t_FmPcdCtrlParamsPage *p_ParamsPage; 5210 5211 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); 5212 5213 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE; 5214 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) 5215 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP 5216 | NIA_ENG_FM_CTL; 5217 else 5218 fmPortGetSetCcParams.setCcParams.nia = 5219 NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL; 5220 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) 5221 != E_OK) 5222 { 5223 DeletePcd(p_FmPort); 5224 if (p_FmPort->h_ReassemblyTree) 5225 { 5226 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5227 p_FmPort->h_ReassemblyTree = NULL; 5228 }RELEASE_LOCK(p_FmPort->lock); 5229 RETURN_ERROR(MAJOR, err, NO_MSG); 5230 } 5231 5232 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, 5233 (void**)&p_ParamsPage); 5234 ASSERT_COND(p_ParamsPage); 5235 5236 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) 5237 WRITE_UINT32( 5238 p_ParamsPage->misc, 5239 GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN); 5240 5241 if ((p_FmPort->h_IpReassemblyManip) 5242 || (p_FmPort->h_CapwapReassemblyManip)) 5243 { 5244 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 5245 WRITE_UINT32( 5246 p_ParamsPage->discardMask, 5247 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm)); 5248 else 5249 WRITE_UINT32( 5250 p_ParamsPage->discardMask, 5251 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm)); 5252 } 5253 #ifdef FM_ERROR_VSP_NO_MATCH_SW006 5254 if (p_FmPort->vspe) 5255 WRITE_UINT32( 5256 p_ParamsPage->misc, 5257 GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK)); 5258 #endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ 5259 } 5260 #endif /* (DPAA_VERSION >= 11) */ 5261 5262 err = AttachPCD(h_FmPort); 5263 if (err) 5264 { 5265 DeletePcd(p_FmPort); 5266 if (p_FmPort->h_ReassemblyTree) 5267 { 5268 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5269 p_FmPort->h_ReassemblyTree = NULL; 5270 }RELEASE_LOCK(p_FmPort->lock); 5271 RETURN_ERROR(MAJOR, err, NO_MSG); 5272 } 5273 5274 RELEASE_LOCK(p_FmPort->lock); 5275 5276 return err; 5277 } 5278 5279 t_Error FM_PORT_DeletePCD(t_Handle h_FmPort) 5280 { 5281 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 5282 t_Error err = E_OK; 5283 5284 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 5285 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 5286 5287 if (p_FmPort->imEn) 5288 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 5289 ("available for non-independant mode ports only")); 5290 5291 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 5292 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 5293 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 5294 RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 5295 ("available for Rx and offline parsing ports only")); 5296 5297 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 5298 { 5299 DBG(TRACE, ("FM Port Try Lock - BUSY")); 5300 return ERROR_CODE(E_BUSY); 5301 } 5302 5303 err = DetachPCD(h_FmPort); 5304 if (err) 5305 { 5306 RELEASE_LOCK(p_FmPort->lock); 5307 RETURN_ERROR(MAJOR, err, NO_MSG); 5308 } 5309 5310 FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); 5311 5312 /* we do it anyway, instead of checking if included */ 5313 if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics) 5314 { 5315 FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, 5316 p_FmPort->hardwarePortId, FALSE); 5317 p_FmPort->includeInPrsStatistics = FALSE; 5318 } 5319 5320 if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd)) 5321 { 5322 RELEASE_LOCK(p_FmPort->lock); 5323 DBG(TRACE, ("Try LockAll - BUSY")); 5324 return ERROR_CODE(E_BUSY); 5325 } 5326 5327 err = DeletePcd(h_FmPort); 5328 FmPcdLockUnlockAll(p_FmPort->h_FmPcd); 5329 if (err) 5330 { 5331 RELEASE_LOCK(p_FmPort->lock); 5332 RETURN_ERROR(MAJOR, err, NO_MSG); 5333 } 5334 5335 if (p_FmPort->h_ReassemblyTree) 5336 { 5337 err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); 5338 if (err) 5339 { 5340 RELEASE_LOCK(p_FmPort->lock); 5341 RETURN_ERROR(MAJOR, err, NO_MSG); 5342 } 5343 p_FmPort->h_ReassemblyTree = NULL; 5344 }RELEASE_LOCK(p_FmPort->lock); 5345 5346 return err; 5347 } 5348 5349 t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort, 5350 t_FmPcdPortSchemesParams *p_PortScheme) 5351 { 5352 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 5353 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 5354 t_Error err = E_OK; 5355 uint32_t tmpScmVec = 0; 5356 int i; 5357 5358 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 5359 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 5360 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, 5361 E_INVALID_STATE); 5362 5363 schemeBind.netEnvId = p_FmPort->netEnvId; 5364 schemeBind.hardwarePortId = p_FmPort->hardwarePortId; 5365 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; 5366 schemeBind.useClsPlan = p_FmPort->useClsPlan; 5367 for (i = 0; i < schemeBind.numOfSchemes; i++) 5368 { 5369 schemeBind.schemesIds[i] = FmPcdKgGetSchemeId( 5370 p_PortScheme->h_Schemes[i]); 5371 /* build vector */ 5372 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); 5373 } 5374 5375 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 5376 { 5377 DBG(TRACE, ("FM Port Try Lock - BUSY")); 5378 return ERROR_CODE(E_BUSY); 5379 } 5380 5381 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 5382 if (err == E_OK) 5383 p_FmPort->schemesPerPortVector |= tmpScmVec; 5384 5385 #ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 5386 if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) && 5387 (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && 5388 (p_FmPort->fmRevInfo.majorRev < 6)) 5389 { 5390 for (i=0; i<p_PortScheme->numOfSchemes; i++) 5391 FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0); 5392 } 5393 #endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */ 5394 5395 RELEASE_LOCK(p_FmPort->lock); 5396 5397 return err; 5398 } 5399 5400 t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort, 5401 t_FmPcdPortSchemesParams *p_PortScheme) 5402 { 5403 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 5404 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 5405 t_Error err = E_OK; 5406 uint32_t tmpScmVec = 0; 5407 int i; 5408 5409 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 5410 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 5411 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, 5412 E_INVALID_STATE); 5413 5414 schemeBind.netEnvId = p_FmPort->netEnvId; 5415 schemeBind.hardwarePortId = p_FmPort->hardwarePortId; 5416 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; 5417 for (i = 0; i < schemeBind.numOfSchemes; i++) 5418 { 5419 schemeBind.schemesIds[i] = FmPcdKgGetSchemeId( 5420 p_PortScheme->h_Schemes[i]); 5421 /* build vector */ 5422 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); 5423 } 5424 5425 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 5426 { 5427 DBG(TRACE, ("FM Port Try Lock - BUSY")); 5428 return ERROR_CODE(E_BUSY); 5429 } 5430 5431 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 5432 if (err == E_OK) 5433 p_FmPort->schemesPerPortVector &= ~tmpScmVec; 5434 RELEASE_LOCK(p_FmPort->lock); 5435 5436 return err; 5437 } 5438 5439 t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, 5440 t_FmPortCongestionGrps *p_CongestionGrps) 5441 { 5442 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 5443 uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS]; 5444 uint8_t mod, index; 5445 uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM]; 5446 int err; 5447 #if (DPAA_VERSION >= 11) 5448 int j; 5449 #endif /* (DPAA_VERSION >= 11) */ 5450 5451 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 5452 5453 /* un-necessary check of the indexes; probably will be needed in the future when there 5454 will be more CGs available .... 5455 for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++) 5456 if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS) 5457 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!")); 5458 */ 5459 5460 #ifdef FM_NO_OP_OBSERVED_CGS 5461 if ((p_FmPort->fmRevInfo.majorRev != 4) && 5462 (p_FmPort->fmRevInfo.majorRev < 6)) 5463 { 5464 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 5465 (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 5466 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); 5467 } 5468 else 5469 #endif /* FM_NO_OP_OBSERVED_CGS */ 5470 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 5471 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 5472 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 5473 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 5474 ("Available for Rx & OP ports only")); 5475 5476 /* Prepare groups map array */ 5477 memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t)); 5478 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) 5479 { 5480 index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32); 5481 mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32); 5482 if (p_FmPort->fmRevInfo.majorRev != 4) 5483 grpsMap[7 - index] |= (uint32_t)(1 << mod); 5484 else 5485 grpsMap[0] |= (uint32_t)(1 << mod); 5486 } 5487 5488 memset(&priorityTmpArray, 0, 5489 FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t)); 5490 5491 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) 5492 { 5493 #if (DPAA_VERSION >= 11) 5494 for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++) 5495 if (p_CongestionGrps->pfcPrioritiesEn[i][j]) 5496 priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |= 5497 (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1)); 5498 #endif /* (DPAA_VERSION >= 11) */ 5499 } 5500 5501 #if (DPAA_VERSION >= 11) 5502 for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++) 5503 { 5504 err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i, 5505 priorityTmpArray[i]); 5506 if (err) 5507 return err; 5508 } 5509 #endif /* (DPAA_VERSION >= 11) */ 5510 5511 err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap); 5512 if (err != 0) 5513 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps")); 5514 5515 return E_OK; 5516 } 5517 5518 t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, 5519 t_FmPortCongestionGrps *p_CongestionGrps) 5520 { 5521 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 5522 uint8_t mod, index; 5523 uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM]; 5524 int err; 5525 5526 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 5527 5528 { 5529 #ifdef FM_NO_OP_OBSERVED_CGS 5530 t_FmRevisionInfo revInfo; 5531 5532 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 5533 if (revInfo.majorRev != 4) 5534 { 5535 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 5536 (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 5537 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); 5538 } 5539 else 5540 #endif /* FM_NO_OP_OBSERVED_CGS */ 5541 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 5542 && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 5543 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 5544 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 5545 ("Available for Rx & OP ports only")); 5546 } 5547 5548 /* Prepare groups map array */ 5549 memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t)); 5550 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) 5551 { 5552 index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32); 5553 mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32); 5554 if (p_FmPort->fmRevInfo.majorRev != 4) 5555 grpsMap[7 - index] |= (uint32_t)(1 << mod); 5556 else 5557 grpsMap[0] |= (uint32_t)(1 << mod); 5558 } 5559 5560 #if (DPAA_VERSION >= 11) 5561 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) 5562 { 5563 t_Error err = FmSetCongestionGroupPFCpriority( 5564 p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i], 5565 0); 5566 if (err) 5567 return err; 5568 } 5569 #endif /* (DPAA_VERSION >= 11) */ 5570 5571 err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap); 5572 if (err != 0) 5573 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 5574 ("fman_port_remove_congestion_grps")); 5575 return E_OK; 5576 } 5577 5578 #if (DPAA_VERSION >= 11) 5579 t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, 5580 uint32_t *p_Ipv4OptionsCount) 5581 { 5582 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 5583 5584 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 5585 SANITY_CHECK_RETURN_ERROR( 5586 (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING), 5587 E_INVALID_VALUE); 5588 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE); 5589 SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER); 5590 5591 *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter); 5592 5593 return E_OK; 5594 } 5595 #endif /* (DPAA_VERSION >= 11) */ 5596 5597 t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, 5598 t_FmPortDsarTablesSizes *params) 5599 { 5600 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; 5601 p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc( 5602 sizeof(struct t_FmPortDsarTablesSizes)); 5603 memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params, 5604 sizeof(struct t_FmPortDsarTablesSizes)); 5605 return E_OK; 5606 } 5607 5608 static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort) 5609 { 5610 uint32_t *param_page; 5611 t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes; 5612 t_ArCommonDesc *ArCommonDescPtr; 5613 uint32_t size = sizeof(t_ArCommonDesc); 5614 // ARP 5615 // should put here if (params->max_num_of_arp_entries)? 5616 size = ROUND_UP(size,4); 5617 size += sizeof(t_DsarArpDescriptor); 5618 size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries; 5619 size += sizeof(t_DsarArpStatistics); 5620 //ICMPV4 5621 size = ROUND_UP(size,4); 5622 size += sizeof(t_DsarIcmpV4Descriptor); 5623 size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries; 5624 size += sizeof(t_DsarIcmpV4Statistics); 5625 //ICMPV6 5626 size = ROUND_UP(size,4); 5627 size += sizeof(t_DsarIcmpV6Descriptor); 5628 size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries; 5629 size += sizeof(t_DsarIcmpV6Statistics); 5630 //ND 5631 size = ROUND_UP(size,4); 5632 size += sizeof(t_DsarNdDescriptor); 5633 size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries; 5634 size += sizeof(t_DsarIcmpV6Statistics); 5635 //SNMP 5636 size = ROUND_UP(size,4); 5637 size += sizeof(t_DsarSnmpDescriptor); 5638 size += sizeof(t_DsarSnmpIpv4AddrTblEntry) 5639 * params->maxNumOfSnmpIPV4Entries; 5640 size += sizeof(t_DsarSnmpIpv6AddrTblEntry) 5641 * params->maxNumOfSnmpIPV6Entries; 5642 size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries; 5643 size += params->maxNumOfSnmpOidChar; 5644 size += sizeof(t_DsarIcmpV6Statistics); 5645 //filters 5646 size = ROUND_UP(size,4); 5647 size += params->maxNumOfIpProtFiltering; 5648 size = ROUND_UP(size,4); 5649 size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry); 5650 size = ROUND_UP(size,4); 5651 size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry); 5652 5653 // add here for more protocols 5654 5655 // statistics 5656 size = ROUND_UP(size,4); 5657 size += sizeof(t_ArStatistics); 5658 5659 ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10); 5660 5661 param_page = 5662 XX_PhysToVirt( 5663 p_FmPort->fmMuramPhysBaseAddr 5664 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); 5665 WRITE_UINT32( 5666 *param_page, 5667 (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr)); 5668 return E_OK; 5669 } 5670 5671 t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx) 5672 { 5673 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; 5674 return p_FmPort->deepSleepVars.autoResMaxSizes; 5675 } 5676 5677 struct arOffsets 5678 { 5679 uint32_t arp; 5680 uint32_t nd; 5681 uint32_t icmpv4; 5682 uint32_t icmpv6; 5683 uint32_t snmp; 5684 uint32_t stats; 5685 uint32_t filtIp; 5686 uint32_t filtUdp; 5687 uint32_t filtTcp; 5688 }; 5689 5690 static uint32_t AR_ComputeOffsets(struct arOffsets* of, 5691 struct t_FmPortDsarParams *params, 5692 t_FmPort *p_FmPort) 5693 { 5694 uint32_t size = sizeof(t_ArCommonDesc); 5695 // ARP 5696 if (params->p_AutoResArpInfo) 5697 { 5698 size = ROUND_UP(size,4); 5699 of->arp = size; 5700 size += sizeof(t_DsarArpDescriptor); 5701 size += sizeof(t_DsarArpBindingEntry) 5702 * params->p_AutoResArpInfo->tableSize; 5703 size += sizeof(t_DsarArpStatistics); 5704 } 5705 // ICMPV4 5706 if (params->p_AutoResEchoIpv4Info) 5707 { 5708 size = ROUND_UP(size,4); 5709 of->icmpv4 = size; 5710 size += sizeof(t_DsarIcmpV4Descriptor); 5711 size += sizeof(t_DsarIcmpV4BindingEntry) 5712 * params->p_AutoResEchoIpv4Info->tableSize; 5713 size += sizeof(t_DsarIcmpV4Statistics); 5714 } 5715 // ICMPV6 5716 if (params->p_AutoResEchoIpv6Info) 5717 { 5718 size = ROUND_UP(size,4); 5719 of->icmpv6 = size; 5720 size += sizeof(t_DsarIcmpV6Descriptor); 5721 size += sizeof(t_DsarIcmpV6BindingEntry) 5722 * params->p_AutoResEchoIpv6Info->tableSize; 5723 size += sizeof(t_DsarIcmpV6Statistics); 5724 } 5725 // ND 5726 if (params->p_AutoResNdpInfo) 5727 { 5728 size = ROUND_UP(size,4); 5729 of->nd = size; 5730 size += sizeof(t_DsarNdDescriptor); 5731 size += sizeof(t_DsarIcmpV6BindingEntry) 5732 * (params->p_AutoResNdpInfo->tableSizeAssigned 5733 + params->p_AutoResNdpInfo->tableSizeTmp); 5734 size += sizeof(t_DsarIcmpV6Statistics); 5735 } 5736 // SNMP 5737 if (params->p_AutoResSnmpInfo) 5738 { 5739 size = ROUND_UP(size,4); 5740 of->snmp = size; 5741 size += sizeof(t_DsarSnmpDescriptor); 5742 size += sizeof(t_DsarSnmpIpv4AddrTblEntry) 5743 * params->p_AutoResSnmpInfo->numOfIpv4Addresses; 5744 size += sizeof(t_DsarSnmpIpv6AddrTblEntry) 5745 * params->p_AutoResSnmpInfo->numOfIpv6Addresses; 5746 size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize; 5747 size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar; 5748 size += sizeof(t_DsarIcmpV6Statistics); 5749 } 5750 //filters 5751 size = ROUND_UP(size,4); 5752 if (params->p_AutoResFilteringInfo) 5753 { 5754 of->filtIp = size; 5755 size += params->p_AutoResFilteringInfo->ipProtTableSize; 5756 size = ROUND_UP(size,4); 5757 of->filtUdp = size; 5758 size += params->p_AutoResFilteringInfo->udpPortsTableSize 5759 * sizeof(t_PortTblEntry); 5760 size = ROUND_UP(size,4); 5761 of->filtTcp = size; 5762 size += params->p_AutoResFilteringInfo->tcpPortsTableSize 5763 * sizeof(t_PortTblEntry); 5764 } 5765 // add here for more protocols 5766 // statistics 5767 size = ROUND_UP(size,4); 5768 of->stats = size; 5769 size += sizeof(t_ArStatistics); 5770 return size; 5771 } 5772 5773 uint32_t* ARDesc; 5774 void PrsEnable(t_Handle p_FmPcd); 5775 void PrsDisable(t_Handle p_FmPcd); 5776 int PrsIsEnabled(t_Handle p_FmPcd); 5777 t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd); 5778 5779 static t_Error DsarCheckParams(t_FmPortDsarParams *params, 5780 t_FmPortDsarTablesSizes *sizes) 5781 { 5782 bool macInit = FALSE; 5783 uint8_t mac[6]; 5784 int i = 0; 5785 5786 // check table sizes 5787 if (params->p_AutoResArpInfo 5788 && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize) 5789 RETURN_ERROR( 5790 MAJOR, E_INVALID_VALUE, 5791 ("DSAR: Arp table size exceeds the configured maximum size.")); 5792 if (params->p_AutoResEchoIpv4Info 5793 && sizes->maxNumOfEchoIpv4Entries 5794 < params->p_AutoResEchoIpv4Info->tableSize) 5795 RETURN_ERROR( 5796 MAJOR, 5797 E_INVALID_VALUE, 5798 ("DSAR: EchoIpv4 table size exceeds the configured maximum size.")); 5799 if (params->p_AutoResNdpInfo 5800 && sizes->maxNumOfNdpEntries 5801 < params->p_AutoResNdpInfo->tableSizeAssigned 5802 + params->p_AutoResNdpInfo->tableSizeTmp) 5803 RETURN_ERROR( 5804 MAJOR, E_INVALID_VALUE, 5805 ("DSAR: NDP table size exceeds the configured maximum size.")); 5806 if (params->p_AutoResEchoIpv6Info 5807 && sizes->maxNumOfEchoIpv6Entries 5808 < params->p_AutoResEchoIpv6Info->tableSize) 5809 RETURN_ERROR( 5810 MAJOR, 5811 E_INVALID_VALUE, 5812 ("DSAR: EchoIpv6 table size exceeds the configured maximum size.")); 5813 if (params->p_AutoResSnmpInfo 5814 && sizes->maxNumOfSnmpOidEntries 5815 < params->p_AutoResSnmpInfo->oidsTblSize) 5816 RETURN_ERROR( 5817 MAJOR, 5818 E_INVALID_VALUE, 5819 ("DSAR: Snmp Oid table size exceeds the configured maximum size.")); 5820 if (params->p_AutoResSnmpInfo 5821 && sizes->maxNumOfSnmpIPV4Entries 5822 < params->p_AutoResSnmpInfo->numOfIpv4Addresses) 5823 RETURN_ERROR( 5824 MAJOR, 5825 E_INVALID_VALUE, 5826 ("DSAR: Snmp ipv4 table size exceeds the configured maximum size.")); 5827 if (params->p_AutoResSnmpInfo 5828 && sizes->maxNumOfSnmpIPV6Entries 5829 < params->p_AutoResSnmpInfo->numOfIpv6Addresses) 5830 RETURN_ERROR( 5831 MAJOR, 5832 E_INVALID_VALUE, 5833 ("DSAR: Snmp ipv6 table size exceeds the configured maximum size.")); 5834 if (params->p_AutoResFilteringInfo) 5835 { 5836 if (sizes->maxNumOfIpProtFiltering 5837 < params->p_AutoResFilteringInfo->ipProtTableSize) 5838 RETURN_ERROR( 5839 MAJOR, 5840 E_INVALID_VALUE, 5841 ("DSAR: ip filter table size exceeds the configured maximum size.")); 5842 if (sizes->maxNumOfTcpPortFiltering 5843 < params->p_AutoResFilteringInfo->udpPortsTableSize) 5844 RETURN_ERROR( 5845 MAJOR, 5846 E_INVALID_VALUE, 5847 ("DSAR: udp filter table size exceeds the configured maximum size.")); 5848 if (sizes->maxNumOfUdpPortFiltering 5849 < params->p_AutoResFilteringInfo->tcpPortsTableSize) 5850 RETURN_ERROR( 5851 MAJOR, 5852 E_INVALID_VALUE, 5853 ("DSAR: tcp filter table size exceeds the configured maximum size.")); 5854 } 5855 /* check only 1 MAC address is configured (this is what ucode currently supports) */ 5856 if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize) 5857 { 5858 memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6); 5859 i = 1; 5860 macInit = TRUE; 5861 5862 for (; i < params->p_AutoResArpInfo->tableSize; i++) 5863 if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6)) 5864 RETURN_ERROR( 5865 MAJOR, E_INVALID_VALUE, 5866 ("DSAR: Only 1 mac address is currently supported.")); 5867 } 5868 if (params->p_AutoResEchoIpv4Info 5869 && params->p_AutoResEchoIpv4Info->tableSize) 5870 { 5871 i = 0; 5872 if (!macInit) 5873 { 5874 memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac, 5875 6); 5876 i = 1; 5877 macInit = TRUE; 5878 } 5879 for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++) 5880 if (memcmp(mac, 5881 params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6)) 5882 RETURN_ERROR( 5883 MAJOR, E_INVALID_VALUE, 5884 ("DSAR: Only 1 mac address is currently supported.")); 5885 } 5886 if (params->p_AutoResEchoIpv6Info 5887 && params->p_AutoResEchoIpv6Info->tableSize) 5888 { 5889 i = 0; 5890 if (!macInit) 5891 { 5892 memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac, 5893 6); 5894 i = 1; 5895 macInit = TRUE; 5896 } 5897 for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++) 5898 if (memcmp(mac, 5899 params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6)) 5900 RETURN_ERROR( 5901 MAJOR, E_INVALID_VALUE, 5902 ("DSAR: Only 1 mac address is currently supported.")); 5903 } 5904 if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned) 5905 { 5906 i = 0; 5907 if (!macInit) 5908 { 5909 memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac, 5910 6); 5911 i = 1; 5912 macInit = TRUE; 5913 } 5914 for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++) 5915 if (memcmp(mac, 5916 params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac, 5917 6)) 5918 RETURN_ERROR( 5919 MAJOR, E_INVALID_VALUE, 5920 ("DSAR: Only 1 mac address is currently supported.")); 5921 } 5922 if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp) 5923 { 5924 i = 0; 5925 if (!macInit) 5926 { 5927 memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6); 5928 i = 1; 5929 } 5930 for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++) 5931 if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac, 5932 6)) 5933 RETURN_ERROR( 5934 MAJOR, E_INVALID_VALUE, 5935 ("DSAR: Only 1 mac address is currently supported.")); 5936 } 5937 return E_OK; 5938 } 5939 5940 static int GetBERLen(uint8_t* buf) 5941 { 5942 if (*buf & 0x80) 5943 { 5944 if ((*buf & 0x7F) == 1) 5945 return buf[1]; 5946 else 5947 return *(uint16_t*)&buf[1]; // assuming max len is 2 5948 } 5949 else 5950 return buf[0]; 5951 } 5952 #define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3 5953 5954 #ifdef TODO_SOC_SUSPEND // XXX 5955 #define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C 5956 #define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000 5957 #define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000 5958 static int fm_soc_suspend(void) 5959 { 5960 uint32_t *fmclk, tmp32; 5961 fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); 5962 tmp32 = GET_UINT32(*fmclk); 5963 WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL); 5964 tmp32 = GET_UINT32(*fmclk); 5965 iounmap(fmclk); 5966 return 0; 5967 } 5968 5969 void fm_clk_down(void) 5970 { 5971 uint32_t *fmclk, tmp32; 5972 fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); 5973 tmp32 = GET_UINT32(*fmclk); 5974 WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000); 5975 tmp32 = GET_UINT32(*fmclk); 5976 iounmap(fmclk); 5977 } 5978 #endif 5979 5980 #if 0 5981 t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params) 5982 { 5983 int i, j; 5984 t_Error err; 5985 uint32_t nia; 5986 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; 5987 t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx; 5988 t_DsarArpDescriptor *ArpDescriptor; 5989 t_DsarIcmpV4Descriptor* ICMPV4Descriptor; 5990 t_DsarIcmpV6Descriptor* ICMPV6Descriptor; 5991 t_DsarNdDescriptor* NDDescriptor; 5992 5993 uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr)); 5994 uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); 5995 t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page))); 5996 struct arOffsets* of; 5997 uint8_t tmp = 0; 5998 t_FmGetSetParams fmGetSetParams; 5999 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6000 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; 6001 fmGetSetParams.setParams.sleep = 1; 6002 6003 err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes); 6004 if (err != E_OK) 6005 return err; 6006 6007 p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets)); 6008 of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets; 6009 IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort)); 6010 6011 // common 6012 WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId); 6013 nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia 6014 if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser 6015 WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne)); 6016 else 6017 WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia); 6018 WRITE_UINT16(ArCommonDescPtr->snmpPort, 161); 6019 6020 // ARP 6021 if (params->p_AutoResArpInfo) 6022 { 6023 t_DsarArpBindingEntry* arp_bindings; 6024 ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp); 6025 WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr); 6026 arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor)); 6027 if (params->p_AutoResArpInfo->enableConflictDetection) 6028 WRITE_UINT16(ArpDescriptor->control, 1); 6029 else 6030 WRITE_UINT16(ArpDescriptor->control, 0); 6031 if (params->p_AutoResArpInfo->tableSize) 6032 { 6033 t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable; 6034 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]); 6035 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]); 6036 WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize); 6037 6038 for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++) 6039 { 6040 WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress); 6041 if (arp_entry[i].isVlan) 6042 WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF); 6043 } 6044 WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr); 6045 } 6046 WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) + 6047 sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr); 6048 } 6049 6050 // ICMPV4 6051 if (params->p_AutoResEchoIpv4Info) 6052 { 6053 t_DsarIcmpV4BindingEntry* icmpv4_bindings; 6054 ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4); 6055 WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr); 6056 icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor)); 6057 WRITE_UINT16(ICMPV4Descriptor->control, 0); 6058 if (params->p_AutoResEchoIpv4Info->tableSize) 6059 { 6060 t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable; 6061 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]); 6062 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]); 6063 WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize); 6064 6065 for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++) 6066 { 6067 WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress); 6068 if (arp_entry[i].isVlan) 6069 WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF); 6070 } 6071 WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr); 6072 } 6073 WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) + 6074 sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr); 6075 } 6076 6077 // ICMPV6 6078 if (params->p_AutoResEchoIpv6Info) 6079 { 6080 t_DsarIcmpV6BindingEntry* icmpv6_bindings; 6081 ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6); 6082 WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr); 6083 icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor)); 6084 WRITE_UINT16(ICMPV6Descriptor->control, 0); 6085 if (params->p_AutoResEchoIpv6Info->tableSize) 6086 { 6087 t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable; 6088 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]); 6089 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]); 6090 WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize); 6091 6092 for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++) 6093 { 6094 for (j = 0; j < 4; j++) 6095 WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]); 6096 if (ndp_entry[i].isVlan) 6097 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan 6098 } 6099 WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr); 6100 } 6101 WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + 6102 sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr); 6103 } 6104 6105 // ND 6106 if (params->p_AutoResNdpInfo) 6107 { 6108 t_DsarIcmpV6BindingEntry* icmpv6_bindings; 6109 NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd); 6110 WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr); 6111 icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor)); 6112 if (params->p_AutoResNdpInfo->enableConflictDetection) 6113 WRITE_UINT16(NDDescriptor->control, 1); 6114 else 6115 WRITE_UINT16(NDDescriptor->control, 0); 6116 if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp) 6117 { 6118 t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned; 6119 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]); 6120 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]); 6121 WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned 6122 + params->p_AutoResNdpInfo->tableSizeTmp); 6123 6124 for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++) 6125 { 6126 for (j = 0; j < 4; j++) 6127 WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]); 6128 if (ndp_entry[i].isVlan) 6129 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan 6130 } 6131 ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp; 6132 for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++) 6133 { 6134 for (j = 0; j < 4; j++) 6135 WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]); 6136 if (ndp_entry[i].isVlan) 6137 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan 6138 } 6139 WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr); 6140 } 6141 WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry) 6142 * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp) 6143 - fmMuramVirtBaseAddr); 6144 WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF); 6145 } 6146 6147 // SNMP 6148 if (params->p_AutoResSnmpInfo) 6149 { 6150 t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo; 6151 t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr; 6152 t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr; 6153 t_OidsTblEntry* snmpOid; 6154 uint8_t *charPointer; 6155 int len; 6156 t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp); 6157 WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr); 6158 WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control); 6159 WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength); 6160 snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor)); 6161 if (snmpSrc->numOfIpv4Addresses) 6162 { 6163 t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl; 6164 WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses); 6165 for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++) 6166 { 6167 WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr); 6168 if (snmpIpv4AddrSrc[i].isVlan) 6169 WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF); 6170 } 6171 WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr); 6172 } 6173 snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr) 6174 + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses); 6175 if (snmpSrc->numOfIpv6Addresses) 6176 { 6177 t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl; 6178 WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses); 6179 for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++) 6180 { 6181 for (j = 0; j < 4; j++) 6182 WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]); 6183 if (snmpIpv6AddrSrc[i].isVlan) 6184 WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF); 6185 } 6186 WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr); 6187 } 6188 snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr) 6189 + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses); 6190 charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid) 6191 + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize); 6192 len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1])); 6193 Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len); 6194 WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); 6195 charPointer += len; 6196 len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1])); 6197 Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len); 6198 WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); 6199 charPointer += len; 6200 WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize); 6201 WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr); 6202 for (i = 0; i < snmpSrc->oidsTblSize; i++) 6203 { 6204 WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize); 6205 WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize); 6206 Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize); 6207 WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); 6208 charPointer += snmpSrc->p_OidsTbl[i].oidSize; 6209 if (snmpSrc->p_OidsTbl[i].resSize <= 4) 6210 WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal); 6211 else 6212 { 6213 Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize); 6214 WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); 6215 charPointer += snmpSrc->p_OidsTbl[i].resSize; 6216 } 6217 snmpOid++; 6218 } 6219 charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4)); 6220 WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); 6221 } 6222 6223 // filtering 6224 if (params->p_AutoResFilteringInfo) 6225 { 6226 if (params->p_AutoResFilteringInfo->ipProtPassOnHit) 6227 tmp |= IP_PROT_TBL_PASS_MASK; 6228 if (params->p_AutoResFilteringInfo->udpPortPassOnHit) 6229 tmp |= UDP_PORT_TBL_PASS_MASK; 6230 if (params->p_AutoResFilteringInfo->tcpPortPassOnHit) 6231 tmp |= TCP_PORT_TBL_PASS_MASK; 6232 WRITE_UINT8(ArCommonDescPtr->filterControl, tmp); 6233 WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask); 6234 6235 // ip filtering 6236 if (params->p_AutoResFilteringInfo->ipProtTableSize) 6237 { 6238 uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp); 6239 WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize); 6240 for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++) 6241 WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]); 6242 WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr); 6243 } 6244 6245 // udp filtering 6246 if (params->p_AutoResFilteringInfo->udpPortsTableSize) 6247 { 6248 t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp); 6249 WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize); 6250 for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++) 6251 { 6252 WRITE_UINT32(udp_tbl[i].Ports, 6253 (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) + 6254 params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort); 6255 WRITE_UINT32(udp_tbl[i].PortsMask, 6256 (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) + 6257 params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask); 6258 } 6259 WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr); 6260 } 6261 6262 // tcp filtering 6263 if (params->p_AutoResFilteringInfo->tcpPortsTableSize) 6264 { 6265 t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp); 6266 WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize); 6267 for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++) 6268 { 6269 WRITE_UINT32(tcp_tbl[i].Ports, 6270 (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) + 6271 params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort); 6272 WRITE_UINT32(tcp_tbl[i].PortsMask, 6273 (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) + 6274 params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask); 6275 } 6276 WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr); 6277 } 6278 } 6279 // common stats 6280 WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr); 6281 6282 // get into Deep Sleep sequence: 6283 6284 // Ensures that FMan do not enter the idle state. This is done by programing 6285 // FMDPSLPCR[FM_STOP] to one. 6286 fm_soc_suspend(); 6287 6288 ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr)); 6289 return E_OK; 6290 6291 } 6292 6293 void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId); 6294 t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort) 6295 { 6296 t_FmGetSetParams fmGetSetParams; 6297 t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort; 6298 t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort; 6299 t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm); 6300 t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd); 6301 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6302 fmGetSetParams.setParams.type = UPDATE_FM_CLD; 6303 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6304 6305 /* Issue graceful stop to HC port */ 6306 FM_PORT_Disable(p_FmPortHc); 6307 6308 // config tx port 6309 p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg); 6310 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN); 6311 // ???? 6312 p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne); 6313 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE); 6314 // Stage 7:echo 6315 p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne); 6316 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E); 6317 if (!PrsIsEnabled(h_FmPcd)) 6318 { 6319 p_FmPort->deepSleepVars.dsarEnabledParser = TRUE; 6320 PrsEnable(h_FmPcd); 6321 } 6322 else 6323 p_FmPort->deepSleepVars.dsarEnabledParser = FALSE; 6324 6325 p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); 6326 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000); 6327 6328 // save rcfg for restoring: accumulate mode is changed by ucode 6329 p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg); 6330 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM); 6331 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6332 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; 6333 fmGetSetParams.setParams.sleep = 1; 6334 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6335 6336 // ***** issue external request sync command 6337 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6338 fmGetSetParams.setParams.type = UPDATE_FPM_EXTC; 6339 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6340 // get 6341 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6342 fmGetSetParams.getParams.type = GET_FMFP_EXTC; 6343 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6344 if (fmGetSetParams.getParams.fmfp_extc != 0) 6345 { 6346 // clear 6347 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6348 fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR; 6349 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6350 } 6351 6352 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6353 fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI; 6354 do 6355 { 6356 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6357 } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0); 6358 if (fmGetSetParams.getParams.fm_npi != 0) 6359 XX_Print("FM: Sync did not finish\n"); 6360 6361 // check that all stoped 6362 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6363 fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI; 6364 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6365 while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000) 6366 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6367 if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0) 6368 XX_Print("FM: Sleeping\n"); 6369 // FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId); 6370 6371 return E_OK; 6372 } 6373 6374 void FM_PORT_Dsar_DumpRegs() 6375 { 6376 uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc)); 6377 DUMP_MEMORY(hh, 0x220); 6378 } 6379 6380 void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx) 6381 { 6382 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; 6383 t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx; 6384 t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm); 6385 t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd); 6386 t_FmGetSetParams fmGetSetParams; 6387 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); 6388 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; 6389 fmGetSetParams.setParams.sleep = 0; 6390 if (p_FmPort->deepSleepVars.autoResOffsets) 6391 { 6392 XX_Free(p_FmPort->deepSleepVars.autoResOffsets); 6393 p_FmPort->deepSleepVars.autoResOffsets = 0; 6394 } 6395 6396 if (p_FmPort->deepSleepVars.dsarEnabledParser) 6397 PrsDisable(FmGetPcd(p_FmPort->h_Fm)); 6398 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne); 6399 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne); 6400 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg); 6401 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); 6402 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne); 6403 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg); 6404 FM_PORT_Enable(p_FmPortHc); 6405 } 6406 6407 bool FM_PORT_IsInDsar(t_Handle h_FmPort) 6408 { 6409 t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; 6410 return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets); 6411 } 6412 6413 t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats) 6414 { 6415 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; 6416 struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets; 6417 uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr); 6418 uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); 6419 t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page))); 6420 t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp); 6421 t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr); 6422 t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4); 6423 t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr); 6424 t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd); 6425 t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr); 6426 t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6); 6427 t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr); 6428 t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp); 6429 t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr); 6430 stats->arpArCnt = arp_stats->arCnt; 6431 stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt; 6432 stats->ndpArCnt = nd_stats->arCnt; 6433 stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt; 6434 stats->snmpGetCnt = snmp_stats->snmpGetReqCnt; 6435 stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt; 6436 return E_OK; 6437 } 6438 #endif 6439