1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2008-2012 Freescale Semiconductor Inc. 3254885Sdumbbell * 4254885Sdumbbell * Redistribution and use in source and binary forms, with or without 5254885Sdumbbell * modification, are permitted provided that the following conditions are met: 6254885Sdumbbell * * Redistributions of source code must retain the above copyright 7254885Sdumbbell * notice, this list of conditions and the following disclaimer. 8254885Sdumbbell * * Redistributions in binary form must reproduce the above copyright 9254885Sdumbbell * notice, this list of conditions and the following disclaimer in the 10254885Sdumbbell * documentation and/or other materials provided with the distribution. 11254885Sdumbbell * * Neither the name of Freescale Semiconductor nor the 12254885Sdumbbell * names of its contributors may be used to endorse or promote products 13254885Sdumbbell * derived from this software without specific prior written permission. 14254885Sdumbbell * 15254885Sdumbbell * 16254885Sdumbbell * ALTERNATIVELY, this software may be distributed under the terms of the 17254885Sdumbbell * GNU General Public License ("GPL") as published by the Free Software 18254885Sdumbbell * Foundation, either version 2 of that License or (at your option) any 19254885Sdumbbell * later version. 20254885Sdumbbell * 21254885Sdumbbell * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22254885Sdumbbell * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23254885Sdumbbell * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24254885Sdumbbell * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25254885Sdumbbell * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26254885Sdumbbell * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27254885Sdumbbell * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28254885Sdumbbell * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29254885Sdumbbell * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30254885Sdumbbell * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31254885Sdumbbell */ 32254885Sdumbbell 33254885Sdumbbell 34254885Sdumbbell/****************************************************************************** 35254885Sdumbbell @File fm_port.c 36254885Sdumbbell 37254885Sdumbbell @Description FM driver routines implementation. 38254885Sdumbbell *//***************************************************************************/ 39254885Sdumbbell#include "error_ext.h" 40254885Sdumbbell#include "std_ext.h" 41254885Sdumbbell#include "string_ext.h" 42254885Sdumbbell#include "sprint_ext.h" 43254885Sdumbbell#include "debug_ext.h" 44254885Sdumbbell#include "fm_muram_ext.h" 45254885Sdumbbell 46254885Sdumbbell#include "fman_common.h" 47254885Sdumbbell#include "fm_port.h" 48254885Sdumbbell#include "fm_port_dsar.h" 49254885Sdumbbell#include "common/general.h" 50254885Sdumbbell 51254885Sdumbbell/****************************************/ 52254885Sdumbbell/* static functions */ 53254885Sdumbbell/****************************************/ 54254885Sdumbbellstatic t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort); 55254885Sdumbbell 56254885Sdumbbellstatic t_Error CheckInitParameters(t_FmPort *p_FmPort) 57254885Sdumbbell{ 58254885Sdumbbell t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; 59254885Sdumbbell struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg; 60254885Sdumbbell t_Error ans = E_OK; 61254885Sdumbbell uint32_t unusedMask; 62254885Sdumbbell 63254885Sdumbbell if (p_FmPort->imEn) 64254885Sdumbbell { 65254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 66254885Sdumbbell if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 67254885Sdumbbell > 2) 68254885Sdumbbell RETURN_ERROR( 69254885Sdumbbell MAJOR, 70254885Sdumbbell E_INVALID_VALUE, 71254885Sdumbbell ("fifoDeqPipelineDepth for IM 10G can't be larger than 2")); 72254885Sdumbbell 73254885Sdumbbell if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK) 74254885Sdumbbell return ERROR_CODE(ans); 75254885Sdumbbell } 76254885Sdumbbell else 77254885Sdumbbell { 78254885Sdumbbell /****************************************/ 79254885Sdumbbell /* Rx only */ 80254885Sdumbbell /****************************************/ 81254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 82254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 83254885Sdumbbell { 84254885Sdumbbell /* external buffer pools */ 85254885Sdumbbell if (!p_Params->extBufPools.numOfPoolsUsed) 86254885Sdumbbell RETURN_ERROR( 87254885Sdumbbell MAJOR, 88254885Sdumbbell E_INVALID_VALUE, 89254885Sdumbbell ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined")); 90254885Sdumbbell 91254885Sdumbbell if (FmSpCheckBufPoolsParams(&p_Params->extBufPools, 92254885Sdumbbell p_Params->p_BackupBmPools, 93254885Sdumbbell &p_Params->bufPoolDepletion) != E_OK) 94254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 95254885Sdumbbell 96254885Sdumbbell /* Check that part of IC that needs copying is small enough to enter start margin */ 97254885Sdumbbell if (p_Params->intContext.size 98254885Sdumbbell && (p_Params->intContext.size 99254885Sdumbbell + p_Params->intContext.extBufOffset 100254885Sdumbbell > p_Params->bufMargins.startMargins)) 101254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 102254885Sdumbbell ("intContext.size is larger than start margins")); 103254885Sdumbbell 104254885Sdumbbell if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE) 105254885Sdumbbell && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK)) 106254885Sdumbbell RETURN_ERROR( 107254885Sdumbbell MAJOR, 108254885Sdumbbell E_INVALID_VALUE, 109254885Sdumbbell ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); 110254885Sdumbbell 111254885Sdumbbell#ifdef FM_NO_BACKUP_POOLS 112254885Sdumbbell if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6)) 113254885Sdumbbell if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 114254885Sdumbbell RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools")); 115254885Sdumbbell#endif /* FM_NO_BACKUP_POOLS */ 116254885Sdumbbell } 117254885Sdumbbell 118254885Sdumbbell /****************************************/ 119254885Sdumbbell /* Non Rx ports */ 120254885Sdumbbell /****************************************/ 121254885Sdumbbell else 122254885Sdumbbell { 123254885Sdumbbell if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS) 124254885Sdumbbell RETURN_ERROR( 125254885Sdumbbell MAJOR, 126254885Sdumbbell E_INVALID_VALUE, 127254885Sdumbbell (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS)); 128254885Sdumbbell 129254885Sdumbbell /* to protect HW internal-context from overwrite */ 130254885Sdumbbell if ((p_Params->intContext.size) 131254885Sdumbbell && (p_Params->intContext.intContextOffset 132254885Sdumbbell < MIN_TX_INT_OFFSET)) 133254885Sdumbbell RETURN_ERROR( 134254885Sdumbbell MAJOR, 135254885Sdumbbell E_INVALID_VALUE, 136254885Sdumbbell ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET)); 137254885Sdumbbell 138254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 139254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 140254885Sdumbbell /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */ 141254885Sdumbbell || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 142254885Sdumbbell != DEFAULT_notSupported)) 143254885Sdumbbell { 144254885Sdumbbell /* Check that not larger than 8 */ 145254885Sdumbbell if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth) 146254885Sdumbbell || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 147254885Sdumbbell > MAX_FIFO_PIPELINE_DEPTH)) 148254885Sdumbbell RETURN_ERROR( 149254885Sdumbbell MAJOR, 150254885Sdumbbell E_INVALID_VALUE, 151254885Sdumbbell ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH)); 152254885Sdumbbell } 153254885Sdumbbell } 154254885Sdumbbell 155254885Sdumbbell /****************************************/ 156254885Sdumbbell /* Rx Or Offline Parsing */ 157254885Sdumbbell /****************************************/ 158254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 159254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 160254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 161254885Sdumbbell { 162254885Sdumbbell if (!p_Params->dfltFqid) 163254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 164254885Sdumbbell ("dfltFqid must be between 1 and 2^24-1")); 165254885Sdumbbell#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004) 166254885Sdumbbell if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16) 167254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16")); 168254885Sdumbbell#endif /* defined(FM_CAPWAP_SUPPORT) && ... */ 169254885Sdumbbell } 170254885Sdumbbell 171254885Sdumbbell /****************************************/ 172254885Sdumbbell /* All ports */ 173254885Sdumbbell /****************************************/ 174254885Sdumbbell /* common BMI registers values */ 175254885Sdumbbell /* Check that Queue Id is not larger than 2^24, and is not 0 */ 176254885Sdumbbell if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid) 177254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 178254885Sdumbbell ("errFqid must be between 1 and 2^24-1")); 179254885Sdumbbell if (p_Params->dfltFqid & ~0x00FFFFFF) 180254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 181254885Sdumbbell ("dfltFqid must be between 1 and 2^24-1")); 182254885Sdumbbell } 183254885Sdumbbell 184254885Sdumbbell /****************************************/ 185254885Sdumbbell /* Rx only */ 186254885Sdumbbell /****************************************/ 187254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 188254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 189254885Sdumbbell { 190254885Sdumbbell if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS) 191254885Sdumbbell RETURN_ERROR( 192254885Sdumbbell MAJOR, 193254885Sdumbbell E_INVALID_VALUE, 194254885Sdumbbell ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS)); 195254885Sdumbbell if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS) 196254885Sdumbbell || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE)) 197254885Sdumbbell RETURN_ERROR( 198254885Sdumbbell MAJOR, 199254885Sdumbbell E_INVALID_VALUE, 200254885Sdumbbell ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 201254885Sdumbbell if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS) 202254885Sdumbbell RETURN_ERROR( 203254885Sdumbbell MAJOR, 204254885Sdumbbell E_INVALID_VALUE, 205254885Sdumbbell ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS)); 206254885Sdumbbell if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS) 207254885Sdumbbell || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE)) 208254885Sdumbbell RETURN_ERROR( 209254885Sdumbbell MAJOR, 210254885Sdumbbell E_INVALID_VALUE, 211254885Sdumbbell ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 212254885Sdumbbell 213254885Sdumbbell /* Check that not larger than 16 */ 214254885Sdumbbell if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE) 215254885Sdumbbell RETURN_ERROR( 216254885Sdumbbell MAJOR, 217254885Sdumbbell E_INVALID_VALUE, 218254885Sdumbbell ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); 219254885Sdumbbell 220254885Sdumbbell if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK) 221254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 222254885Sdumbbell 223254885Sdumbbell /* extra FIFO size (allowed only to Rx ports) */ 224254885Sdumbbell if (p_Params->setSizeOfFifo 225254885Sdumbbell && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS)) 226254885Sdumbbell RETURN_ERROR( 227254885Sdumbbell MAJOR, 228254885Sdumbbell E_INVALID_VALUE, 229254885Sdumbbell ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS)); 230254885Sdumbbell 231254885Sdumbbell if (p_Params->bufPoolDepletion.poolsGrpModeEnable 232254885Sdumbbell && !p_Params->bufPoolDepletion.numOfPools) 233254885Sdumbbell RETURN_ERROR( 234254885Sdumbbell MAJOR, 235254885Sdumbbell E_INVALID_VALUE, 236254885Sdumbbell ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE")); 237254885Sdumbbell#ifdef FM_CSI_CFED_LIMIT 238254885Sdumbbell if (p_FmPort->fmRevInfo.majorRev == 4) 239254885Sdumbbell { 240254885Sdumbbell /* Check that not larger than 16 */ 241254885Sdumbbell if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE) 242254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); 243254885Sdumbbell } 244254885Sdumbbell#endif /* FM_CSI_CFED_LIMIT */ 245254885Sdumbbell } 246254885Sdumbbell 247254885Sdumbbell /****************************************/ 248254885Sdumbbell /* Non Rx ports */ 249254885Sdumbbell /****************************************/ 250254885Sdumbbell /* extra FIFO size (allowed only to Rx ports) */ 251254885Sdumbbell else 252254885Sdumbbell if (p_FmPort->fifoBufs.extra) 253254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 254254885Sdumbbell (" No fifoBufs.extra for non Rx ports")); 255254885Sdumbbell 256254885Sdumbbell /****************************************/ 257254885Sdumbbell /* Tx only */ 258254885Sdumbbell /****************************************/ 259254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 260254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) 261254885Sdumbbell { 262254885Sdumbbell if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS) 263254885Sdumbbell RETURN_ERROR( 264254885Sdumbbell MAJOR, 265254885Sdumbbell E_INVALID_VALUE, 266254885Sdumbbell ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS)); 267254885Sdumbbell if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256)) 268254885Sdumbbell RETURN_ERROR( 269254885Sdumbbell MAJOR, 270254885Sdumbbell E_INVALID_VALUE, 271254885Sdumbbell ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256))); 272254885Sdumbbell if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS) 273254885Sdumbbell RETURN_ERROR( 274254885Sdumbbell MAJOR, 275254885Sdumbbell E_INVALID_VALUE, 276254885Sdumbbell ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS)); 277254885Sdumbbell if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS) 278254885Sdumbbell || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE)) 279254885Sdumbbell RETURN_ERROR( 280254885Sdumbbell MAJOR, 281254885Sdumbbell E_INVALID_VALUE, 282254885Sdumbbell ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 283254885Sdumbbell 284254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_TX) 285254885Sdumbbell if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 286254885Sdumbbell > 2) 287254885Sdumbbell RETURN_ERROR( 288254885Sdumbbell MAJOR, E_INVALID_VALUE, 289254885Sdumbbell ("fifoDeqPipelineDepth for 1G can't be larger than 2")); 290254885Sdumbbell } 291254885Sdumbbell 292254885Sdumbbell /****************************************/ 293254885Sdumbbell /* Non Tx Ports */ 294254885Sdumbbell /****************************************/ 295254885Sdumbbell /* If discard override was selected , no frames may be discarded. */ 296254885Sdumbbell else 297254885Sdumbbell if (p_DfltConfig->discard_override && p_Params->errorsToDiscard) 298254885Sdumbbell RETURN_ERROR( 299254885Sdumbbell MAJOR, 300254885Sdumbbell E_CONFLICT, 301254885Sdumbbell ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue).")); 302254885Sdumbbell 303254885Sdumbbell /****************************************/ 304254885Sdumbbell /* Rx and Offline parsing */ 305254885Sdumbbell /****************************************/ 306254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) 307254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 308254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 309254885Sdumbbell { 310254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 311254885Sdumbbell unusedMask = BMI_STATUS_OP_MASK_UNUSED; 312254885Sdumbbell else 313254885Sdumbbell unusedMask = BMI_STATUS_RX_MASK_UNUSED; 314254885Sdumbbell 315254885Sdumbbell /* Check that no common bits with BMI_STATUS_MASK_UNUSED */ 316254885Sdumbbell if (p_Params->errorsToDiscard & unusedMask) 317254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_SELECTION, 318254885Sdumbbell ("errorsToDiscard contains undefined bits")); 319254885Sdumbbell } 320254885Sdumbbell 321254885Sdumbbell /****************************************/ 322254885Sdumbbell /* Offline Ports */ 323254885Sdumbbell /****************************************/ 324254885Sdumbbell#ifdef FM_OP_OPEN_DMA_MIN_LIMIT 325254885Sdumbbell if ((p_FmPort->fmRevInfo.majorRev >= 6) 326254885Sdumbbell && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 327254885Sdumbbell && p_Params->setNumOfOpenDmas 328254885Sdumbbell && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS)) 329254885Sdumbbell RETURN_ERROR( 330254885Sdumbbell MAJOR, 331254885Sdumbbell E_INVALID_VALUE, 332254885Sdumbbell ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS)); 333254885Sdumbbell#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */ 334254885Sdumbbell 335254885Sdumbbell /****************************************/ 336254885Sdumbbell /* Offline & HC Ports */ 337254885Sdumbbell /****************************************/ 338254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 339254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 340254885Sdumbbell { 341254885Sdumbbell#ifndef FM_FRAME_END_PARAMS_FOR_OP 342254885Sdumbbell if ((p_FmPort->fmRevInfo.majorRev < 6) && 343254885Sdumbbell (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported)) 344254885Sdumbbell /* this is an indication that user called config for this mode which is not supported in this integration */ 345254885Sdumbbell RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only")); 346254885Sdumbbell#endif /* !FM_FRAME_END_PARAMS_FOR_OP */ 347254885Sdumbbell 348254885Sdumbbell#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP 349254885Sdumbbell if ((!((p_FmPort->fmRevInfo.majorRev == 4) || 350254885Sdumbbell (p_FmPort->fmRevInfo.majorRev >= 6))) && 351254885Sdumbbell (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported)) 352254885Sdumbbell /* this is an indication that user called config for this mode which is not supported in this integration */ 353254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only")); 354254885Sdumbbell#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ 355254885Sdumbbell } 356254885Sdumbbell 357254885Sdumbbell /****************************************/ 358254885Sdumbbell /* All ports */ 359254885Sdumbbell /****************************************/ 360254885Sdumbbell /* Check that not larger than 16 */ 361254885Sdumbbell if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) 362254885Sdumbbell && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported))) 363254885Sdumbbell RETURN_ERROR( 364254885Sdumbbell MAJOR, 365254885Sdumbbell E_INVALID_VALUE, 366254885Sdumbbell ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE)); 367254885Sdumbbell 368254885Sdumbbell if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK) 369254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 370254885Sdumbbell 371254885Sdumbbell /* common BMI registers values */ 372254885Sdumbbell if (p_Params->setNumOfTasks 373254885Sdumbbell && ((!p_FmPort->tasks.num) 374254885Sdumbbell || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS))) 375254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 376254885Sdumbbell ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS)); 377254885Sdumbbell if (p_Params->setNumOfTasks 378254885Sdumbbell && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS)) 379254885Sdumbbell RETURN_ERROR( 380254885Sdumbbell MAJOR, 381254885Sdumbbell E_INVALID_VALUE, 382254885Sdumbbell ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); 383254885Sdumbbell if (p_Params->setNumOfOpenDmas 384254885Sdumbbell && ((!p_FmPort->openDmas.num) 385254885Sdumbbell || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS))) 386254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 387254885Sdumbbell ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS)); 388254885Sdumbbell if (p_Params->setNumOfOpenDmas 389254885Sdumbbell && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS)) 390254885Sdumbbell RETURN_ERROR( 391254885Sdumbbell MAJOR, 392254885Sdumbbell E_INVALID_VALUE, 393254885Sdumbbell ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); 394254885Sdumbbell if (p_Params->setSizeOfFifo 395254885Sdumbbell && (!p_FmPort->fifoBufs.num 396254885Sdumbbell || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE))) 397254885Sdumbbell RETURN_ERROR( 398254885Sdumbbell MAJOR, 399254885Sdumbbell E_INVALID_VALUE, 400254885Sdumbbell ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); 401254885Sdumbbell if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS)) 402254885Sdumbbell RETURN_ERROR( 403254885Sdumbbell MAJOR, E_INVALID_VALUE, 404254885Sdumbbell ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS)); 405254885Sdumbbell 406254885Sdumbbell#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT 407254885Sdumbbell if (p_FmPort->fmRevInfo.majorRev == 4) 408254885Sdumbbell if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported) 409254885Sdumbbell /* this is an indication that user called config for this mode which is not supported in this integration */ 410254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption")); 411254885Sdumbbell#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ 412254885Sdumbbell 413254885Sdumbbell return E_OK; 414254885Sdumbbell} 415254885Sdumbbell 416254885Sdumbbellstatic t_Error VerifySizeOfFifo(t_FmPort *p_FmPort) 417254885Sdumbbell{ 418254885Sdumbbell uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0; 419254885Sdumbbell 420254885Sdumbbell /*************************/ 421254885Sdumbbell /* TX PORTS */ 422254885Sdumbbell /*************************/ 423254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) 424254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) 425254885Sdumbbell { 426254885Sdumbbell minFifoSizeRequired = 427254885Sdumbbell (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 428254885Sdumbbell + (3 * BMI_FIFO_UNITS)); 429254885Sdumbbell if (!p_FmPort->imEn) 430254885Sdumbbell minFifoSizeRequired += 431254885Sdumbbell p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 432254885Sdumbbell * BMI_FIFO_UNITS; 433254885Sdumbbell 434254885Sdumbbell optFifoSizeForB2B = minFifoSizeRequired; 435254885Sdumbbell 436254885Sdumbbell /* Add some margin for back-to-back capability to improve performance, 437254885Sdumbbell allows the hardware to pipeline new frame dma while the previous 438254885Sdumbbell frame not yet transmitted. */ 439254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 440254885Sdumbbell optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; 441254885Sdumbbell else 442254885Sdumbbell optFifoSizeForB2B += 2 * BMI_FIFO_UNITS; 443254885Sdumbbell } 444254885Sdumbbell 445254885Sdumbbell /*************************/ 446254885Sdumbbell /* RX IM PORTS */ 447254885Sdumbbell /*************************/ 448254885Sdumbbell else 449254885Sdumbbell if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) 450254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 451254885Sdumbbell && p_FmPort->imEn) 452254885Sdumbbell { 453254885Sdumbbell optFifoSizeForB2B = 454254885Sdumbbell minFifoSizeRequired = 455254885Sdumbbell (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 456254885Sdumbbell + (4 * BMI_FIFO_UNITS)); 457254885Sdumbbell } 458254885Sdumbbell 459254885Sdumbbell /*************************/ 460254885Sdumbbell /* RX non-IM PORTS */ 461254885Sdumbbell /*************************/ 462254885Sdumbbell else 463254885Sdumbbell if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) 464254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 465254885Sdumbbell && !p_FmPort->imEn) 466254885Sdumbbell { 467254885Sdumbbell if (p_FmPort->fmRevInfo.majorRev == 4) 468254885Sdumbbell { 469254885Sdumbbell if (p_FmPort->rxPoolsParams.numOfPools == 1) 470254885Sdumbbell minFifoSizeRequired = 8 * BMI_FIFO_UNITS; 471254885Sdumbbell else 472254885Sdumbbell minFifoSizeRequired = 473254885Sdumbbell (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS) 474254885Sdumbbell + (7 * BMI_FIFO_UNITS)); 475254885Sdumbbell } 476254885Sdumbbell else 477254885Sdumbbell { 478254885Sdumbbell#if (DPAA_VERSION >= 11) 479254885Sdumbbell minFifoSizeRequired = 480254885Sdumbbell (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 481254885Sdumbbell + (5 * BMI_FIFO_UNITS)); 482254885Sdumbbell /* 4 according to spec + 1 for FOF>0 */ 483254885Sdumbbell#else 484254885Sdumbbell minFifoSizeRequired = (uint32_t) 485254885Sdumbbell (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS) 486254885Sdumbbell + (7*BMI_FIFO_UNITS)); 487254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */ 488254885Sdumbbell } 489254885Sdumbbell 490254885Sdumbbell optFifoSizeForB2B = minFifoSizeRequired; 491254885Sdumbbell 492254885Sdumbbell /* Add some margin for back-to-back capability to improve performance, 493254885Sdumbbell allows the hardware to pipeline new frame dma while the previous 494254885Sdumbbell frame not yet transmitted. */ 495254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 496254885Sdumbbell optFifoSizeForB2B += 8 * BMI_FIFO_UNITS; 497254885Sdumbbell else 498254885Sdumbbell optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; 499254885Sdumbbell } 500254885Sdumbbell 501254885Sdumbbell /* For O/H ports, check fifo size and update if necessary */ 502254885Sdumbbell else 503254885Sdumbbell if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 504254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 505254885Sdumbbell { 506254885Sdumbbell#if (DPAA_VERSION >= 11) 507254885Sdumbbell optFifoSizeForB2B = 508254885Sdumbbell minFifoSizeRequired = 509254885Sdumbbell (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) 510254885Sdumbbell + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth 511254885Sdumbbell + 5) * BMI_FIFO_UNITS)); 512254885Sdumbbell /* 4 according to spec + 1 for FOF>0 */ 513254885Sdumbbell#else 514254885Sdumbbell optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS); 515254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */ 516254885Sdumbbell } 517254885Sdumbbell 518254885Sdumbbell ASSERT_COND(minFifoSizeRequired > 0); 519254885Sdumbbell ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired); 520254885Sdumbbell 521254885Sdumbbell /* Verify the size */ 522254885Sdumbbell if (p_FmPort->fifoBufs.num < minFifoSizeRequired) 523254885Sdumbbell DBG(INFO, 524254885Sdumbbell ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired)); 525254885Sdumbbell else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B) 526254885Sdumbbell DBG(INFO, 527254885Sdumbbell ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B)); 528254885Sdumbbell 529254885Sdumbbell return E_OK; 530254885Sdumbbell} 531254885Sdumbbell 532254885Sdumbbellstatic void FmPortDriverParamFree(t_FmPort *p_FmPort) 533254885Sdumbbell{ 534254885Sdumbbell if (p_FmPort->p_FmPortDriverParam) 535254885Sdumbbell { 536254885Sdumbbell XX_Free(p_FmPort->p_FmPortDriverParam); 537254885Sdumbbell p_FmPort->p_FmPortDriverParam = NULL; 538254885Sdumbbell } 539254885Sdumbbell} 540254885Sdumbbell 541254885Sdumbbellstatic t_Error SetExtBufferPools(t_FmPort *p_FmPort) 542254885Sdumbbell{ 543254885Sdumbbell t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools; 544254885Sdumbbell t_FmBufPoolDepletion *p_BufPoolDepletion = 545254885Sdumbbell &p_FmPort->p_FmPortDriverParam->bufPoolDepletion; 546254885Sdumbbell uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; 547254885Sdumbbell uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; 548254885Sdumbbell int i = 0, j = 0, err; 549254885Sdumbbell struct fman_port_bpools bpools; 550254885Sdumbbell 551254885Sdumbbell memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS); 552254885Sdumbbell memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS); 553254885Sdumbbell memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools)); 554254885Sdumbbell 555254885Sdumbbell FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray, 556254885Sdumbbell sizesArray); 557254885Sdumbbell 558254885Sdumbbell /* Prepare flibs bpools structure */ 559254885Sdumbbell memset(&bpools, 0, sizeof(struct fman_port_bpools)); 560254885Sdumbbell bpools.count = p_ExtBufPools->numOfPoolsUsed; 561254885Sdumbbell bpools.counters_enable = TRUE; 562254885Sdumbbell for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++) 563254885Sdumbbell { 564254885Sdumbbell bpools.bpool[i].bpid = orderedArray[i]; 565254885Sdumbbell bpools.bpool[i].size = sizesArray[orderedArray[i]]; 566254885Sdumbbell /* functionality available only for some derivatives (limited by config) */ 567254885Sdumbbell if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 568254885Sdumbbell for (j = 0; 569254885Sdumbbell j 570254885Sdumbbell < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools; 571254885Sdumbbell j++) 572254885Sdumbbell if (orderedArray[i] 573254885Sdumbbell == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j]) 574254885Sdumbbell { 575254885Sdumbbell bpools.bpool[i].is_backup = TRUE; 576254885Sdumbbell break; 577254885Sdumbbell } 578254885Sdumbbell } 579254885Sdumbbell 580254885Sdumbbell /* save pools parameters for later use */ 581254885Sdumbbell p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed; 582254885Sdumbbell p_FmPort->rxPoolsParams.largestBufSize = 583254885Sdumbbell sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]]; 584254885Sdumbbell p_FmPort->rxPoolsParams.secondLargestBufSize = 585254885Sdumbbell sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]]; 586254885Sdumbbell 587254885Sdumbbell /* FMBM_RMPD reg. - pool depletion */ 588254885Sdumbbell if (p_BufPoolDepletion->poolsGrpModeEnable) 589254885Sdumbbell { 590254885Sdumbbell bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools; 591254885Sdumbbell for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++) 592254885Sdumbbell { 593254885Sdumbbell if (p_BufPoolDepletion->poolsToConsider[i]) 594254885Sdumbbell { 595254885Sdumbbell for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) 596254885Sdumbbell { 597254885Sdumbbell if (i == orderedArray[j]) 598254885Sdumbbell { 599254885Sdumbbell bpools.bpool[j].grp_bp_depleted = TRUE; 600254885Sdumbbell break; 601254885Sdumbbell } 602254885Sdumbbell } 603254885Sdumbbell } 604254885Sdumbbell } 605254885Sdumbbell } 606254885Sdumbbell 607254885Sdumbbell if (p_BufPoolDepletion->singlePoolModeEnable) 608254885Sdumbbell { 609254885Sdumbbell for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++) 610254885Sdumbbell { 611254885Sdumbbell if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i]) 612254885Sdumbbell { 613254885Sdumbbell for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) 614254885Sdumbbell { 615254885Sdumbbell if (i == orderedArray[j]) 616254885Sdumbbell { 617254885Sdumbbell bpools.bpool[j].single_bp_depleted = TRUE; 618254885Sdumbbell break; 619254885Sdumbbell } 620254885Sdumbbell } 621254885Sdumbbell } 622254885Sdumbbell } 623254885Sdumbbell } 624254885Sdumbbell 625254885Sdumbbell#if (DPAA_VERSION >= 11) 626254885Sdumbbell /* fill QbbPEV */ 627254885Sdumbbell if (p_BufPoolDepletion->poolsGrpModeEnable 628254885Sdumbbell || p_BufPoolDepletion->singlePoolModeEnable) 629254885Sdumbbell { 630254885Sdumbbell for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++) 631254885Sdumbbell { 632254885Sdumbbell if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE) 633254885Sdumbbell { 634254885Sdumbbell bpools.bpool[i].pfc_priorities_en = TRUE; 635254885Sdumbbell } 636254885Sdumbbell } 637254885Sdumbbell } 638254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */ 639254885Sdumbbell 640254885Sdumbbell /* Issue flibs function */ 641254885Sdumbbell err = fman_port_set_bpools(&p_FmPort->port, &bpools); 642254885Sdumbbell if (err != 0) 643254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools")); 644254885Sdumbbell 645254885Sdumbbell if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 646254885Sdumbbell XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools); 647254885Sdumbbell 648254885Sdumbbell return E_OK; 649254885Sdumbbell} 650254885Sdumbbell 651254885Sdumbbellstatic t_Error ClearPerfCnts(t_FmPort *p_FmPort) 652254885Sdumbbell{ 653254885Sdumbbell if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 654254885Sdumbbell FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0); 655254885Sdumbbell FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0); 656254885Sdumbbell FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0); 657254885Sdumbbell FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0); 658254885Sdumbbell return E_OK; 659254885Sdumbbell} 660254885Sdumbbell 661254885Sdumbbellstatic t_Error InitLowLevelDriver(t_FmPort *p_FmPort) 662254885Sdumbbell{ 663254885Sdumbbell t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam; 664254885Sdumbbell struct fman_port_params portParams; 665254885Sdumbbell uint32_t tmpVal; 666254885Sdumbbell t_Error err; 667254885Sdumbbell 668254885Sdumbbell /* Set up flibs parameters and issue init function */ 669254885Sdumbbell 670254885Sdumbbell memset(&portParams, 0, sizeof(struct fman_port_params)); 671254885Sdumbbell portParams.discard_mask = p_DriverParams->errorsToDiscard; 672254885Sdumbbell portParams.dflt_fqid = p_DriverParams->dfltFqid; 673254885Sdumbbell portParams.err_fqid = p_DriverParams->errFqid; 674254885Sdumbbell portParams.deq_sp = p_DriverParams->deqSubPortal; 675254885Sdumbbell portParams.dont_release_buf = p_DriverParams->dontReleaseBuf; 676254885Sdumbbell switch (p_FmPort->portType) 677254885Sdumbbell { 678254885Sdumbbell case (e_FM_PORT_TYPE_RX_10G): 679254885Sdumbbell case (e_FM_PORT_TYPE_RX): 680254885Sdumbbell portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask); 681254885Sdumbbell if (!p_FmPort->imEn) 682254885Sdumbbell { 683254885Sdumbbell if (p_DriverParams->forwardReuseIntContext) 684254885Sdumbbell p_DriverParams->dfltCfg.rx_fd_bits = 685254885Sdumbbell (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24); 686254885Sdumbbell } 687254885Sdumbbell break; 688254885Sdumbbell 689254885Sdumbbell case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 690254885Sdumbbell portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask); 691254885Sdumbbell break; 692254885Sdumbbell break; 693254885Sdumbbell 694254885Sdumbbell default: 695254885Sdumbbell break; 696254885Sdumbbell } 697254885Sdumbbell 698254885Sdumbbell tmpVal = 699254885Sdumbbell (uint32_t)( 700254885Sdumbbell (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset 701254885Sdumbbell / OFFSET_UNITS + 1) : 702254885Sdumbbell (p_FmPort->internalBufferOffset / OFFSET_UNITS)); 703254885Sdumbbell p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS); 704254885Sdumbbell p_DriverParams->dfltCfg.int_buf_start_margin = 705254885Sdumbbell p_FmPort->internalBufferOffset; 706254885Sdumbbell 707254885Sdumbbell p_DriverParams->dfltCfg.ext_buf_start_margin = 708254885Sdumbbell p_DriverParams->bufMargins.startMargins; 709254885Sdumbbell p_DriverParams->dfltCfg.ext_buf_end_margin = 710254885Sdumbbell p_DriverParams->bufMargins.endMargins; 711254885Sdumbbell 712254885Sdumbbell p_DriverParams->dfltCfg.ic_ext_offset = 713254885Sdumbbell p_DriverParams->intContext.extBufOffset; 714254885Sdumbbell p_DriverParams->dfltCfg.ic_int_offset = 715254885Sdumbbell p_DriverParams->intContext.intContextOffset; 716254885Sdumbbell p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size; 717254885Sdumbbell 718254885Sdumbbell p_DriverParams->dfltCfg.stats_counters_enable = TRUE; 719254885Sdumbbell p_DriverParams->dfltCfg.perf_counters_enable = TRUE; 720254885Sdumbbell p_DriverParams->dfltCfg.queue_counters_enable = TRUE; 721254885Sdumbbell 722254885Sdumbbell p_DriverParams->dfltCfg.perf_cnt_params.task_val = 723254885Sdumbbell (uint8_t)p_FmPort->tasks.num; 724254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING || 725254885Sdumbbell p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0; 726254885Sdumbbell else 727254885Sdumbbell p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1; 728254885Sdumbbell p_DriverParams->dfltCfg.perf_cnt_params.dma_val = 729254885Sdumbbell (uint8_t)p_FmPort->openDmas.num; 730254885Sdumbbell p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num; 731254885Sdumbbell 732254885Sdumbbell if (0 733254885Sdumbbell != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg, 734254885Sdumbbell &portParams)) 735254885Sdumbbell RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init")); 736254885Sdumbbell 737254885Sdumbbell if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK)) 738254885Sdumbbell RETURN_ERROR(MAJOR, err, NO_MSG); 739254885Sdumbbell else 740254885Sdumbbell { 741254885Sdumbbell // from QMIInit 742254885Sdumbbell if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 743254885Sdumbbell && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 744254885Sdumbbell { 745254885Sdumbbell if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH) 746254885Sdumbbell FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, 747254885Sdumbbell FALSE); 748254885Sdumbbell else 749254885Sdumbbell FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, 750254885Sdumbbell TRUE); 751254885Sdumbbell } 752254885Sdumbbell } 753254885Sdumbbell /* The code bellow is a trick so the FM will not release the buffer 754254885Sdumbbell to BM nor will try to enqueue the frame to QM */ 755254885Sdumbbell if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 756254885Sdumbbell || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn)) 757254885Sdumbbell { 758254885Sdumbbell if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf) 759254885Sdumbbell { 760254885Sdumbbell /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to 761254885Sdumbbell * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release 762254885Sdumbbell * buffers to BM regardless of fmbm_tfene 763254885Sdumbbell */ 764254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF); 765254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene, 766254885Sdumbbell NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); 767254885Sdumbbell } 768254885Sdumbbell } 769254885Sdumbbell 770254885Sdumbbell return E_OK; 771254885Sdumbbell} 772254885Sdumbbell 773254885Sdumbbellstatic bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) 774254885Sdumbbell{ 775254885Sdumbbell UNUSED(p_FmPort); 776254885Sdumbbell 777254885Sdumbbell switch (counter) 778254885Sdumbbell { 779254885Sdumbbell case (e_FM_PORT_COUNTERS_CYCLE): 780254885Sdumbbell case (e_FM_PORT_COUNTERS_TASK_UTIL): 781254885Sdumbbell case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 782254885Sdumbbell case (e_FM_PORT_COUNTERS_DMA_UTIL): 783254885Sdumbbell case (e_FM_PORT_COUNTERS_FIFO_UTIL): 784254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 785254885Sdumbbell case (e_FM_PORT_COUNTERS_FRAME): 786254885Sdumbbell case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 787254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): 788254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 789254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 790254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 791254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 792254885Sdumbbell case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 793254885Sdumbbell case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER): 794254885Sdumbbell return TRUE; 795254885Sdumbbell default: 796254885Sdumbbell return FALSE; 797254885Sdumbbell } 798254885Sdumbbell} 799254885Sdumbbell 800254885Sdumbbellstatic bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) 801254885Sdumbbell{ 802254885Sdumbbell UNUSED(p_FmPort); 803254885Sdumbbell 804254885Sdumbbell switch (counter) 805254885Sdumbbell { 806254885Sdumbbell case (e_FM_PORT_COUNTERS_CYCLE): 807254885Sdumbbell case (e_FM_PORT_COUNTERS_TASK_UTIL): 808254885Sdumbbell case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 809254885Sdumbbell case (e_FM_PORT_COUNTERS_DMA_UTIL): 810254885Sdumbbell case (e_FM_PORT_COUNTERS_FIFO_UTIL): 811254885Sdumbbell case (e_FM_PORT_COUNTERS_FRAME): 812254885Sdumbbell case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 813254885Sdumbbell case (e_FM_PORT_COUNTERS_LENGTH_ERR): 814254885Sdumbbell case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 815254885Sdumbbell case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 816254885Sdumbbell return TRUE; 817254885Sdumbbell default: 818254885Sdumbbell return FALSE; 819254885Sdumbbell } 820254885Sdumbbell} 821254885Sdumbbell 822254885Sdumbbellstatic bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) 823254885Sdumbbell{ 824254885Sdumbbell switch (counter) 825254885Sdumbbell { 826254885Sdumbbell case (e_FM_PORT_COUNTERS_CYCLE): 827254885Sdumbbell case (e_FM_PORT_COUNTERS_TASK_UTIL): 828254885Sdumbbell case (e_FM_PORT_COUNTERS_DMA_UTIL): 829254885Sdumbbell case (e_FM_PORT_COUNTERS_FIFO_UTIL): 830254885Sdumbbell case (e_FM_PORT_COUNTERS_FRAME): 831254885Sdumbbell case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 832254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 833254885Sdumbbell case (e_FM_PORT_COUNTERS_WRED_DISCARD): 834254885Sdumbbell case (e_FM_PORT_COUNTERS_LENGTH_ERR): 835254885Sdumbbell case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 836254885Sdumbbell case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 837254885Sdumbbell return TRUE; 838254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 839254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 840254885Sdumbbell return FALSE; 841254885Sdumbbell else 842254885Sdumbbell return TRUE; 843254885Sdumbbell default: 844254885Sdumbbell return FALSE; 845254885Sdumbbell } 846254885Sdumbbell} 847254885Sdumbbell 848254885Sdumbbellstatic t_Error BmiPortCheckAndGetCounterType( 849254885Sdumbbell t_FmPort *p_FmPort, e_FmPortCounters counter, 850254885Sdumbbell enum fman_port_stats_counters *p_StatsType, 851254885Sdumbbell enum fman_port_perf_counters *p_PerfType, bool *p_IsStats) 852254885Sdumbbell{ 853254885Sdumbbell volatile uint32_t *p_Reg; 854254885Sdumbbell bool isValid; 855254885Sdumbbell 856254885Sdumbbell switch (p_FmPort->portType) 857254885Sdumbbell { 858254885Sdumbbell case (e_FM_PORT_TYPE_RX_10G): 859254885Sdumbbell case (e_FM_PORT_TYPE_RX): 860254885Sdumbbell p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc; 861254885Sdumbbell isValid = CheckRxBmiCounter(p_FmPort, counter); 862254885Sdumbbell break; 863254885Sdumbbell case (e_FM_PORT_TYPE_TX_10G): 864254885Sdumbbell case (e_FM_PORT_TYPE_TX): 865254885Sdumbbell p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc; 866254885Sdumbbell isValid = CheckTxBmiCounter(p_FmPort, counter); 867254885Sdumbbell break; 868254885Sdumbbell case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 869254885Sdumbbell case (e_FM_PORT_TYPE_OH_HOST_COMMAND): 870254885Sdumbbell p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc; 871254885Sdumbbell isValid = CheckOhBmiCounter(p_FmPort, counter); 872254885Sdumbbell break; 873254885Sdumbbell default: 874254885Sdumbbell RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); 875254885Sdumbbell } 876254885Sdumbbell 877254885Sdumbbell if (!isValid) 878254885Sdumbbell RETURN_ERROR(MINOR, E_INVALID_STATE, 879254885Sdumbbell ("Requested counter is not available for this port type")); 880254885Sdumbbell 881254885Sdumbbell /* check that counters are enabled */ 882254885Sdumbbell switch (counter) 883254885Sdumbbell { 884254885Sdumbbell case (e_FM_PORT_COUNTERS_CYCLE): 885254885Sdumbbell case (e_FM_PORT_COUNTERS_TASK_UTIL): 886254885Sdumbbell case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 887254885Sdumbbell case (e_FM_PORT_COUNTERS_DMA_UTIL): 888254885Sdumbbell case (e_FM_PORT_COUNTERS_FIFO_UTIL): 889254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 890254885Sdumbbell /* performance counters - may be read when disabled */ 891254885Sdumbbell *p_IsStats = FALSE; 892254885Sdumbbell break; 893254885Sdumbbell case (e_FM_PORT_COUNTERS_FRAME): 894254885Sdumbbell case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 895254885Sdumbbell case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 896254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): 897254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 898254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 899254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 900254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 901254885Sdumbbell case (e_FM_PORT_COUNTERS_LENGTH_ERR): 902254885Sdumbbell case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 903254885Sdumbbell case (e_FM_PORT_COUNTERS_WRED_DISCARD): 904254885Sdumbbell *p_IsStats = TRUE; 905254885Sdumbbell if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN)) 906254885Sdumbbell RETURN_ERROR(MINOR, E_INVALID_STATE, 907254885Sdumbbell ("Requested counter was not enabled")); 908254885Sdumbbell break; 909254885Sdumbbell default: 910254885Sdumbbell break; 911254885Sdumbbell } 912254885Sdumbbell 913254885Sdumbbell /* Set counter */ 914254885Sdumbbell switch (counter) 915254885Sdumbbell { 916254885Sdumbbell case (e_FM_PORT_COUNTERS_CYCLE): 917254885Sdumbbell *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE; 918254885Sdumbbell break; 919254885Sdumbbell case (e_FM_PORT_COUNTERS_TASK_UTIL): 920254885Sdumbbell *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL; 921254885Sdumbbell break; 922254885Sdumbbell case (e_FM_PORT_COUNTERS_QUEUE_UTIL): 923254885Sdumbbell *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL; 924254885Sdumbbell break; 925254885Sdumbbell case (e_FM_PORT_COUNTERS_DMA_UTIL): 926254885Sdumbbell *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL; 927254885Sdumbbell break; 928254885Sdumbbell case (e_FM_PORT_COUNTERS_FIFO_UTIL): 929254885Sdumbbell *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL; 930254885Sdumbbell break; 931254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 932254885Sdumbbell *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE; 933254885Sdumbbell break; 934254885Sdumbbell case (e_FM_PORT_COUNTERS_FRAME): 935254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME; 936254885Sdumbbell break; 937254885Sdumbbell case (e_FM_PORT_COUNTERS_DISCARD_FRAME): 938254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD; 939254885Sdumbbell break; 940254885Sdumbbell case (e_FM_PORT_COUNTERS_DEALLOC_BUF): 941254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF; 942254885Sdumbbell break; 943254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): 944254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME; 945254885Sdumbbell break; 946254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 947254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME; 948254885Sdumbbell break; 949254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 950254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF; 951254885Sdumbbell break; 952254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 953254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME; 954254885Sdumbbell break; 955254885Sdumbbell case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 956254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR; 957254885Sdumbbell break; 958254885Sdumbbell case (e_FM_PORT_COUNTERS_WRED_DISCARD): 959254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD; 960254885Sdumbbell break; 961254885Sdumbbell case (e_FM_PORT_COUNTERS_LENGTH_ERR): 962254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR; 963254885Sdumbbell break; 964254885Sdumbbell case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 965254885Sdumbbell *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT; 966254885Sdumbbell break; 967254885Sdumbbell default: 968254885Sdumbbell break; 969254885Sdumbbell } 970254885Sdumbbell 971254885Sdumbbell return E_OK; 972254885Sdumbbell} 973254885Sdumbbell 974254885Sdumbbellstatic t_Error AdditionalPrsParams(t_FmPort *p_FmPort, 975254885Sdumbbell t_FmPcdPrsAdditionalHdrParams *p_HdrParams, 976254885Sdumbbell uint32_t *p_SoftSeqAttachReg) 977254885Sdumbbell{ 978254885Sdumbbell uint8_t hdrNum, Ipv4HdrNum; 979254885Sdumbbell u_FmPcdHdrPrsOpts *p_prsOpts; 980254885Sdumbbell uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset; 981254885Sdumbbell 982254885Sdumbbell if (IS_PRIVATE_HEADER(p_HdrParams->hdr) 983254885Sdumbbell || IS_SPECIAL_HEADER(p_HdrParams->hdr)) 984254885Sdumbbell RETURN_ERROR( 985254885Sdumbbell MAJOR, E_NOT_SUPPORTED, 986254885Sdumbbell ("No additional parameters for private or special headers.")); 987254885Sdumbbell 988254885Sdumbbell if (p_HdrParams->errDisable) 989254885Sdumbbell tmpReg |= PRS_HDR_ERROR_DIS; 990254885Sdumbbell 991254885Sdumbbell /* Set parser options */ 992254885Sdumbbell if (p_HdrParams->usePrsOpts) 993254885Sdumbbell { 994254885Sdumbbell p_prsOpts = &p_HdrParams->prsOpts; 995254885Sdumbbell switch (p_HdrParams->hdr) 996254885Sdumbbell { 997254885Sdumbbell case (HEADER_TYPE_MPLS): 998254885Sdumbbell if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable) 999254885Sdumbbell tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN; 1000254885Sdumbbell hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse); 1001254885Sdumbbell if (hdrNum == ILLEGAL_HDR_NUM) 1002254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1003254885Sdumbbell Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1004254885Sdumbbell if (hdrNum < Ipv4HdrNum) 1005254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1006254885Sdumbbell ("Header must be equal or higher than IPv4")); 1007254885Sdumbbell tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE) 1008254885Sdumbbell << PRS_HDR_MPLS_NEXT_HDR_SHIFT; 1009254885Sdumbbell break; 1010254885Sdumbbell case (HEADER_TYPE_PPPoE): 1011254885Sdumbbell if (p_prsOpts->pppoePrsOptions.enableMTUCheck) 1012254885Sdumbbell tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN; 1013254885Sdumbbell break; 1014254885Sdumbbell case (HEADER_TYPE_IPv6): 1015254885Sdumbbell if (p_prsOpts->ipv6PrsOptions.routingHdrEnable) 1016254885Sdumbbell tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN; 1017254885Sdumbbell break; 1018254885Sdumbbell case (HEADER_TYPE_TCP): 1019254885Sdumbbell if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum) 1020254885Sdumbbell tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; 1021254885Sdumbbell else 1022254885Sdumbbell tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL; 1023254885Sdumbbell break; 1024254885Sdumbbell case (HEADER_TYPE_UDP): 1025254885Sdumbbell if (p_prsOpts->udpPrsOptions.padIgnoreChecksum) 1026254885Sdumbbell tmpReg |= PRS_HDR_UDP_PAD_REMOVAL; 1027254885Sdumbbell else 1028254885Sdumbbell tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL; 1029254885Sdumbbell break; 1030254885Sdumbbell default: 1031254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header")); 1032254885Sdumbbell } 1033254885Sdumbbell } 1034254885Sdumbbell 1035254885Sdumbbell /* set software parsing (address is divided in 2 since parser uses 2 byte access. */ 1036254885Sdumbbell if (p_HdrParams->swPrsEnable) 1037254885Sdumbbell { 1038254885Sdumbbell tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr, 1039254885Sdumbbell p_HdrParams->indexPerHdr); 1040254885Sdumbbell if (tmpPrsOffset == ILLEGAL_BASE) 1041254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1042254885Sdumbbell tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset); 1043254885Sdumbbell } 1044254885Sdumbbell *p_SoftSeqAttachReg = tmpReg; 1045254885Sdumbbell 1046254885Sdumbbell return E_OK; 1047254885Sdumbbell} 1048254885Sdumbbell 1049254885Sdumbbellstatic uint32_t GetPortSchemeBindParams( 1050254885Sdumbbell t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) 1051254885Sdumbbell{ 1052254885Sdumbbell t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1053254885Sdumbbell uint32_t walking1Mask = 0x80000000, tmp; 1054254885Sdumbbell uint8_t idx = 0; 1055254885Sdumbbell 1056254885Sdumbbell p_SchemeBind->netEnvId = p_FmPort->netEnvId; 1057254885Sdumbbell p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId; 1058254885Sdumbbell p_SchemeBind->useClsPlan = p_FmPort->useClsPlan; 1059254885Sdumbbell p_SchemeBind->numOfSchemes = 0; 1060254885Sdumbbell tmp = p_FmPort->schemesPerPortVector; 1061254885Sdumbbell if (tmp) 1062254885Sdumbbell { 1063254885Sdumbbell while (tmp) 1064254885Sdumbbell { 1065254885Sdumbbell if (tmp & walking1Mask) 1066254885Sdumbbell { 1067254885Sdumbbell p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx; 1068254885Sdumbbell p_SchemeBind->numOfSchemes++; 1069254885Sdumbbell tmp &= ~walking1Mask; 1070254885Sdumbbell } 1071254885Sdumbbell walking1Mask >>= 1; 1072254885Sdumbbell idx++; 1073254885Sdumbbell } 1074254885Sdumbbell } 1075254885Sdumbbell 1076254885Sdumbbell return tmp; 1077254885Sdumbbell} 1078254885Sdumbbell 1079254885Sdumbbellstatic void FmPortCheckNApplyMacsec(t_Handle h_FmPort) 1080254885Sdumbbell{ 1081254885Sdumbbell t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1082254885Sdumbbell volatile uint32_t *p_BmiCfgReg = NULL; 1083254885Sdumbbell uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC; 1084254885Sdumbbell uint32_t lcv, walking1Mask = 0x80000000; 1085254885Sdumbbell uint8_t cnt = 0; 1086254885Sdumbbell 1087254885Sdumbbell ASSERT_COND(p_FmPort); 1088254885Sdumbbell ASSERT_COND(p_FmPort->h_FmPcd); 1089254885Sdumbbell ASSERT_COND(!p_FmPort->p_FmPortDriverParam); 1090254885Sdumbbell 1091254885Sdumbbell if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 1092254885Sdumbbell && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 1093254885Sdumbbell return; 1094254885Sdumbbell 1095254885Sdumbbell p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg; 1096254885Sdumbbell /* get LCV for MACSEC */ 1097254885Sdumbbell if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId)) 1098254885Sdumbbell != 0) 1099254885Sdumbbell { 1100254885Sdumbbell while (!(lcv & walking1Mask)) 1101254885Sdumbbell { 1102254885Sdumbbell cnt++; 1103254885Sdumbbell walking1Mask >>= 1; 1104254885Sdumbbell } 1105254885Sdumbbell 1106254885Sdumbbell macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT; 1107254885Sdumbbell WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn); 1108254885Sdumbbell } 1109254885Sdumbbell} 1110254885Sdumbbell 1111254885Sdumbbellstatic t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams) 1112254885Sdumbbell{ 1113254885Sdumbbell t_Error err = E_OK; 1114254885Sdumbbell uint32_t tmpReg; 1115254885Sdumbbell volatile uint32_t *p_BmiNia = NULL; 1116254885Sdumbbell volatile uint32_t *p_BmiPrsNia = NULL; 1117254885Sdumbbell volatile uint32_t *p_BmiPrsStartOffset = NULL; 1118254885Sdumbbell volatile uint32_t *p_BmiInitPrsResult = NULL; 1119254885Sdumbbell volatile uint32_t *p_BmiCcBase = NULL; 1120254885Sdumbbell uint16_t hdrNum, L3HdrNum, greHdrNum; 1121254885Sdumbbell int i; 1122254885Sdumbbell bool isEmptyClsPlanGrp; 1123254885Sdumbbell uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS]; 1124254885Sdumbbell uint16_t absoluteProfileId; 1125254885Sdumbbell uint8_t physicalSchemeId; 1126254885Sdumbbell uint32_t ccTreePhysOffset; 1127254885Sdumbbell t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 1128254885Sdumbbell uint32_t initialSwPrs = 0; 1129254885Sdumbbell 1130254885Sdumbbell ASSERT_COND(p_FmPort); 1131254885Sdumbbell SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1132254885Sdumbbell 1133254885Sdumbbell if (p_FmPort->imEn) 1134254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1135254885Sdumbbell ("available for non-independant mode ports only")); 1136254885Sdumbbell 1137254885Sdumbbell if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 1138254885Sdumbbell && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 1139254885Sdumbbell && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1140254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1141254885Sdumbbell ("available for Rx and offline parsing ports only")); 1142254885Sdumbbell 1143254885Sdumbbell p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv); 1144254885Sdumbbell 1145254885Sdumbbell p_FmPort->pcdEngines = 0; 1146254885Sdumbbell 1147254885Sdumbbell /* initialize p_FmPort->pcdEngines field in port's structure */ 1148254885Sdumbbell switch (p_PcdParams->pcdSupport) 1149254885Sdumbbell { 1150254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_NONE): 1151254885Sdumbbell RETURN_ERROR( 1152254885Sdumbbell MAJOR, 1153254885Sdumbbell E_INVALID_STATE, 1154254885Sdumbbell ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected")); 1155254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): 1156254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1157254885Sdumbbell break; 1158254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY): 1159254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PLCR; 1160254885Sdumbbell break; 1161254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): 1162254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1163254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PLCR; 1164254885Sdumbbell break; 1165254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): 1166254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1167254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_KG; 1168254885Sdumbbell break; 1169254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): 1170254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1171254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_CC; 1172254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_KG; 1173254885Sdumbbell break; 1174254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): 1175254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1176254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_KG; 1177254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_CC; 1178254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PLCR; 1179254885Sdumbbell break; 1180254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): 1181254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1182254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_CC; 1183254885Sdumbbell break; 1184254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): 1185254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1186254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_CC; 1187254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PLCR; 1188254885Sdumbbell break; 1189254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): 1190254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PRS; 1191254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_KG; 1192254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PLCR; 1193254885Sdumbbell break; 1194254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_CC_ONLY): 1195254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_CC; 1196254885Sdumbbell break; 1197254885Sdumbbell#ifdef FM_CAPWAP_SUPPORT 1198254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG): 1199254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_CC; 1200254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_KG; 1201254885Sdumbbell break; 1202254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR): 1203254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_CC; 1204254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_KG; 1205254885Sdumbbell p_FmPort->pcdEngines |= FM_PCD_PLCR; 1206254885Sdumbbell break; 1207254885Sdumbbell#endif /* FM_CAPWAP_SUPPORT */ 1208254885Sdumbbell 1209254885Sdumbbell default: 1210254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport")); 1211254885Sdumbbell } 1212254885Sdumbbell 1213254885Sdumbbell if ((p_FmPort->pcdEngines & FM_PCD_PRS) 1214254885Sdumbbell && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams 1215254885Sdumbbell > FM_PCD_PRS_NUM_OF_HDRS)) 1216254885Sdumbbell RETURN_ERROR( 1217254885Sdumbbell MAJOR, 1218254885Sdumbbell E_INVALID_VALUE, 1219254885Sdumbbell ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS)); 1220254885Sdumbbell 1221254885Sdumbbell /* check that parameters exist for each and only each defined engine */ 1222254885Sdumbbell if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams) 1223254885Sdumbbell || (!!(p_FmPort->pcdEngines & FM_PCD_KG) 1224254885Sdumbbell != !!p_PcdParams->p_KgParams) 1225254885Sdumbbell || (!!(p_FmPort->pcdEngines & FM_PCD_CC) 1226254885Sdumbbell != !!p_PcdParams->p_CcParams)) 1227254885Sdumbbell RETURN_ERROR( 1228254885Sdumbbell MAJOR, 1229254885Sdumbbell E_INVALID_STATE, 1230254885Sdumbbell ("PCD initialization structure is not consistent with pcdSupport")); 1231254885Sdumbbell 1232254885Sdumbbell /* get PCD registers pointers */ 1233254885Sdumbbell switch (p_FmPort->portType) 1234254885Sdumbbell { 1235254885Sdumbbell case (e_FM_PORT_TYPE_RX_10G): 1236254885Sdumbbell case (e_FM_PORT_TYPE_RX): 1237254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1238254885Sdumbbell p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; 1239254885Sdumbbell p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; 1240254885Sdumbbell p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0]; 1241254885Sdumbbell p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb; 1242254885Sdumbbell break; 1243254885Sdumbbell case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1244254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1245254885Sdumbbell p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; 1246254885Sdumbbell p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; 1247254885Sdumbbell p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0]; 1248254885Sdumbbell p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb; 1249254885Sdumbbell break; 1250254885Sdumbbell default: 1251254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 1252254885Sdumbbell } 1253254885Sdumbbell 1254254885Sdumbbell /* set PCD port parameter */ 1255254885Sdumbbell if (p_FmPort->pcdEngines & FM_PCD_CC) 1256254885Sdumbbell { 1257254885Sdumbbell err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams, 1258254885Sdumbbell p_PcdParams->p_CcParams->h_CcTree, 1259254885Sdumbbell &ccTreePhysOffset, p_FmPort); 1260254885Sdumbbell if (err) 1261254885Sdumbbell RETURN_ERROR(MAJOR, err, NO_MSG); 1262254885Sdumbbell 1263254885Sdumbbell WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); 1264254885Sdumbbell p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree; 1265254885Sdumbbell } 1266254885Sdumbbell 1267254885Sdumbbell if (p_FmPort->pcdEngines & FM_PCD_KG) 1268254885Sdumbbell { 1269254885Sdumbbell if (p_PcdParams->p_KgParams->numOfSchemes == 0) 1270254885Sdumbbell RETURN_ERROR( 1271254885Sdumbbell MAJOR, 1272254885Sdumbbell E_INVALID_VALUE, 1273254885Sdumbbell ("For ports using Keygen, at least one scheme must be bound. ")); 1274254885Sdumbbell 1275254885Sdumbbell err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd, 1276254885Sdumbbell p_FmPort->hardwarePortId, 1277254885Sdumbbell p_FmPort->netEnvId, 1278254885Sdumbbell p_FmPort->optArray, 1279254885Sdumbbell &p_FmPort->clsPlanGrpId, 1280254885Sdumbbell &isEmptyClsPlanGrp); 1281254885Sdumbbell if (err) 1282254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1283254885Sdumbbell ("FmPcdKgSetOrBindToClsPlanGrp failed. ")); 1284254885Sdumbbell 1285254885Sdumbbell p_FmPort->useClsPlan = !isEmptyClsPlanGrp; 1286254885Sdumbbell 1287254885Sdumbbell schemeBind.netEnvId = p_FmPort->netEnvId; 1288254885Sdumbbell schemeBind.hardwarePortId = p_FmPort->hardwarePortId; 1289254885Sdumbbell schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes; 1290254885Sdumbbell schemeBind.useClsPlan = p_FmPort->useClsPlan; 1291254885Sdumbbell 1292254885Sdumbbell /* for each scheme */ 1293254885Sdumbbell for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) 1294254885Sdumbbell { 1295254885Sdumbbell ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]); 1296254885Sdumbbell physicalSchemeId = FmPcdKgGetSchemeId( 1297254885Sdumbbell p_PcdParams->p_KgParams->h_Schemes[i]); 1298254885Sdumbbell schemeBind.schemesIds[i] = physicalSchemeId; 1299254885Sdumbbell /* build vector */ 1300254885Sdumbbell p_FmPort->schemesPerPortVector |= 1 1301254885Sdumbbell << (31 - (uint32_t)physicalSchemeId); 1302254885Sdumbbell#if (DPAA_VERSION >= 11) 1303254885Sdumbbell /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement 1304254885Sdumbbell if !VSPE - in port, for relevant scheme VSPE can not be set*/ 1305254885Sdumbbell if (!p_FmPort->vspe 1306254885Sdumbbell && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i]))) 1307254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, 1308254885Sdumbbell ("VSPE is not at port level")); 1309254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */ 1310254885Sdumbbell } 1311254885Sdumbbell 1312254885Sdumbbell err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 1313254885Sdumbbell if (err) 1314254885Sdumbbell RETURN_ERROR(MAJOR, err, NO_MSG); 1315254885Sdumbbell } 1316254885Sdumbbell 1317254885Sdumbbell /***************************/ 1318254885Sdumbbell /* configure NIA after BMI */ 1319254885Sdumbbell /***************************/ 1320254885Sdumbbell /* rfne may contain FDCS bits, so first we read them. */ 1321254885Sdumbbell p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; 1322254885Sdumbbell 1323254885Sdumbbell /* If policer is used directly after BMI or PRS */ 1324254885Sdumbbell if ((p_FmPort->pcdEngines & FM_PCD_PLCR) 1325254885Sdumbbell && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY) 1326254885Sdumbbell || (p_PcdParams->pcdSupport 1327254885Sdumbbell == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR))) 1328254885Sdumbbell { 1329254885Sdumbbell if (!p_PcdParams->p_PlcrParams->h_Profile) 1330254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, 1331254885Sdumbbell ("Profile should be initialized")); 1332254885Sdumbbell 1333254885Sdumbbell absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId( 1334254885Sdumbbell p_PcdParams->p_PlcrParams->h_Profile); 1335254885Sdumbbell 1336254885Sdumbbell if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) 1337254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, 1338254885Sdumbbell ("Private port profile not valid.")); 1339254885Sdumbbell 1340254885Sdumbbell tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE); 1341254885Sdumbbell 1342254885Sdumbbell if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ 1343254885Sdumbbell /* update BMI HPNIA */ 1344254885Sdumbbell WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg)); 1345254885Sdumbbell else 1346254885Sdumbbell /* e_FM_PCD_SUPPORT_PLCR_ONLY */ 1347254885Sdumbbell /* update BMI NIA */ 1348254885Sdumbbell p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR); 1349254885Sdumbbell } 1350254885Sdumbbell 1351254885Sdumbbell /* if CC is used directly after BMI */ 1352254885Sdumbbell if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) 1353254885Sdumbbell#ifdef FM_CAPWAP_SUPPORT 1354254885Sdumbbell || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) 1355254885Sdumbbell || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR) 1356254885Sdumbbell#endif /* FM_CAPWAP_SUPPORT */ 1357254885Sdumbbell ) 1358254885Sdumbbell { 1359254885Sdumbbell if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1360254885Sdumbbell RETURN_ERROR( 1361254885Sdumbbell MAJOR, 1362254885Sdumbbell E_INVALID_OPERATION, 1363254885Sdumbbell ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only")); 1364254885Sdumbbell p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); 1365254885Sdumbbell /* check that prs start offset == RIM[FOF] */ 1366254885Sdumbbell } 1367254885Sdumbbell 1368254885Sdumbbell if (p_FmPort->pcdEngines & FM_PCD_PRS) 1369254885Sdumbbell { 1370254885Sdumbbell ASSERT_COND(p_PcdParams->p_PrsParams); 1371254885Sdumbbell#if (DPAA_VERSION >= 11) 1372254885Sdumbbell if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP) 1373254885Sdumbbell hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL; 1374254885Sdumbbell else 1375254885Sdumbbell { 1376254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */ 1377254885Sdumbbell /* if PRS is used it is always first */ 1378254885Sdumbbell hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr); 1379254885Sdumbbell if (hdrNum == ILLEGAL_HDR_NUM) 1380254885Sdumbbell RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); 1381254885Sdumbbell#if (DPAA_VERSION >= 11) 1382254885Sdumbbell } 1383254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */ 1384254885Sdumbbell p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum)); 1385254885Sdumbbell /* set after parser NIA */ 1386254885Sdumbbell tmpReg = 0; 1387254885Sdumbbell switch (p_PcdParams->pcdSupport) 1388254885Sdumbbell { 1389254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): 1390254885Sdumbbell WRITE_UINT32(*p_BmiPrsNia, 1391254885Sdumbbell GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd)); 1392254885Sdumbbell break; 1393254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): 1394254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): 1395254885Sdumbbell tmpReg = NIA_KG_CC_EN; 1396254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): 1397254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): 1398254885Sdumbbell if (p_PcdParams->p_KgParams->directScheme) 1399254885Sdumbbell { 1400254885Sdumbbell physicalSchemeId = FmPcdKgGetSchemeId( 1401254885Sdumbbell p_PcdParams->p_KgParams->h_DirectScheme); 1402254885Sdumbbell /* check that this scheme was bound to this port */ 1403254885Sdumbbell for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) 1404254885Sdumbbell if (p_PcdParams->p_KgParams->h_DirectScheme 1405254885Sdumbbell == p_PcdParams->p_KgParams->h_Schemes[i]) 1406254885Sdumbbell break; 1407254885Sdumbbell if (i == p_PcdParams->p_KgParams->numOfSchemes) 1408254885Sdumbbell RETURN_ERROR( 1409254885Sdumbbell MAJOR, 1410254885Sdumbbell E_INVALID_VALUE, 1411254885Sdumbbell ("Direct scheme is not one of the port selected schemes.")); 1412254885Sdumbbell tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId); 1413254885Sdumbbell } 1414254885Sdumbbell WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg); 1415254885Sdumbbell break; 1416254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): 1417254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): 1418254885Sdumbbell WRITE_UINT32(*p_BmiPrsNia, 1419254885Sdumbbell (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); 1420254885Sdumbbell break; 1421254885Sdumbbell case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): 1422254885Sdumbbell break; 1423254885Sdumbbell default: 1424254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support")); 1425254885Sdumbbell } 1426254885Sdumbbell 1427254885Sdumbbell /* set start parsing offset */ 1428254885Sdumbbell WRITE_UINT32(*p_BmiPrsStartOffset, 1429254885Sdumbbell p_PcdParams->p_PrsParams->parsingOffset); 1430254885Sdumbbell 1431254885Sdumbbell /************************************/ 1432254885Sdumbbell /* Parser port parameters */ 1433254885Sdumbbell /************************************/ 1434254885Sdumbbell /* stop before configuring */ 1435254885Sdumbbell WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); 1436254885Sdumbbell /* wait for parser to be in idle state */ 1437254885Sdumbbell while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) 1438254885Sdumbbell ; 1439254885Sdumbbell 1440254885Sdumbbell /* set soft seq attachment register */ 1441254885Sdumbbell memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t)); 1442254885Sdumbbell 1443254885Sdumbbell /* set protocol options */ 1444254885Sdumbbell for (i = 0; p_FmPort->optArray[i]; i++) 1445254885Sdumbbell switch (p_FmPort->optArray[i]) 1446254885Sdumbbell { 1447254885Sdumbbell case (ETH_BROADCAST): 1448254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); 1449254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT; 1450254885Sdumbbell break; 1451254885Sdumbbell case (ETH_MULTICAST): 1452254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); 1453254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT; 1454254885Sdumbbell break; 1455254885Sdumbbell case (VLAN_STACKED): 1456254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN); 1457254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT; 1458254885Sdumbbell break; 1459254885Sdumbbell case (MPLS_STACKED): 1460254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); 1461254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT; 1462254885Sdumbbell break; 1463254885Sdumbbell case (IPV4_BROADCAST_1): 1464254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1465254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT; 1466254885Sdumbbell break; 1467254885Sdumbbell case (IPV4_MULTICAST_1): 1468254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1469254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT; 1470254885Sdumbbell break; 1471254885Sdumbbell case (IPV4_UNICAST_2): 1472254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1473254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT; 1474254885Sdumbbell break; 1475254885Sdumbbell case (IPV4_MULTICAST_BROADCAST_2): 1476254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1477254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT; 1478254885Sdumbbell break; 1479254885Sdumbbell case (IPV6_MULTICAST_1): 1480254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1481254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT; 1482254885Sdumbbell break; 1483254885Sdumbbell case (IPV6_UNICAST_2): 1484254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1485254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT; 1486254885Sdumbbell break; 1487254885Sdumbbell case (IPV6_MULTICAST_2): 1488254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1489254885Sdumbbell tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT; 1490254885Sdumbbell break; 1491254885Sdumbbell } 1492254885Sdumbbell 1493254885Sdumbbell if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, 1494254885Sdumbbell HEADER_TYPE_UDP_ENCAP_ESP)) 1495254885Sdumbbell { 1496254885Sdumbbell if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS) 1497254885Sdumbbell RETURN_ERROR( 1498254885Sdumbbell MINOR, E_INVALID_VALUE, 1499254885Sdumbbell ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1")); 1500254885Sdumbbell 1501254885Sdumbbell p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr = 1502254885Sdumbbell HEADER_TYPE_UDP; 1503254885Sdumbbell p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable = 1504254885Sdumbbell TRUE; 1505254885Sdumbbell p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++; 1506254885Sdumbbell } 1507254885Sdumbbell 1508254885Sdumbbell /* set MPLS default next header - HW reset workaround */ 1509254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); 1510254885Sdumbbell tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN; 1511254885Sdumbbell L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3); 1512254885Sdumbbell tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT; 1513254885Sdumbbell 1514254885Sdumbbell /* for GRE, disable errors */ 1515254885Sdumbbell greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE); 1516254885Sdumbbell tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS; 1517254885Sdumbbell 1518254885Sdumbbell /* For UDP remove PAD from L4 checksum calculation */ 1519254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP); 1520254885Sdumbbell tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL; 1521254885Sdumbbell /* For TCP remove PAD from L4 checksum calculation */ 1522254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP); 1523254885Sdumbbell tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL; 1524254885Sdumbbell 1525254885Sdumbbell /* config additional params for specific headers */ 1526254885Sdumbbell for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams; 1527254885Sdumbbell i++) 1528254885Sdumbbell { 1529254885Sdumbbell /* case for using sw parser as the initial NIA address, before 1530254885Sdumbbell * HW parsing 1531254885Sdumbbell */ 1532254885Sdumbbell if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) && 1533254885Sdumbbell p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable) 1534254885Sdumbbell { 1535254885Sdumbbell initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE, 1536254885Sdumbbell p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr); 1537254885Sdumbbell if (initialSwPrs == ILLEGAL_BASE) 1538254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1539254885Sdumbbell 1540254885Sdumbbell /* clear parser first HXS */ 1541254885Sdumbbell p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */ 1542254885Sdumbbell /* rewrite with soft parser start */ 1543254885Sdumbbell p_FmPort->savedBmiNia |= initialSwPrs; 1544254885Sdumbbell continue; 1545254885Sdumbbell } 1546254885Sdumbbell 1547254885Sdumbbell hdrNum = 1548254885Sdumbbell GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr); 1549254885Sdumbbell if (hdrNum == ILLEGAL_HDR_NUM) 1550254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1551254885Sdumbbell if (hdrNum == NO_HDR_NUM) 1552254885Sdumbbell RETURN_ERROR( 1553254885Sdumbbell MAJOR, E_INVALID_VALUE, 1554254885Sdumbbell ("Private headers may not use additional parameters")); 1555254885Sdumbbell 1556254885Sdumbbell err = AdditionalPrsParams( 1557254885Sdumbbell p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i], 1558254885Sdumbbell &tmpHxs[hdrNum]); 1559254885Sdumbbell if (err) 1560254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1561254885Sdumbbell } 1562254885Sdumbbell 1563254885Sdumbbell /* Check if ip-reassembly port - need to link sw-parser code */ 1564254885Sdumbbell if (p_FmPort->h_IpReassemblyManip) 1565254885Sdumbbell { 1566254885Sdumbbell /* link to sw parser code for IP Frag - only if no other code is applied. */ 1567254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); 1568254885Sdumbbell if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1569254885Sdumbbell tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL); 1570254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1571254885Sdumbbell if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1572254885Sdumbbell tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL); 1573254885Sdumbbell } else { 1574254885Sdumbbell if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE)) 1575254885Sdumbbell { 1576254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1577254885Sdumbbell if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1578254885Sdumbbell tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); 1579254885Sdumbbell } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) 1580254885Sdumbbell && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))) 1581254885Sdumbbell { 1582254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1583254885Sdumbbell if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1584254885Sdumbbell tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); 1585254885Sdumbbell } 1586254885Sdumbbell } 1587254885Sdumbbell 1588254885Sdumbbell#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) 1589254885Sdumbbell if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, 1590254885Sdumbbell HEADER_TYPE_UDP_LITE)) 1591254885Sdumbbell { 1592254885Sdumbbell /* link to sw parser code for udp lite - only if no other code is applied. */ 1593254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1594254885Sdumbbell if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1595254885Sdumbbell tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL); 1596254885Sdumbbell } 1597254885Sdumbbell#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ 1598254885Sdumbbell for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++) 1599254885Sdumbbell { 1600254885Sdumbbell /* For all header set LCV as taken from netEnv*/ 1601254885Sdumbbell WRITE_UINT32( 1602254885Sdumbbell p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv, 1603254885Sdumbbell FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i)); 1604254885Sdumbbell /* set HXS register according to default+Additional params+protocol options */ 1605254885Sdumbbell WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach, 1606254885Sdumbbell tmpHxs[i]); 1607254885Sdumbbell } 1608254885Sdumbbell 1609254885Sdumbbell /* set tpid. */ 1610254885Sdumbbell tmpReg = PRS_TPID_DFLT; 1611254885Sdumbbell if (p_PcdParams->p_PrsParams->setVlanTpid1) 1612254885Sdumbbell { 1613254885Sdumbbell tmpReg &= PRS_TPID2_MASK; 1614254885Sdumbbell tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1 1615254885Sdumbbell << PRS_PCTPID_SHIFT; 1616254885Sdumbbell } 1617254885Sdumbbell if (p_PcdParams->p_PrsParams->setVlanTpid2) 1618254885Sdumbbell { 1619254885Sdumbbell tmpReg &= PRS_TPID1_MASK; 1620254885Sdumbbell tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2; 1621254885Sdumbbell }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg); 1622254885Sdumbbell 1623254885Sdumbbell /* enable parser */ 1624254885Sdumbbell WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0); 1625254885Sdumbbell 1626254885Sdumbbell if (p_PcdParams->p_PrsParams->prsResultPrivateInfo) 1627254885Sdumbbell p_FmPort->privateInfo = 1628254885Sdumbbell p_PcdParams->p_PrsParams->prsResultPrivateInfo; 1629254885Sdumbbell 1630254885Sdumbbell } /* end parser */ 1631254885Sdumbbell else { 1632254885Sdumbbell if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) 1633254885Sdumbbell && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1634254885Sdumbbell { 1635254885Sdumbbell hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); 1636254885Sdumbbell WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach, 1637254885Sdumbbell (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL)); 1638254885Sdumbbell } 1639254885Sdumbbell 1640254885Sdumbbell WRITE_UINT32(*p_BmiPrsStartOffset, 0); 1641254885Sdumbbell 1642254885Sdumbbell p_FmPort->privateInfo = 0; 1643254885Sdumbbell } 1644254885Sdumbbell 1645254885Sdumbbell FmPortCheckNApplyMacsec(p_FmPort); 1646254885Sdumbbell 1647254885Sdumbbell WRITE_UINT32( 1648254885Sdumbbell *p_BmiPrsStartOffset, 1649254885Sdumbbell GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset); 1650254885Sdumbbell 1651254885Sdumbbell /* set initial parser result - used for all engines */ 1652254885Sdumbbell for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++) 1653254885Sdumbbell { 1654254885Sdumbbell if (!i) 1655254885Sdumbbell WRITE_UINT32( 1656254885Sdumbbell *(p_BmiInitPrsResult), 1657254885Sdumbbell (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH)); 1658254885Sdumbbell else 1659254885Sdumbbell { 1660254885Sdumbbell if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2) 1661254885Sdumbbell WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH); 1662254885Sdumbbell else 1663254885Sdumbbell WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW); 1664254885Sdumbbell } 1665254885Sdumbbell } 1666254885Sdumbbell 1667254885Sdumbbell return E_OK; 1668254885Sdumbbell} 1669254885Sdumbbell 1670254885Sdumbbellstatic t_Error DeletePcd(t_FmPort *p_FmPort) 1671254885Sdumbbell{ 1672254885Sdumbbell t_Error err = E_OK; 1673254885Sdumbbell volatile uint32_t *p_BmiNia = NULL; 1674254885Sdumbbell volatile uint32_t *p_BmiPrsStartOffset = NULL; 1675254885Sdumbbell 1676254885Sdumbbell ASSERT_COND(p_FmPort); 1677254885Sdumbbell SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1678254885Sdumbbell 1679254885Sdumbbell if (p_FmPort->imEn) 1680254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1681254885Sdumbbell ("available for non-independant mode ports only")); 1682254885Sdumbbell 1683254885Sdumbbell if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) 1684254885Sdumbbell && (p_FmPort->portType != e_FM_PORT_TYPE_RX) 1685254885Sdumbbell && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1686254885Sdumbbell RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 1687254885Sdumbbell ("available for Rx and offline parsing ports only")); 1688254885Sdumbbell 1689254885Sdumbbell if (!p_FmPort->pcdEngines) 1690254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port")); 1691254885Sdumbbell 1692254885Sdumbbell /* get PCD registers pointers */ 1693254885Sdumbbell switch (p_FmPort->portType) 1694254885Sdumbbell { 1695254885Sdumbbell case (e_FM_PORT_TYPE_RX_10G): 1696254885Sdumbbell case (e_FM_PORT_TYPE_RX): 1697254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1698254885Sdumbbell p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; 1699254885Sdumbbell break; 1700254885Sdumbbell case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1701254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1702254885Sdumbbell p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; 1703254885Sdumbbell break; 1704254885Sdumbbell default: 1705254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 1706254885Sdumbbell } 1707254885Sdumbbell 1708254885Sdumbbell if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) 1709254885Sdumbbell != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) 1710254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_OPERATION, 1711254885Sdumbbell ("port has to be detached previousely")); 1712254885Sdumbbell 1713254885Sdumbbell WRITE_UINT32(*p_BmiPrsStartOffset, 0); 1714254885Sdumbbell 1715254885Sdumbbell /* "cut" PCD out of the port's flow - go to BMI */ 1716254885Sdumbbell /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */ 1717254885Sdumbbell 1718254885Sdumbbell if (p_FmPort->pcdEngines & FM_PCD_PRS) 1719254885Sdumbbell { 1720254885Sdumbbell /* stop parser */ 1721254885Sdumbbell WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); 1722254885Sdumbbell /* wait for parser to be in idle state */ 1723254885Sdumbbell while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) 1724254885Sdumbbell ; 1725254885Sdumbbell } 1726254885Sdumbbell 1727254885Sdumbbell if (p_FmPort->pcdEngines & FM_PCD_KG) 1728254885Sdumbbell { 1729254885Sdumbbell t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 1730254885Sdumbbell 1731254885Sdumbbell /* unbind all schemes */ 1732254885Sdumbbell p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort, 1733254885Sdumbbell &schemeBind); 1734254885Sdumbbell 1735254885Sdumbbell err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 1736254885Sdumbbell if (err) 1737254885Sdumbbell RETURN_ERROR(MAJOR, err, NO_MSG); 1738254885Sdumbbell 1739254885Sdumbbell err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, 1740254885Sdumbbell p_FmPort->hardwarePortId, 1741254885Sdumbbell p_FmPort->clsPlanGrpId); 1742254885Sdumbbell if (err) 1743254885Sdumbbell RETURN_ERROR(MAJOR, err, NO_MSG); 1744254885Sdumbbell p_FmPort->useClsPlan = FALSE; 1745254885Sdumbbell } 1746254885Sdumbbell 1747254885Sdumbbell if (p_FmPort->pcdEngines & FM_PCD_CC) 1748254885Sdumbbell { 1749254885Sdumbbell /* unbind - we need to get the treeId too */ 1750254885Sdumbbell err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId); 1751254885Sdumbbell if (err) 1752254885Sdumbbell RETURN_ERROR(MAJOR, err, NO_MSG); 1753254885Sdumbbell } 1754254885Sdumbbell 1755254885Sdumbbell p_FmPort->pcdEngines = 0; 1756254885Sdumbbell 1757254885Sdumbbell return E_OK; 1758254885Sdumbbell} 1759254885Sdumbbell 1760254885Sdumbbellstatic t_Error AttachPCD(t_FmPort *p_FmPort) 1761254885Sdumbbell{ 1762254885Sdumbbell volatile uint32_t *p_BmiNia = NULL; 1763254885Sdumbbell 1764254885Sdumbbell ASSERT_COND(p_FmPort); 1765254885Sdumbbell 1766254885Sdumbbell /* get PCD registers pointers */ 1767254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1768254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1769254885Sdumbbell else 1770254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1771254885Sdumbbell 1772254885Sdumbbell /* check that current NIA is BMI to BMI */ 1773254885Sdumbbell if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) 1774254885Sdumbbell != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) 1775254885Sdumbbell RETURN_ERROR( MAJOR, E_INVALID_OPERATION, 1776254885Sdumbbell ("may be called only for ports in BMI-to-BMI state.")); 1777254885Sdumbbell 1778254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) 1779254885Sdumbbell if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1, 1780254885Sdumbbell p_FmPort->orFmanCtrl) != E_OK) 1781254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 1782254885Sdumbbell 1783254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_CMNE) 1784254885Sdumbbell { 1785254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1786254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne, 1787254885Sdumbbell p_FmPort->savedBmiCmne); 1788254885Sdumbbell else 1789254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne, 1790254885Sdumbbell p_FmPort->savedBmiCmne); 1791254885Sdumbbell } 1792254885Sdumbbell 1793254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) 1794254885Sdumbbell WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, 1795254885Sdumbbell p_FmPort->savedQmiPnen); 1796254885Sdumbbell 1797254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_FENE) 1798254885Sdumbbell { 1799254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1800254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, 1801254885Sdumbbell p_FmPort->savedBmiFene); 1802254885Sdumbbell else 1803254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, 1804254885Sdumbbell p_FmPort->savedBmiFene); 1805254885Sdumbbell } 1806254885Sdumbbell 1807254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_FPNE) 1808254885Sdumbbell { 1809254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1810254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne, 1811254885Sdumbbell p_FmPort->savedBmiFpne); 1812254885Sdumbbell else 1813254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne, 1814254885Sdumbbell p_FmPort->savedBmiFpne); 1815254885Sdumbbell } 1816254885Sdumbbell 1817254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_OFP_DPTE) 1818254885Sdumbbell { 1819254885Sdumbbell ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING); 1820254885Sdumbbell 1821254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp, 1822254885Sdumbbell p_FmPort->savedBmiOfp); 1823254885Sdumbbell } 1824254885Sdumbbell 1825254885Sdumbbell WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia); 1826254885Sdumbbell 1827254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) 1828254885Sdumbbell { 1829254885Sdumbbell p_FmPort->origNonRxQmiRegsPndn = 1830254885Sdumbbell GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn); 1831254885Sdumbbell WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, 1832254885Sdumbbell p_FmPort->savedNonRxQmiRegsPndn); 1833254885Sdumbbell } 1834254885Sdumbbell 1835254885Sdumbbell return E_OK; 1836254885Sdumbbell} 1837254885Sdumbbell 1838254885Sdumbbellstatic t_Error DetachPCD(t_FmPort *p_FmPort) 1839254885Sdumbbell{ 1840254885Sdumbbell volatile uint32_t *p_BmiNia = NULL; 1841254885Sdumbbell 1842254885Sdumbbell ASSERT_COND(p_FmPort); 1843254885Sdumbbell 1844254885Sdumbbell /* get PCD registers pointers */ 1845254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) 1846254885Sdumbbell WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, 1847254885Sdumbbell p_FmPort->origNonRxQmiRegsPndn); 1848254885Sdumbbell 1849254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1850254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; 1851254885Sdumbbell else 1852254885Sdumbbell p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; 1853254885Sdumbbell 1854254885Sdumbbell WRITE_UINT32( 1855254885Sdumbbell *p_BmiNia, 1856254885Sdumbbell (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()); 1857254885Sdumbbell 1858254885Sdumbbell if (FmPcdGetHcHandle(p_FmPort->h_FmPcd)) 1859254885Sdumbbell FmPcdHcSync(p_FmPort->h_FmPcd); 1860254885Sdumbbell 1861254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_FENE) 1862254885Sdumbbell { 1863254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1864254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, 1865254885Sdumbbell NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); 1866254885Sdumbbell else 1867254885Sdumbbell WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, 1868254885Sdumbbell NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); 1869254885Sdumbbell } 1870254885Sdumbbell 1871254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) 1872254885Sdumbbell WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen, 1873254885Sdumbbell NIA_ENG_BMI | NIA_BMI_AC_RELEASE); 1874254885Sdumbbell 1875254885Sdumbbell if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) 1876254885Sdumbbell if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2, 1877254885Sdumbbell p_FmPort->orFmanCtrl) != E_OK) 1878254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 1879254885Sdumbbell 1880254885Sdumbbell p_FmPort->requiredAction = 0; 1881254885Sdumbbell 1882254885Sdumbbell return E_OK; 1883254885Sdumbbell} 1884254885Sdumbbell 1885254885Sdumbbell/*****************************************************************************/ 1886254885Sdumbbell/* Inter-module API routines */ 1887254885Sdumbbell/*****************************************************************************/ 1888254885Sdumbbellvoid FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci) 1889254885Sdumbbell{ 1890254885Sdumbbell t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1891254885Sdumbbell volatile uint32_t *p_BmiCfgReg = NULL; 1892254885Sdumbbell uint32_t tmpReg; 1893254885Sdumbbell 1894254885Sdumbbell SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); 1895254885Sdumbbell SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1896254885Sdumbbell 1897254885Sdumbbell if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) 1898254885Sdumbbell && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 1899254885Sdumbbell { 1900254885Sdumbbell REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only")); 1901254885Sdumbbell return; 1902254885Sdumbbell } 1903254885Sdumbbell 1904254885Sdumbbell p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca; 1905254885Sdumbbell tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK; 1906254885Sdumbbell tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED; 1907254885Sdumbbell tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT) 1908254885Sdumbbell & BMI_CMD_ATTR_MACCMD_SC_MASK); 1909254885Sdumbbell 1910254885Sdumbbell WRITE_UINT32(*p_BmiCfgReg, tmpReg); 1911254885Sdumbbell} 1912254885Sdumbbell 1913254885Sdumbbelluint8_t FmPortGetNetEnvId(t_Handle h_FmPort) 1914254885Sdumbbell{ 1915254885Sdumbbell return ((t_FmPort*)h_FmPort)->netEnvId; 1916254885Sdumbbell} 1917254885Sdumbbell 1918254885Sdumbbelluint8_t FmPortGetHardwarePortId(t_Handle h_FmPort) 1919254885Sdumbbell{ 1920254885Sdumbbell return ((t_FmPort*)h_FmPort)->hardwarePortId; 1921254885Sdumbbell} 1922254885Sdumbbell 1923254885Sdumbbelluint32_t FmPortGetPcdEngines(t_Handle h_FmPort) 1924254885Sdumbbell{ 1925254885Sdumbbell return ((t_FmPort*)h_FmPort)->pcdEngines; 1926254885Sdumbbell} 1927254885Sdumbbell 1928254885Sdumbbell#if (DPAA_VERSION >= 11) 1929254885Sdumbbellt_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, 1930254885Sdumbbell void **p_Value) 1931254885Sdumbbell{ 1932254885Sdumbbell t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1933254885Sdumbbell uint32_t muramPageOffset; 1934254885Sdumbbell 1935254885Sdumbbell ASSERT_COND(p_FmPort); 1936254885Sdumbbell ASSERT_COND(p_Value); 1937254885Sdumbbell 1938254885Sdumbbell if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY) 1939254885Sdumbbell { 1940254885Sdumbbell if (p_FmPort->gprFunc != gprFunc) 1941254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, 1942254885Sdumbbell ("gpr was assigned with different func")); 1943254885Sdumbbell } 1944254885Sdumbbell else 1945254885Sdumbbell { 1946254885Sdumbbell switch (gprFunc) 1947254885Sdumbbell { 1948254885Sdumbbell case (e_FM_PORT_GPR_MURAM_PAGE): 1949254885Sdumbbell p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, 1950254885Sdumbbell 256, 8); 1951254885Sdumbbell if (!p_FmPort->p_ParamsPage) 1952254885Sdumbbell RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page")); 1953254885Sdumbbell 1954254885Sdumbbell IOMemSet32(p_FmPort->p_ParamsPage, 0, 256); 1955254885Sdumbbell muramPageOffset = 1956254885Sdumbbell (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage) 1957254885Sdumbbell - p_FmPort->fmMuramPhysBaseAddr); 1958254885Sdumbbell switch (p_FmPort->portType) 1959254885Sdumbbell { 1960254885Sdumbbell case (e_FM_PORT_TYPE_RX_10G): 1961254885Sdumbbell case (e_FM_PORT_TYPE_RX): 1962254885Sdumbbell WRITE_UINT32( 1963254885Sdumbbell p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr, 1964254885Sdumbbell muramPageOffset); 1965254885Sdumbbell break; 1966254885Sdumbbell case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1967254885Sdumbbell WRITE_UINT32( 1968254885Sdumbbell p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr, 1969254885Sdumbbell muramPageOffset); 1970254885Sdumbbell break; 1971254885Sdumbbell default: 1972254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_STATE, 1973254885Sdumbbell ("Invalid port type")); 1974254885Sdumbbell } 1975254885Sdumbbell break; 1976254885Sdumbbell default: 1977254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1978254885Sdumbbell } 1979254885Sdumbbell p_FmPort->gprFunc = gprFunc; 1980254885Sdumbbell } 1981254885Sdumbbell 1982254885Sdumbbell switch (p_FmPort->gprFunc) 1983254885Sdumbbell { 1984254885Sdumbbell case (e_FM_PORT_GPR_MURAM_PAGE): 1985254885Sdumbbell *p_Value = p_FmPort->p_ParamsPage; 1986254885Sdumbbell break; 1987254885Sdumbbell default: 1988254885Sdumbbell RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1989254885Sdumbbell } 1990254885Sdumbbell 1991254885Sdumbbell return E_OK; 1992254885Sdumbbell} 1993254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */ 1994254885Sdumbbell 1995254885Sdumbbellt_Error FmPortGetSetCcParams(t_Handle h_FmPort, 1996254885Sdumbbell t_FmPortGetSetCcParams *p_CcParams) 1997254885Sdumbbell{ 1998254885Sdumbbell t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1999254885Sdumbbell uint32_t tmpInt; 2000254885Sdumbbell volatile uint32_t *p_BmiPrsStartOffset = NULL; 2001254885Sdumbbell 2002254885Sdumbbell /* this function called from Cc for pass and receive parameters port params between CC and PORT*/ 2003254885Sdumbbell 2004254885Sdumbbell if ((p_CcParams->getCcParams.type & OFFSET_OF_PR) 2005254885Sdumbbell && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE)) 2006254885Sdumbbell { 2007254885Sdumbbell p_CcParams->getCcParams.prOffset = 2008254885Sdumbbell (uint8_t)p_FmPort->bufferOffsets.prsResultOffset; 2009254885Sdumbbell p_CcParams->getCcParams.type &= ~OFFSET_OF_PR; 2010254885Sdumbbell } 2011254885Sdumbbell if (p_CcParams->getCcParams.type & HW_PORT_ID) 2012254885Sdumbbell { 2013254885Sdumbbell p_CcParams->getCcParams.hardwarePortId = 2014254885Sdumbbell (uint8_t)p_FmPort->hardwarePortId; 2015254885Sdumbbell p_CcParams->getCcParams.type &= ~HW_PORT_ID; 2016254885Sdumbbell } 2017254885Sdumbbell if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA) 2018254885Sdumbbell && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE)) 2019254885Sdumbbell { 2020254885Sdumbbell p_CcParams->getCcParams.dataOffset = 2021254885Sdumbbell (uint16_t)p_FmPort->bufferOffsets.dataOffset; 2022254885Sdumbbell p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA; 2023254885Sdumbbell } 2024254885Sdumbbell if (p_CcParams->getCcParams.type & NUM_OF_TASKS) 2025254885Sdumbbell { 2026254885Sdumbbell p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; 2027254885Sdumbbell p_CcParams->getCcParams.type &= ~NUM_OF_TASKS; 2028254885Sdumbbell } 2029254885Sdumbbell if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS) 2030254885Sdumbbell { 2031254885Sdumbbell p_CcParams->getCcParams.numOfExtraTasks = 2032254885Sdumbbell (uint8_t)p_FmPort->tasks.extra; 2033254885Sdumbbell p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS; 2034254885Sdumbbell } 2035254885Sdumbbell if (p_CcParams->getCcParams.type & FM_REV) 2036254885Sdumbbell { 2037254885Sdumbbell p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev; 2038254885Sdumbbell p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev; 2039254885Sdumbbell p_CcParams->getCcParams.type &= ~FM_REV; 2040254885Sdumbbell } 2041254885Sdumbbell if (p_CcParams->getCcParams.type & DISCARD_MASK) 2042254885Sdumbbell { 2043254885Sdumbbell if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2044262861Sjhb p_CcParams->getCcParams.discardMask = 2045262861Sjhb GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm); 2046262861Sjhb else 2047254885Sdumbbell p_CcParams->getCcParams.discardMask = 2048254885Sdumbbell GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm); 2049254885Sdumbbell p_CcParams->getCcParams.type &= ~DISCARD_MASK; 2050254885Sdumbbell } 2051254885Sdumbbell if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE) 2052254885Sdumbbell { 2053254885Sdumbbell 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 2211t_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 2561t_FmPort *rx_port = 0; 2562t_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 *//***************************************************************************/ 2573t_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 *//***************************************************************************/ 2763t_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 2816t_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 2829t_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 2841t_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 2854t_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 2869t_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 2886t_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 2903t_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 2925t_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 2941t_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 2959t_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 2973t_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 2990t_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 3009t_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 3032t_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 3049t_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 3065t_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 3076t_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 3093t_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 3109t_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 3127t_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 3140t_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 3154t_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 3168t_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 3182t_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) 3200t_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 3216t_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 3234t_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 3247t_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 3264t_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 3281t_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 3304t_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 3322t_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 3338t_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 3358t_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 3386t_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 3418t_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 3465uint32_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 3476uint8_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 3490t_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 3504uint64_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 3518uint8_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 3532t_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 3560t_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 3587t_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 3681t_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 3701t_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 3734t_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 3746t_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 3760t_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 3840t_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 3942t_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 3956t_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 3999t_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 4020t_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 4160uint32_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 4247t_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 4329uint32_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 4345t_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} 4361bool 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 4380t_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 4390t_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) 4422t_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 4517t_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 4546t_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 4567t_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 4644t_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 4715t_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 4809t_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 4842t_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 4880t_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 5279t_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 5349t_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 5400t_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 5439t_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 5518t_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) 5579t_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 5597t_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 5608static 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 5671t_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 5677struct 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 5690static 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 5773uint32_t* ARDesc; 5774void PrsEnable(t_Handle p_FmPcd); 5775void PrsDisable(t_Handle p_FmPcd); 5776int PrsIsEnabled(t_Handle p_FmPcd); 5777t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd); 5778 5779static 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 5940static 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 5958static 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 5969void 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 5981t_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 6293void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId); 6294t_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 6374void FM_PORT_Dsar_DumpRegs() 6375{ 6376 uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc)); 6377 DUMP_MEMORY(hh, 0x220); 6378} 6379 6380void 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 6407bool 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 6413t_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