1/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * * Neither the name of Freescale Semiconductor nor the 12 * names of its contributors may be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * 16 * ALTERNATIVELY, this software may be distributed under the terms of the 17 * GNU General Public License ("GPL") as published by the Free Software 18 * Foundation, either version 2 of that License or (at your option) any 19 * later version. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/****************************************************************************** 34 @File fm_port.c 35 36 @Description FM driver routines implementation. 37*//***************************************************************************/ 38#include "error_ext.h" 39#include "std_ext.h" 40#include "string_ext.h" 41#include "sprint_ext.h" 42#include "debug_ext.h" 43#include "fm_pcd_ext.h" 44 45#include "fm_port.h" 46 47 48/****************************************/ 49/* static functions */ 50/****************************************/ 51 52static t_Error CheckInitParameters(t_FmPort *p_FmPort) 53{ 54 t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; 55 t_Error ans = E_OK; 56 uint32_t unusedMask; 57 uint8_t i; 58 uint8_t j; 59 bool found; 60 61 if (p_FmPort->imEn) 62 { 63 if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK) 64 return ERROR_CODE(ans); 65 } 66 else 67 { 68 /****************************************/ 69 /* Rx only */ 70 /****************************************/ 71 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 72 { 73 /* external buffer pools */ 74 if(!p_Params->extBufPools.numOfPoolsUsed) 75 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined")); 76 77 if(p_Params->extBufPools.numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS) 78 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS)); 79 80 for(i=0;i<p_Params->extBufPools.numOfPoolsUsed;i++) 81 { 82 if(p_Params->extBufPools.extBufPool[i].id >= BM_MAX_NUM_OF_POOLS) 83 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS)); 84 if(!p_Params->extBufPools.extBufPool[i].size) 85 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i)); 86 } 87 88 /* backup BM pools indication is valid only for some chip deriviatives 89 (limited by the config routine) */ 90 if(p_Params->p_BackupBmPools) 91 { 92 if(p_Params->p_BackupBmPools->numOfBackupPools >= p_Params->extBufPools.numOfPoolsUsed) 93 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed")); 94 found = FALSE; 95 for(i = 0;i<p_Params->p_BackupBmPools->numOfBackupPools;i++) 96 for(j=0;j<p_Params->extBufPools.numOfPoolsUsed;j++) 97 if(p_Params->p_BackupBmPools->poolIds[i] == p_Params->extBufPools.extBufPool[j].id) 98 found = TRUE; 99 if (!found) 100 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id")); 101 } 102 103 /* up to extBufPools.numOfPoolsUsed pools may be defined */ 104 if(p_Params->bufPoolDepletion.numberOfPoolsModeEnable) 105 { 106 if((p_Params->bufPoolDepletion.numOfPools > p_Params->extBufPools.numOfPoolsUsed)) 107 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools can't be larger than %d and can't be larger than numOfPoolsUsed", FM_PORT_MAX_NUM_OF_EXT_POOLS)); 108 109 if(!p_Params->bufPoolDepletion.numOfPools) 110 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when numberOfPoolsModeEnable=TRUE")); 111 } 112 /* Check that part of IC that needs copying is small enough to enter start margin */ 113 if(p_Params->intContext.size + p_Params->intContext.extBufOffset > p_Params->bufMargins.startMargins) 114 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size is larger than start margins")); 115 116 if(p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK) 117 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); 118#ifdef FM_PARTITION_ARRAY 119 { 120 t_FmRevisionInfo revInfo; 121 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 122 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 123 { 124 if(p_Params->liodnOffset >= MAX_LIODN_OFFSET) 125 { 126 p_Params->liodnOffset = (uint16_t)(p_Params->liodnOffset & (MAX_LIODN_OFFSET-1)); 127 DBG(WARNING, ("liodnOffset number is out of rev1 range - MSB bits cleard.")); 128 } 129 } 130 } 131#endif /* FM_PARTITION_ARRAY */ 132 } 133 134 /****************************************/ 135 /* Non Rx ports */ 136 /****************************************/ 137 else 138 { 139 if(p_Params->deqSubPortal >= MAX_QMI_DEQ_SUBPORTAL) 140 RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" deqSubPortal has to be in the range of 0 - %d", MAX_QMI_DEQ_SUBPORTAL)); 141 142 /* to protect HW internal-context from overwrite */ 143 if((p_Params->intContext.size) && (p_Params->intContext.intContextOffset < MIN_TX_INT_OFFSET)) 144 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET)); 145 } 146 147 /****************************************/ 148 /* Rx Or Offline Parsing */ 149 /****************************************/ 150 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 151 { 152 153 if(!p_Params->dfltFqid) 154 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dfltFqid must be between 1 and 2^24-1")); 155#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004) 156 if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16) 157 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16")); 158#endif /* defined(FM_CAPWAP_SUPPORT) && ... */ 159 } 160 161 /****************************************/ 162 /* All ports */ 163 /****************************************/ 164 /* common BMI registers values */ 165 /* Check that Queue Id is not larger than 2^24, and is not 0 */ 166 if((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid) 167 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("errFqid must be between 1 and 2^24-1")); 168 if(p_Params->dfltFqid & ~0x00FFFFFF) 169 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dfltFqid must be between 1 and 2^24-1")); 170 } 171 172 /****************************************/ 173 /* Rx only */ 174 /****************************************/ 175 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 176 { 177 /* Check that divisible by 256 and not larger than 256 */ 178 if(p_Params->rxFifoPriElevationLevel % BMI_FIFO_UNITS) 179 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS)); 180 if(!p_Params->rxFifoPriElevationLevel || (p_Params->rxFifoPriElevationLevel > BMI_MAX_FIFO_SIZE)) 181 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); 182 if(p_Params->rxFifoThreshold % BMI_FIFO_UNITS) 183 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS)); 184 if(!p_Params->rxFifoThreshold ||(p_Params->rxFifoThreshold > BMI_MAX_FIFO_SIZE)) 185 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); 186 187 /* Check that not larger than 16 */ 188 if(p_Params->cutBytesFromEnd > FRAME_END_DATA_SIZE) 189 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); 190 191 /* Check the margin definition */ 192 if(p_Params->bufMargins.startMargins > MAX_EXT_BUFFER_OFFSET) 193 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); 194 if(p_Params->bufMargins.endMargins > MAX_EXT_BUFFER_OFFSET) 195 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); 196 197 /* extra FIFO size (allowed only to Rx ports) */ 198 if(p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS) 199 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS)); 200 201 if(p_Params->bufPoolDepletion.numberOfPoolsModeEnable && 202 !p_Params->bufPoolDepletion.numOfPools) 203 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when numberOfPoolsModeEnable=TRUE")); 204#ifdef FM_CSI_CFED_LIMIT 205 { 206 t_FmRevisionInfo revInfo; 207 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 208 209 if (revInfo.majorRev == 4) 210 { 211 /* Check that not larger than 16 */ 212 if(p_Params->cutBytesFromEnd + p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) 213 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); 214 } 215 } 216#endif /* FM_CSI_CFED_LIMIT */ 217 218 } 219 220 /****************************************/ 221 /* Non Rx ports */ 222 /****************************************/ 223 else 224 /* extra FIFO size (allowed only to Rx ports) */ 225 if(p_FmPort->fifoBufs.extra) 226 RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" No fifoBufs.extra for non Rx ports")); 227 228 /****************************************/ 229 /* Rx & Tx */ 230 /****************************************/ 231 if((p_FmPort->portType == e_FM_PORT_TYPE_TX) || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || 232 (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 233 { 234 /* Check that not larger than 16 */ 235 if(p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) 236 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE)); 237 } 238 239 /****************************************/ 240 /* Tx only */ 241 /****************************************/ 242 if((p_FmPort->portType == e_FM_PORT_TYPE_TX) || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) 243 { 244 /* Check that divisible by 256 and not larger than 256 */ 245 if(p_Params->txFifoMinFillLevel % BMI_FIFO_UNITS) 246 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS)); 247 if(p_Params->txFifoMinFillLevel > (BMI_MAX_FIFO_SIZE - 256)) 248 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be in the range of 0 - %d", BMI_MAX_FIFO_SIZE)); 249 if(p_Params->txFifoLowComfLevel % BMI_FIFO_UNITS) 250 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS)); 251 if(!p_Params->txFifoLowComfLevel || (p_Params->txFifoLowComfLevel > BMI_MAX_FIFO_SIZE)) 252 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); 253 254 /* Check that not larger than 8 */ 255 if((!p_FmPort->txFifoDeqPipelineDepth) ||( p_FmPort->txFifoDeqPipelineDepth > MAX_FIFO_PIPELINE_DEPTH)) 256 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH)); 257 if(p_FmPort->portType == e_FM_PORT_TYPE_TX) 258 if(p_FmPort->txFifoDeqPipelineDepth > 2) 259 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoDeqPipelineDepth for !G can't be larger than 2")); 260 } 261 else 262 /****************************************/ 263 /* Non Tx Ports */ 264 /****************************************/ 265 { 266 /* If discard override was selected , no frames may be discarded. */ 267 if(p_Params->frmDiscardOverride && p_Params->errorsToDiscard) 268 RETURN_ERROR(MAJOR, E_CONFLICT, ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue).")); 269 } 270 271 /****************************************/ 272 /* Rx and Offline parsing */ 273 /****************************************/ 274 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) 275 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 276 { 277 if(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 278 unusedMask = BMI_STATUS_OP_MASK_UNUSED; 279 else 280 unusedMask = BMI_STATUS_RX_MASK_UNUSED; 281 282 /* Check that no common bits with BMI_STATUS_MASK_UNUSED */ 283 if(p_Params->errorsToDiscard & unusedMask) 284 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("errorsToDiscard contains undefined bits")); 285 } 286 287 /****************************************/ 288 /* All ports */ 289 /****************************************/ 290 291 /* Check that divisible by 16 and not larger than 240 */ 292 if(p_Params->intContext.intContextOffset >MAX_INT_OFFSET) 293 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET)); 294 if(p_Params->intContext.intContextOffset % OFFSET_UNITS) 295 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS)); 296 297 /* check that ic size+ic internal offset, does not exceed ic block size */ 298 if(p_Params->intContext.size + p_Params->intContext.intContextOffset > MAX_IC_SIZE) 299 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE)); 300 /* Check that divisible by 16 and not larger than 256 */ 301 if(p_Params->intContext.size % OFFSET_UNITS) 302 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS)); 303 304 /* Check that divisible by 16 and not larger than 4K */ 305 if(p_Params->intContext.extBufOffset > MAX_EXT_OFFSET) 306 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET)); 307 if(p_Params->intContext.extBufOffset % OFFSET_UNITS) 308 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS)); 309 310 /* common BMI registers values */ 311 if((!p_FmPort->tasks.num) || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)) 312 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS)); 313 if(p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS) 314 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); 315 if((!p_FmPort->openDmas.num) || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)) 316 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS)); 317 if(p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS) 318 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); 319 if(!p_FmPort->fifoBufs.num || (p_FmPort->fifoBufs.num > BMI_MAX_FIFO_SIZE)) 320 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.num has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); 321 if(p_FmPort->fifoBufs.num % BMI_FIFO_UNITS) 322 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS)); 323 324 return E_OK; 325} 326 327static void FmPortDriverParamFree(t_FmPort *p_FmPort) 328{ 329 if(p_FmPort->p_FmPortDriverParam) 330 { 331 XX_Free(p_FmPort->p_FmPortDriverParam); 332 p_FmPort->p_FmPortDriverParam = NULL; 333 } 334} 335 336static t_Error SetExtBufferPools(t_FmPort *p_FmPort) 337{ 338 t_FmPortExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools; 339 t_FmPortBufPoolDepletion *p_BufPoolDepletion = &p_FmPort->p_FmPortDriverParam->bufPoolDepletion; 340 volatile uint32_t *p_ExtBufRegs; 341 volatile uint32_t *p_BufPoolDepletionReg; 342 bool rxPort; 343 bool found; 344 uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; 345 uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; 346 uint8_t count = 0; 347 uint8_t numOfPools; 348 uint16_t bufSize = 0, largestBufSize = 0; 349 int i=0, j=0, k=0; 350 uint32_t tmpReg, vector, minFifoSizeRequired=0; 351 352 memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS); 353 memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS); 354 memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmPortExtPools)); 355 356 switch(p_FmPort->portType) 357 { 358 case(e_FM_PORT_TYPE_RX_10G): 359 case(e_FM_PORT_TYPE_RX): 360 p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi; 361 p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_mpd; 362 rxPort = TRUE; 363 break; 364 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 365 p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi; 366 p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ompd; 367 rxPort = FALSE; 368 break; 369 default: 370 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for port type")); 371 } 372 373 /* First we copy the external buffers pools information to an ordered local array */ 374 for(i=0;i<p_ExtBufPools->numOfPoolsUsed;i++) 375 { 376 /* get pool size */ 377 bufSize = p_ExtBufPools->extBufPool[i].size; 378 379 /* keep sizes in an array according to poolId for direct access */ 380 sizesArray[p_ExtBufPools->extBufPool[i].id] = bufSize; 381 382 /* save poolId in an ordered array according to size */ 383 for (j=0;j<=i;j++) 384 { 385 /* this is the next free place in the array */ 386 if (j==i) 387 orderedArray[i] = p_ExtBufPools->extBufPool[i].id; 388 else 389 { 390 /* find the right place for this poolId */ 391 if(bufSize < sizesArray[orderedArray[j]]) 392 { 393 /* move the poolIds one place ahead to make room for this poolId */ 394 for(k=i;k>j;k--) 395 orderedArray[k] = orderedArray[k-1]; 396 397 /* now k==j, this is the place for the new size */ 398 orderedArray[k] = p_ExtBufPools->extBufPool[i].id; 399 break; 400 } 401 } 402 } 403 } 404 405 /* build the register value */ 406 407 for(i=0;i<p_ExtBufPools->numOfPoolsUsed;i++) 408 { 409 tmpReg = BMI_EXT_BUF_POOL_VALID | BMI_EXT_BUF_POOL_EN_COUNTER; 410 tmpReg |= ((uint32_t)orderedArray[i] << BMI_EXT_BUF_POOL_ID_SHIFT); 411 tmpReg |= sizesArray[orderedArray[i]]; 412 /* functionality available only for some deriviatives (limited by config) */ 413 if(p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 414 for(j=0;j<p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;j++) 415 if(orderedArray[i] == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j]) 416 { 417 tmpReg |= BMI_EXT_BUF_POOL_BACKUP; 418 break; 419 } 420 WRITE_UINT32(*(p_ExtBufRegs+i), tmpReg); 421 } 422 423 if(p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 424 XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools); 425 426 numOfPools = (uint8_t)(rxPort ? FM_PORT_MAX_NUM_OF_EXT_POOLS:FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS); 427 428 /* clear unused pools */ 429 for(i=p_ExtBufPools->numOfPoolsUsed;i<numOfPools;i++) 430 WRITE_UINT32(*(p_ExtBufRegs+i), 0); 431 432 p_FmPort->rxPoolsParams.largestBufSize = largestBufSize = sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed-1]]; 433 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 434 { 435#ifdef FM_FIFO_ALLOCATION_OLD_ALG 436 t_FmRevisionInfo revInfo; 437 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 438 439 if(revInfo.majorRev != 4) 440 { 441 minFifoSizeRequired = (uint32_t)(((largestBufSize % BMI_FIFO_UNITS) ? 442 ((largestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) : 443 largestBufSize) + 444 (7*BMI_FIFO_UNITS)); 445 } 446 else 447#endif /* FM_FIFO_ALLOCATION_OLD_ALG */ 448 { 449 p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed; 450 if(p_ExtBufPools->numOfPoolsUsed == 1) 451 minFifoSizeRequired = 8*BMI_FIFO_UNITS; 452 else 453 { 454 uint16_t secondLargestBufSize = sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed-2]]; 455 p_FmPort->rxPoolsParams.secondLargestBufSize = secondLargestBufSize; 456 minFifoSizeRequired = (uint32_t)(((secondLargestBufSize % BMI_FIFO_UNITS) ? 457 ((secondLargestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) : 458 secondLargestBufSize) + 459 (7*BMI_FIFO_UNITS)); 460 } 461 } 462 if(p_FmPort->fifoBufs.num < minFifoSizeRequired) 463 { 464 p_FmPort->fifoBufs.num = minFifoSizeRequired; 465 DBG(INFO, ("FIFO size for Rx port enlarged to %d",minFifoSizeRequired)); 466 } 467 } 468 469 /* check if pool size is not too big */ 470 /* This is a definition problem in which if the fifo for the RX port 471 is lower than the largest pool size the hardware will allocate scatter gather 472 buffers even though the frame size can fit in a single buffer. */ 473 if (largestBufSize > p_FmPort->fifoBufs.num) 474 DBG(WARNING, ("Frame larger than port Fifo size (%u) will be split to more than a single buffer (S/G) even if shorter than largest buffer size (%u)", 475 p_FmPort->fifoBufs.num, largestBufSize)); 476 477 /* pool depletion */ 478 tmpReg = 0; 479 if(p_BufPoolDepletion->numberOfPoolsModeEnable) 480 { 481 /* calculate vector for number of pools depletion */ 482 found = FALSE; 483 vector = 0; 484 count = 0; 485 for(i=0;i<BM_MAX_NUM_OF_POOLS;i++) 486 { 487 if(p_BufPoolDepletion->poolsToConsider[i]) 488 { 489 for(j=0;j<p_ExtBufPools->numOfPoolsUsed;j++) 490 { 491 if (i == orderedArray[j]) 492 { 493 vector |= 0x80000000 >> j; 494 found = TRUE; 495 count++; 496 break; 497 } 498 } 499 if (!found) 500 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); 501 else 502 found = FALSE; 503 } 504 } 505 if (count < p_BufPoolDepletion->numOfPools) 506 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined.")); 507 508 /* configure num of pools and vector for number of pools mode */ 509 tmpReg |= (((uint32_t)p_BufPoolDepletion->numOfPools - 1) << BMI_POOL_DEP_NUM_OF_POOLS_SHIFT); 510 tmpReg |= vector; 511 } 512 513 if(p_BufPoolDepletion->singlePoolModeEnable) 514 { 515 /* calculate vector for number of pools depletion */ 516 found = FALSE; 517 vector = 0; 518 count = 0; 519 for(i=0;i<BM_MAX_NUM_OF_POOLS;i++) 520 { 521 if(p_BufPoolDepletion->poolsToConsiderForSingleMode[i]) 522 { 523 for(j=0;j<p_ExtBufPools->numOfPoolsUsed;j++) 524 { 525 if (i == orderedArray[j]) 526 { 527 vector |= 0x00000080 >> j; 528 found = TRUE; 529 count++; 530 break; 531 } 532 } 533 if (!found) 534 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); 535 else 536 found = FALSE; 537 } 538 } 539 if (!count) 540 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion.")); 541 542 /* configure num of pools and vector for number of pools mode */ 543 tmpReg |= vector; 544 } 545 546 WRITE_UINT32(*p_BufPoolDepletionReg, tmpReg); 547 548 return E_OK; 549} 550 551static t_Error ClearPerfCnts(t_FmPort *p_FmPort) 552{ 553 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0); 554 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0); 555 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0); 556 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0); 557 return E_OK; 558} 559 560static t_Error BmiRxPortInit(t_FmPort *p_FmPort) 561{ 562 t_FmPortRxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs; 563 uint32_t tmpReg; 564 t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; 565 uint32_t errorsToEnq = 0; 566 t_FmPortPerformanceCnt performanceContersParams; 567 t_Error err; 568 569 /* check that port is not busy */ 570 if (GET_UINT32(p_Regs->fmbm_rcfg) & BMI_PORT_CFG_EN) 571 RETURN_ERROR(MAJOR, E_INVALID_STATE, 572 ("Port(%d,%d) is already enabled",p_FmPort->portType, p_FmPort->portId)); 573 574 /* Set Config register */ 575 tmpReg = 0; 576 if (p_FmPort->imEn) 577 tmpReg |= BMI_PORT_CFG_IM; 578 /* No discard - all error frames go to error queue */ 579 else if (p_Params->frmDiscardOverride) 580 tmpReg |= BMI_PORT_CFG_FDOVR; 581 582 WRITE_UINT32(p_Regs->fmbm_rcfg, tmpReg); 583 584 /* Configure dma attributes */ 585 tmpReg = 0; 586 tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; 587 tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; 588 tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; 589 tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; 590 if(p_Params->dmaWriteOptimize) 591 tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE; 592 593 WRITE_UINT32(p_Regs->fmbm_rda, tmpReg); 594 595 /* Configure Rx Fifo params */ 596 tmpReg = 0; 597 tmpReg |= ((p_Params->rxFifoPriElevationLevel/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_PRI_ELEVATION_SHIFT); 598 tmpReg |= ((p_Params->rxFifoThreshold/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_THRESHOLD_SHIFT); 599 600 WRITE_UINT32(p_Regs->fmbm_rfp, tmpReg); 601 602 { 603#ifdef FM_NO_THRESHOLD_REG 604 t_FmRevisionInfo revInfo; 605 606 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 607 if (revInfo.majorRev > 1) 608#endif /* FM_NO_THRESHOLD_REG */ 609 /* always allow access to the extra resources */ 610 WRITE_UINT32(p_Regs->fmbm_reth, BMI_RX_FIFO_THRESHOLD_BC); 611 } 612 613 /* frame end parameters */ 614 tmpReg = 0; 615 tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_RX_FRAME_END_CS_IGNORE_SHIFT); 616 tmpReg |= ((uint32_t)p_Params->cutBytesFromEnd<< BMI_RX_FRAME_END_CUT_SHIFT); 617 618 WRITE_UINT32(p_Regs->fmbm_rfed, tmpReg); 619 620 /* IC parameters */ 621 tmpReg = 0; 622 tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); 623 tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); 624 tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); 625 626 WRITE_UINT32(p_Regs->fmbm_ricp, tmpReg); 627 628 if (!p_FmPort->imEn) 629 { 630 /* check if the largest external buffer pool is large enough */ 631 if(p_Params->bufMargins.startMargins + MIN_EXT_BUF_SIZE + p_Params->bufMargins.endMargins > p_FmPort->rxPoolsParams.largestBufSize) 632 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", 633 p_Params->bufMargins.startMargins, p_Params->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize)); 634 635 /* buffer margins */ 636 tmpReg = 0; 637 tmpReg |= (((uint32_t)p_Params->bufMargins.startMargins) << BMI_EXT_BUF_MARG_START_SHIFT); 638 tmpReg |= (((uint32_t)p_Params->bufMargins.endMargins) << BMI_EXT_BUF_MARG_END_SHIFT); 639 640 WRITE_UINT32(p_Regs->fmbm_rebm, tmpReg); 641 } 642 643 644 if(p_FmPort->internalBufferOffset) 645 { 646 tmpReg = (uint32_t)((p_FmPort->internalBufferOffset % OFFSET_UNITS) ? 647 (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1): 648 (p_FmPort->internalBufferOffset/OFFSET_UNITS)); 649 p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS); 650 WRITE_UINT32(p_Regs->fmbm_rim, tmpReg << BMI_IM_FOF_SHIFT); 651 } 652 653 /* NIA */ 654 if (p_FmPort->imEn) 655 WRITE_UINT32(p_Regs->fmbm_rfne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX); 656 else 657 { 658 tmpReg = 0; 659 if (p_Params->forwardReuseIntContext) 660 tmpReg |= BMI_PORT_RFNE_FRWD_RPD; 661 /* L3/L4 checksum verify is enabled by default. */ 662 /*tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C;*/ 663 WRITE_UINT32(p_Regs->fmbm_rfne, tmpReg | NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); 664 } 665 WRITE_UINT32(p_Regs->fmbm_rfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); 666 667 /* command attribute */ 668 tmpReg = BMI_CMD_RX_MR_DEF; 669 if (!p_FmPort->imEn) 670 { 671 tmpReg |= BMI_CMD_ATTR_ORDER; 672 if(p_Params->syncReq) 673 tmpReg |= BMI_CMD_ATTR_SYNC; 674 tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); 675 } 676 677 WRITE_UINT32(p_Regs->fmbm_rfca, tmpReg); 678 679 /* default queues */ 680 if (!p_FmPort->imEn) 681 { 682 WRITE_UINT32(p_Regs->fmbm_rfqid, p_Params->dfltFqid); 683 WRITE_UINT32(p_Regs->fmbm_refqid, p_Params->errFqid); 684 } 685 686 /* set counters */ 687 WRITE_UINT32(p_Regs->fmbm_rstc, BMI_COUNTERS_EN); 688 689 performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; 690 performanceContersParams.queueCompVal = 1; 691 performanceContersParams.dmaCompVal =(uint8_t) p_FmPort->openDmas.num; 692 performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; 693 if((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams)) != E_OK) 694 RETURN_ERROR(MAJOR, err, NO_MSG); 695 696 WRITE_UINT32(p_Regs->fmbm_rpc, BMI_COUNTERS_EN); 697 698 /* error/status mask - check that if discard OV is set, no 699 discard is required for specific errors.*/ 700 WRITE_UINT32(p_Regs->fmbm_rfsdm, p_Params->errorsToDiscard); 701 702 errorsToEnq = (RX_ERRS_TO_ENQ & ~p_Params->errorsToDiscard); 703 WRITE_UINT32(p_Regs->fmbm_rfsem, errorsToEnq); 704 705#ifdef FM_BMI_TO_RISC_ENQ_ERRATA_FMANc 706 if((GET_UINT32(p_Regs->fmbm_rfene) && NIA_ENG_MASK)== NIA_ENG_FM_CTL) 707 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("NIA not supported at this stage")); 708#endif /* FM_BMI_TO_RISC_ENQ_ERRATA_FMANc */ 709 710 return E_OK; 711} 712 713static t_Error BmiTxPortInit(t_FmPort *p_FmPort) 714{ 715 t_FmPortTxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs; 716 uint32_t tmpReg; 717 t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; 718 /*uint32_t rateCountUnit;*/ 719 t_FmPortPerformanceCnt performanceContersParams; 720 721 /* check that port is not busy */ 722 if (GET_UINT32(p_Regs->fmbm_tcfg) & BMI_PORT_CFG_EN) 723 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); 724 725 tmpReg = 0; 726 if (p_FmPort->imEn) 727 tmpReg |= BMI_PORT_CFG_IM; 728 729 WRITE_UINT32(p_Regs->fmbm_tcfg, tmpReg); 730 731 /* Configure dma attributes */ 732 tmpReg = 0; 733 tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; 734 tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; 735 tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; 736 tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; 737 738 WRITE_UINT32(p_Regs->fmbm_tda, tmpReg); 739 740 /* Configure Tx Fifo params */ 741 tmpReg = 0; 742 tmpReg |= ((p_Params->txFifoMinFillLevel/BMI_FIFO_UNITS) << BMI_TX_FIFO_MIN_FILL_SHIFT); 743 tmpReg |= (((uint32_t)p_FmPort->txFifoDeqPipelineDepth - 1) << BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT); 744 tmpReg |= ((p_Params->txFifoLowComfLevel/BMI_FIFO_UNITS - 1) << BMI_TX_LOW_COMF_SHIFT); 745 746 WRITE_UINT32(p_Regs->fmbm_tfp, tmpReg); 747 748 /* frame end parameters */ 749 tmpReg = 0; 750 tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_TX_FRAME_END_CS_IGNORE_SHIFT); 751 752 WRITE_UINT32(p_Regs->fmbm_tfed, tmpReg); 753 754 if (!p_FmPort->imEn) 755 { 756 /* IC parameters */ 757 tmpReg = 0; 758 tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); 759 tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); 760 tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); 761 762 WRITE_UINT32(p_Regs->fmbm_ticp, tmpReg); 763 } 764 765 /* NIA */ 766 if (p_FmPort->imEn) 767 { 768 WRITE_UINT32(p_Regs->fmbm_tfne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX); 769 WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX); 770 } 771 else 772 { 773 WRITE_UINT32(p_Regs->fmbm_tfne, NIA_ENG_QMI_DEQ); 774 WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); 775 /* The line bellow is a trick so the FM will not release the buffer 776 to BM nor will try to enq the frame to QM */ 777 if(!p_Params->dfltFqid && p_Params->dontReleaseBuf) 778 { 779 /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to 780 * act acording to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release 781 * buffers to BM regardless of fmbm_tfene 782 */ 783 WRITE_UINT32(p_Regs->fmbm_tcfqid, 0xFFFFFF); 784 WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); 785 } 786 } 787 788 /* command attribute */ 789 tmpReg = BMI_CMD_TX_MR_DEF; 790 if (p_FmPort->imEn) 791 tmpReg |= BMI_CMD_MR_DEAS; 792 else 793 { 794 tmpReg |= BMI_CMD_ATTR_ORDER; 795 /* if we set syncReq, we may get stuck when HC command is running */ 796 /*if(p_Params->syncReq) 797 tmpReg |= BMI_CMD_ATTR_SYNC;*/ 798 tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); 799 } 800 801 WRITE_UINT32(p_Regs->fmbm_tfca, tmpReg); 802 803 /* default queues */ 804 if (!p_FmPort->imEn) 805 { 806 if(p_Params->dfltFqid || !p_Params->dontReleaseBuf) 807 WRITE_UINT32(p_Regs->fmbm_tcfqid, p_Params->dfltFqid); 808 WRITE_UINT32(p_Regs->fmbm_tfeqid, p_Params->errFqid); 809 } 810 811 /* statistics & performance counters */ 812 WRITE_UINT32(p_Regs->fmbm_tstc, BMI_COUNTERS_EN); 813 814 performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; 815 performanceContersParams.queueCompVal = 1; 816 performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; 817 performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; 818 FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams); 819 820 WRITE_UINT32(p_Regs->fmbm_tpc, BMI_COUNTERS_EN); 821 822 return E_OK; 823} 824 825static t_Error BmiOhPortInit(t_FmPort *p_FmPort) 826{ 827 t_FmPortOhBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs; 828 uint32_t tmpReg, errorsToEnq = 0; 829 t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; 830 t_FmPortPerformanceCnt performanceContersParams; 831 t_Error err; 832 833 /* check that port is not busy */ 834 if (GET_UINT32(p_Regs->fmbm_ocfg) & BMI_PORT_CFG_EN) 835 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); 836 837 /* Configure dma attributes */ 838 tmpReg = 0; 839 tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT; 840 tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT; 841 tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT; 842 tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT; 843 if(p_Params->dmaWriteOptimize) 844 tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE; 845 846 WRITE_UINT32(p_Regs->fmbm_oda, tmpReg); 847 848 /* IC parameters */ 849 tmpReg = 0; 850 tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT); 851 tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT); 852 tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT); 853 854 WRITE_UINT32(p_Regs->fmbm_oicp, tmpReg); 855 856 /* NIA */ 857 WRITE_UINT32(p_Regs->fmbm_ofdne, NIA_ENG_QMI_DEQ); 858 859 if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND) 860 WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ); 861 else 862 WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); 863 864 /* command attribute */ 865 if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND) 866 tmpReg = BMI_CMD_MR_DEAS | BMI_CMD_MR_MA; 867 else 868 tmpReg = BMI_CMD_ATTR_ORDER | BMI_CMD_MR_DEAS | BMI_CMD_MR_MA; 869 870 if(p_Params->syncReq) 871 tmpReg |= BMI_CMD_ATTR_SYNC; 872 tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT); 873 WRITE_UINT32(p_Regs->fmbm_ofca, tmpReg); 874 875 /* No discard - all error frames go to error queue */ 876 if (p_Params->frmDiscardOverride) 877 tmpReg = BMI_PORT_CFG_FDOVR; 878 else 879 tmpReg = 0; 880 WRITE_UINT32(p_Regs->fmbm_ocfg, tmpReg); 881 882 if(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 883 { 884 WRITE_UINT32(p_Regs->fmbm_ofsdm, p_Params->errorsToDiscard); 885 886 errorsToEnq = (OP_ERRS_TO_ENQ & ~p_Params->errorsToDiscard); 887 WRITE_UINT32(p_Regs->fmbm_ofsem, errorsToEnq); 888 889 /* NIA */ 890 WRITE_UINT32(p_Regs->fmbm_ofne, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); 891 { 892#ifdef FM_NO_OP_OBSERVED_POOLS 893 t_FmRevisionInfo revInfo; 894 895 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 896 if ((revInfo.majorRev == 4) && (p_Params->enBufPoolDepletion)) 897#endif /* FM_NO_OP_OBSERVED_POOLS */ 898 { 899 /* define external buffer pools */ 900 err = SetExtBufferPools(p_FmPort); 901 if(err) 902 RETURN_ERROR(MAJOR, err, NO_MSG); 903 } 904 } 905 } 906 else 907 /* NIA */ 908 WRITE_UINT32(p_Regs->fmbm_ofne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC); 909 910 /* default queues */ 911 WRITE_UINT32(p_Regs->fmbm_ofqid, p_Params->dfltFqid); 912 WRITE_UINT32(p_Regs->fmbm_oefqid, p_Params->errFqid); 913 914 if(p_FmPort->internalBufferOffset) 915 { 916 tmpReg = (uint32_t)((p_FmPort->internalBufferOffset % OFFSET_UNITS) ? 917 (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1): 918 (p_FmPort->internalBufferOffset/OFFSET_UNITS)); 919 p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS); 920 WRITE_UINT32(p_Regs->fmbm_oim, tmpReg << BMI_IM_FOF_SHIFT); 921 } 922 /* statistics & performance counters */ 923 WRITE_UINT32(p_Regs->fmbm_ostc, BMI_COUNTERS_EN); 924 925 performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; 926 performanceContersParams.queueCompVal = 0; 927 performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; 928 performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num; 929 FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams); 930 931 WRITE_UINT32(p_Regs->fmbm_opc, BMI_COUNTERS_EN); 932 933 return E_OK; 934} 935 936static t_Error QmiInit(t_FmPort *p_FmPort) 937{ 938 t_FmPortDriverParam *p_Params = NULL; 939 uint32_t tmpReg; 940 941 p_Params = p_FmPort->p_FmPortDriverParam; 942 943 /* check that port is not busy */ 944 if(((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 945 (p_FmPort->portType != e_FM_PORT_TYPE_RX)) && 946 (GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN)) 947 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled")); 948 949 /* enable & clear counters */ 950 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, QMI_PORT_CFG_EN_COUNTERS); 951 952 /* The following is done for non-Rx ports only */ 953 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 954 (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 955 { 956 if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || 957 (p_FmPort->portType == e_FM_PORT_TYPE_TX)) 958 { 959 /* define dequeue NIA */ 960 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX); 961 /* define enqueue NIA */ 962 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); 963 } 964 else /* for HC & OP */ 965 { 966 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH); 967 /* define enqueue NIA */ 968 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); 969 } 970 971 /* configure dequeue */ 972 tmpReg = 0; 973 if(p_Params->deqHighPriority) 974 tmpReg |= QMI_DEQ_CFG_PRI; 975 976 switch(p_Params->deqType) 977 { 978 case(e_FM_PORT_DEQ_TYPE1): 979 tmpReg |= QMI_DEQ_CFG_TYPE1; 980 break; 981 case(e_FM_PORT_DEQ_TYPE2): 982 tmpReg |= QMI_DEQ_CFG_TYPE2; 983 break; 984 case(e_FM_PORT_DEQ_TYPE3): 985 tmpReg |= QMI_DEQ_CFG_TYPE3; 986 break; 987 default: 988 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue type")); 989 } 990 991#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT 992 switch(p_Params->deqPrefetchOption) 993 { 994 case(e_FM_PORT_DEQ_NO_PREFETCH): 995 /* Do nothing - QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_1_FRAME = 0 */ 996 break; 997 case(e_FM_PORT_DEQ_PARTIAL_PREFETCH): 998 tmpReg |= QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES; 999 break; 1000 case(e_FM_PORT_DEQ_FULL_PREFETCH): 1001 tmpReg |= QMI_DEQ_CFG_PREFETCH_NO_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES; 1002 break; 1003 default: 1004 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue prefetch option")); 1005 } 1006#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ 1007 1008 tmpReg |= p_Params->deqByteCnt; 1009 tmpReg |= (uint32_t)p_Params->deqSubPortal << QMI_DEQ_CFG_SUBPORTAL_SHIFT; 1010 1011 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndc, tmpReg); 1012 } 1013 else /* rx port */ 1014 /* define enqueue NIA */ 1015 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); 1016 1017 return E_OK; 1018} 1019 1020static t_Error BmiRxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) 1021{ 1022 t_FmPortRxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs; 1023 1024 /* check that counters are enabled */ 1025 switch(counter) 1026 { 1027 case(e_FM_PORT_COUNTERS_CYCLE): 1028 case(e_FM_PORT_COUNTERS_TASK_UTIL): 1029 case(e_FM_PORT_COUNTERS_QUEUE_UTIL): 1030 case(e_FM_PORT_COUNTERS_DMA_UTIL): 1031 case(e_FM_PORT_COUNTERS_FIFO_UTIL): 1032 case(e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 1033 /* performance counters - may be read when disabled */ 1034 break; 1035 case(e_FM_PORT_COUNTERS_FRAME): 1036 case(e_FM_PORT_COUNTERS_DISCARD_FRAME): 1037 case(e_FM_PORT_COUNTERS_RX_BAD_FRAME): 1038 case(e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 1039 case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 1040 case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 1041 case(e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 1042 case(e_FM_PORT_COUNTERS_DEALLOC_BUF): 1043 if(!(GET_UINT32(p_BmiRegs->fmbm_rstc) & BMI_COUNTERS_EN)) 1044 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 1045 break; 1046 default: 1047 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); 1048 } 1049 1050 /* Set counter */ 1051 switch(counter) 1052 { 1053 case(e_FM_PORT_COUNTERS_CYCLE): 1054 *p_Ptr = &p_BmiRegs->fmbm_rccn; 1055 break; 1056 case(e_FM_PORT_COUNTERS_TASK_UTIL): 1057 *p_Ptr = &p_BmiRegs->fmbm_rtuc; 1058 break; 1059 case(e_FM_PORT_COUNTERS_QUEUE_UTIL): 1060 *p_Ptr = &p_BmiRegs->fmbm_rrquc; 1061 break; 1062 case(e_FM_PORT_COUNTERS_DMA_UTIL): 1063 *p_Ptr = &p_BmiRegs->fmbm_rduc; 1064 break; 1065 case(e_FM_PORT_COUNTERS_FIFO_UTIL): 1066 *p_Ptr = &p_BmiRegs->fmbm_rfuc; 1067 break; 1068 case(e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): 1069 *p_Ptr = &p_BmiRegs->fmbm_rpac; 1070 break; 1071 case(e_FM_PORT_COUNTERS_FRAME): 1072 *p_Ptr = &p_BmiRegs->fmbm_rfrc; 1073 break; 1074 case(e_FM_PORT_COUNTERS_DISCARD_FRAME): 1075 *p_Ptr = &p_BmiRegs->fmbm_rfcd; 1076 break; 1077 case(e_FM_PORT_COUNTERS_RX_BAD_FRAME): 1078 *p_Ptr = &p_BmiRegs->fmbm_rfbc; 1079 break; 1080 case(e_FM_PORT_COUNTERS_RX_LARGE_FRAME): 1081 *p_Ptr = &p_BmiRegs->fmbm_rlfc; 1082 break; 1083 case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 1084 *p_Ptr = &p_BmiRegs->fmbm_rffc; 1085 break; 1086 case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 1087#ifdef FM_PORT_COUNTERS_ERRATA_FMANg 1088 { 1089 t_FmRevisionInfo revInfo; 1090 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 1091 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 1092 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Requested counter is not available in rev1")); 1093 } 1094#endif /* FM_PORT_COUNTERS_ERRATA_FMANg */ 1095 *p_Ptr = &p_BmiRegs->fmbm_rfldec; 1096 break; 1097 case(e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): 1098 *p_Ptr = &p_BmiRegs->fmbm_rodc; 1099 break; 1100 case(e_FM_PORT_COUNTERS_DEALLOC_BUF): 1101 *p_Ptr = &p_BmiRegs->fmbm_rbdc; 1102 break; 1103 default: 1104 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); 1105 } 1106 1107 return E_OK; 1108} 1109 1110static t_Error BmiTxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) 1111{ 1112 t_FmPortTxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs; 1113 1114 /* check that counters are enabled */ 1115 switch(counter) 1116 { 1117 case(e_FM_PORT_COUNTERS_CYCLE): 1118 case(e_FM_PORT_COUNTERS_TASK_UTIL): 1119 case(e_FM_PORT_COUNTERS_QUEUE_UTIL): 1120 case(e_FM_PORT_COUNTERS_DMA_UTIL): 1121 case(e_FM_PORT_COUNTERS_FIFO_UTIL): 1122 /* performance counters - may be read when disabled */ 1123 break; 1124 case(e_FM_PORT_COUNTERS_FRAME): 1125 case(e_FM_PORT_COUNTERS_DISCARD_FRAME): 1126 case(e_FM_PORT_COUNTERS_LENGTH_ERR): 1127 case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 1128 case(e_FM_PORT_COUNTERS_DEALLOC_BUF): 1129 if(!(GET_UINT32(p_BmiRegs->fmbm_tstc) & BMI_COUNTERS_EN)) 1130 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 1131 break; 1132 default: 1133 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports")); 1134 } 1135 1136 /* Set counter */ 1137 switch(counter) 1138 { 1139 case(e_FM_PORT_COUNTERS_CYCLE): 1140 *p_Ptr = &p_BmiRegs->fmbm_tccn; 1141 break; 1142 case(e_FM_PORT_COUNTERS_TASK_UTIL): 1143 *p_Ptr = &p_BmiRegs->fmbm_ttuc; 1144 break; 1145 case(e_FM_PORT_COUNTERS_QUEUE_UTIL): 1146 *p_Ptr = &p_BmiRegs->fmbm_ttcquc; 1147 break; 1148 case(e_FM_PORT_COUNTERS_DMA_UTIL): 1149 *p_Ptr = &p_BmiRegs->fmbm_tduc; 1150 break; 1151 case(e_FM_PORT_COUNTERS_FIFO_UTIL): 1152 *p_Ptr = &p_BmiRegs->fmbm_tfuc; 1153 break; 1154 case(e_FM_PORT_COUNTERS_FRAME): 1155 *p_Ptr = &p_BmiRegs->fmbm_tfrc; 1156 break; 1157 case(e_FM_PORT_COUNTERS_DISCARD_FRAME): 1158 *p_Ptr = &p_BmiRegs->fmbm_tfdc; 1159 break; 1160 case(e_FM_PORT_COUNTERS_LENGTH_ERR): 1161 *p_Ptr = &p_BmiRegs->fmbm_tfledc; 1162 break; 1163 case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 1164 *p_Ptr = &p_BmiRegs->fmbm_tfufdc; 1165 break; 1166 case(e_FM_PORT_COUNTERS_DEALLOC_BUF): 1167 *p_Ptr = &p_BmiRegs->fmbm_tbdc; 1168 break; 1169 default: 1170 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports")); 1171 } 1172 1173 return E_OK; 1174} 1175 1176static t_Error BmiOhPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr) 1177{ 1178 t_FmPortOhBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs; 1179 1180 /* check that counters are enabled */ 1181 switch(counter) 1182 { 1183 case(e_FM_PORT_COUNTERS_CYCLE): 1184 case(e_FM_PORT_COUNTERS_TASK_UTIL): 1185 case(e_FM_PORT_COUNTERS_DMA_UTIL): 1186 case(e_FM_PORT_COUNTERS_FIFO_UTIL): 1187 /* performance counters - may be read when disabled */ 1188 break; 1189 case(e_FM_PORT_COUNTERS_FRAME): 1190 case(e_FM_PORT_COUNTERS_DISCARD_FRAME): 1191 case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 1192 case(e_FM_PORT_COUNTERS_WRED_DISCARD): 1193 case(e_FM_PORT_COUNTERS_LENGTH_ERR): 1194 case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 1195 case(e_FM_PORT_COUNTERS_DEALLOC_BUF): 1196 if(!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN)) 1197 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 1198 break; 1199 case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): /* only valid for offline parsing */ 1200 if(p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 1201 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Host Command ports")); 1202 if(!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN)) 1203 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 1204 break; 1205 default: 1206 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for O/H ports")); 1207 } 1208 1209 /* Set counter */ 1210 switch(counter) 1211 { 1212 case(e_FM_PORT_COUNTERS_CYCLE): 1213 *p_Ptr = &p_BmiRegs->fmbm_occn; 1214 break; 1215 case(e_FM_PORT_COUNTERS_TASK_UTIL): 1216 *p_Ptr = &p_BmiRegs->fmbm_otuc; 1217 break; 1218 case(e_FM_PORT_COUNTERS_DMA_UTIL): 1219 *p_Ptr = &p_BmiRegs->fmbm_oduc; 1220 break; 1221 case(e_FM_PORT_COUNTERS_FIFO_UTIL): 1222 *p_Ptr = &p_BmiRegs->fmbm_ofuc; 1223 break; 1224 case(e_FM_PORT_COUNTERS_FRAME): 1225 *p_Ptr = &p_BmiRegs->fmbm_ofrc; 1226 break; 1227 case(e_FM_PORT_COUNTERS_DISCARD_FRAME): 1228 *p_Ptr = &p_BmiRegs->fmbm_ofdc; 1229 break; 1230 case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): 1231 *p_Ptr = &p_BmiRegs->fmbm_offc; 1232 break; 1233 case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): 1234#ifdef FM_PORT_COUNTERS_ERRATA_FMANg 1235 { 1236 t_FmRevisionInfo revInfo; 1237 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 1238 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 1239 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Requested counter is not available in rev1")); 1240 } 1241#endif /* FM_PORT_COUNTERS_ERRATA_FMANg */ 1242 *p_Ptr = &p_BmiRegs->fmbm_ofldec; 1243 break; 1244 case(e_FM_PORT_COUNTERS_WRED_DISCARD): 1245 *p_Ptr = &p_BmiRegs->fmbm_ofwdc; 1246 break; 1247 case(e_FM_PORT_COUNTERS_LENGTH_ERR): 1248 *p_Ptr = &p_BmiRegs->fmbm_ofledc; 1249 break; 1250 case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): 1251 *p_Ptr = &p_BmiRegs->fmbm_ofufdc; 1252 break; 1253 case(e_FM_PORT_COUNTERS_DEALLOC_BUF): 1254 *p_Ptr = &p_BmiRegs->fmbm_obdc; 1255 break; 1256 default: 1257 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for O/H ports")); 1258 } 1259 1260 return E_OK; 1261} 1262 1263static t_Error AdditionalPrsParams(t_FmPort *p_FmPort, t_FmPcdPrsAdditionalHdrParams *p_HdrParams, uint32_t *p_SoftSeqAttachReg) 1264{ 1265 uint8_t hdrNum, Ipv4HdrNum; 1266 u_FmPcdHdrPrsOpts *p_prsOpts; 1267 uint32_t tmpReg = 0, tmpPrsOffset; 1268 1269 if(IS_PRIVATE_HEADER(p_HdrParams->hdr) || IS_SPECIAL_HEADER(p_HdrParams->hdr)) 1270 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("No additional parameters for private or special headers.")); 1271 1272 if(p_HdrParams->errDisable) 1273 tmpReg |= PRS_HDR_ERROR_DIS; 1274 1275 /* Set parser options */ 1276 if(p_HdrParams->usePrsOpts) 1277 { 1278 p_prsOpts = &p_HdrParams->prsOpts; 1279 switch(p_HdrParams->hdr) 1280 { 1281 case(HEADER_TYPE_MPLS): 1282 if(p_prsOpts->mplsPrsOptions.labelInterpretationEnable) 1283 tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN; 1284 GET_PRS_HDR_NUM(hdrNum, p_prsOpts->mplsPrsOptions.nextParse); 1285 if(hdrNum == ILLEGAL_HDR_NUM) 1286 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1287 GET_PRS_HDR_NUM(Ipv4HdrNum, HEADER_TYPE_IPv4); 1288 if(hdrNum < Ipv4HdrNum) 1289 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1290 ("Header must be equal or higher than IPv4")); 1291 tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE) << PRS_HDR_MPLS_NEXT_HDR_SHIFT; 1292 break; 1293 case(HEADER_TYPE_PPPoE): 1294 if(p_prsOpts->pppoePrsOptions.enableMTUCheck) 1295 { 1296#ifdef FM_PPPOE_NO_MTU_CHECK 1297 t_FmRevisionInfo revInfo; 1298 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 1299 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 1300 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Invalid parser option")); 1301 else 1302#endif /* FM_PPPOE_NO_MTU_CHECK */ 1303 tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN; 1304 } 1305 break; 1306 case(HEADER_TYPE_IPv6): 1307 if(p_prsOpts->ipv6PrsOptions.routingHdrDisable) 1308 tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_DIS; 1309 break; 1310 case(HEADER_TYPE_TCP): 1311 if(p_prsOpts->tcpPrsOptions.padIgnoreChecksum) 1312 tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; 1313 break; 1314 case(HEADER_TYPE_UDP): 1315 if(p_prsOpts->udpPrsOptions.padIgnoreChecksum) 1316 tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; 1317 break; 1318 default: 1319 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header")); 1320 } 1321 } 1322 1323 /* set software parsing (address is devided in 2 since parser uses 2 byte access. */ 1324 if(p_HdrParams->swPrsEnable) 1325 { 1326 tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr, p_HdrParams->indexPerHdr); 1327 if(tmpPrsOffset == ILLEGAL_BASE) 1328 RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); 1329 tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset); 1330 } 1331 *p_SoftSeqAttachReg = tmpReg; 1332 1333 return E_OK; 1334} 1335 1336static uint32_t GetPortSchemeBindParams(t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) 1337{ 1338 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1339 uint32_t walking1Mask = 0x80000000, tmp; 1340 uint8_t idx = 0; 1341 1342 p_SchemeBind->netEnvId = p_FmPort->netEnvId; 1343 p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId; 1344 p_SchemeBind->useClsPlan = p_FmPort->useClsPlan; 1345 p_SchemeBind->numOfSchemes = 0; 1346 tmp = p_FmPort->schemesPerPortVector; 1347 if(tmp) 1348 { 1349 while (tmp) 1350 { 1351 if(tmp & walking1Mask) 1352 { 1353 p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = FmPcdKgGetSchemeSwId(p_FmPort->h_FmPcd, idx); 1354 p_SchemeBind->numOfSchemes++; 1355 tmp &= ~walking1Mask; 1356 } 1357 walking1Mask >>= 1; 1358 idx++; 1359 } 1360 } 1361 1362 return tmp; 1363} 1364 1365static t_Error BuildBufferStructure(t_FmPort *p_FmPort) 1366{ 1367 uint32_t tmp; 1368 1369 ASSERT_COND(p_FmPort); 1370 1371 /* Align start of internal context data to 16 byte */ 1372 p_FmPort->p_FmPortDriverParam->intContext.extBufOffset = 1373 (uint16_t)((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize & (OFFSET_UNITS-1)) ? 1374 ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) : 1375 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize); 1376 1377 /* Translate margin and intContext params to FM parameters */ 1378#ifdef FM_INCORRECT_CS_ERRATA_FMAN18 1379 { 1380 t_FmRevisionInfo revInfo; 1381 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 1382 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 1383 { 1384 uint8_t mod = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign % 256; 1385 if(mod) 1386 { 1387 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign += (256-mod); 1388 DBG(WARNING,("dataAlign modified to next 256 to conform with FMAN18 errata\n")); 1389 } 1390 } 1391 } 1392#endif /* FM_INCORRECT_CS_ERRATA_FMAN18 */ 1393 1394 /* Initialize with illegal value. Later we'll set legal values. */ 1395 p_FmPort->bufferOffsets.prsResultOffset = (uint32_t)ILLEGAL_BASE; 1396 p_FmPort->bufferOffsets.timeStampOffset = (uint32_t)ILLEGAL_BASE; 1397 p_FmPort->bufferOffsets.hashResultOffset= (uint32_t)ILLEGAL_BASE; 1398 p_FmPort->bufferOffsets.pcdInfoOffset = (uint32_t)ILLEGAL_BASE; 1399#ifdef DEBUG 1400 p_FmPort->bufferOffsets.debugOffset = (uint32_t)ILLEGAL_BASE; 1401#endif /* DEBUG */ 1402 1403 /* Internally the driver supports 4 options 1404 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll 1405 relate to it as 1). 1406 2. All IC context (from AD) except debug. 1407 3. Debug information only. 1408 4. All IC context (from AD) including debug. 1409 Note, that if user asks for prsResult/timestamp/hashResult and Debug, we give them (4) */ 1410 1411 /* This 'if' covers options 2 & 4. We copy from beginning of context with or without debug. */ 1412 /* If passAllOtherPCDInfo explicitly requested, or passDebugInfo+prs/ts --> we also take passAllOtherPCDInfo */ 1413 if ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo) 1414#ifdef DEBUG 1415 || (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo && 1416 (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult || 1417 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp || 1418 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult)) 1419#endif /* DEBUG */ 1420 ) 1421 { 1422#ifdef DEBUG 1423 if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo) 1424 { 1425 p_FmPort->p_FmPortDriverParam->intContext.size = 240; 1426 p_FmPort->bufferOffsets.debugOffset = 1427 (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 128); 1428 } 1429 else 1430#endif /* DEBUG */ 1431 p_FmPort->p_FmPortDriverParam->intContext.size = 128; /* must be aligned to 16 */ 1432 /* Start copying data after 16 bytes (FD) from the beginning of the internal context */ 1433 p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = 16; 1434 1435 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo) 1436 p_FmPort->bufferOffsets.pcdInfoOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; 1437 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult) 1438 p_FmPort->bufferOffsets.prsResultOffset = 1439 (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 16); 1440 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp) 1441 p_FmPort->bufferOffsets.timeStampOffset = 1442 (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 48); 1443 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) 1444 p_FmPort->bufferOffsets.hashResultOffset = 1445 (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 56); 1446 } 1447 else 1448 { 1449#ifdef DEBUG 1450 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo) 1451 { 1452 /* This case covers option 3 */ 1453 p_FmPort->p_FmPortDriverParam->intContext.size = 112; 1454 p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = 144; 1455 p_FmPort->bufferOffsets.debugOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; 1456 } 1457 else 1458#endif /* DEBUG */ 1459 { 1460 /* This case covers the options under 1 */ 1461 /* Copy size must be in 16-byte granularity. */ 1462 p_FmPort->p_FmPortDriverParam->intContext.size = 1463 (uint16_t)((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 32 : 0) + 1464 ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp || 1465 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) ? 16 : 0)); 1466 1467 /* Align start of internal context data to 16 byte */ 1468 p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = 1469 (uint8_t)(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 32 : 1470 ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp || 1471 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) ? 64 : 0)); 1472 1473 if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult) 1474 p_FmPort->bufferOffsets.prsResultOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; 1475 if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp) 1476 p_FmPort->bufferOffsets.timeStampOffset = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 1477 (p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + sizeof(t_FmPrsResult)) : 1478 p_FmPort->p_FmPortDriverParam->intContext.extBufOffset; 1479 if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) 1480 /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */ 1481 p_FmPort->bufferOffsets.hashResultOffset = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 1482 (p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + sizeof(t_FmPrsResult) + 8) : 1483 p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 8; 1484 } 1485 } 1486 1487 p_FmPort->p_FmPortDriverParam->bufMargins.startMargins = 1488 (uint16_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 1489 p_FmPort->p_FmPortDriverParam->intContext.size); 1490#ifdef FM_CAPWAP_SUPPORT 1491 /* save extra space for manip in both external and internal buffers */ 1492 if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace) 1493 { 1494 if((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE) >= 256) 1495 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + 32 can not be equal or larger to 256")); 1496 p_FmPort->bufferOffsets.manipOffset = p_FmPort->p_FmPortDriverParam->bufMargins.startMargins; 1497 p_FmPort->p_FmPortDriverParam->bufMargins.startMargins += (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE); 1498 p_FmPort->p_FmPortDriverParam->internalBufferOffset = 1499 (uint8_t)(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE); 1500 } 1501#endif /* FM_CAPWAP_SUPPORT */ 1502 1503 /* align data start */ 1504 tmp = (uint32_t)(p_FmPort->p_FmPortDriverParam->bufMargins.startMargins % 1505 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign); 1506 if (tmp) 1507 p_FmPort->p_FmPortDriverParam->bufMargins.startMargins += (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign-tmp); 1508 p_FmPort->bufferOffsets.dataOffset = p_FmPort->p_FmPortDriverParam->bufMargins.startMargins; 1509 p_FmPort->internalBufferOffset = p_FmPort->p_FmPortDriverParam->internalBufferOffset; 1510 1511 return E_OK; 1512} 1513 1514static t_Error SetPcd(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams) 1515{ 1516 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1517 t_Error err = E_OK; 1518 uint32_t tmpReg; 1519 volatile uint32_t *p_BmiNia=NULL; 1520 volatile uint32_t *p_BmiPrsNia=NULL; 1521 volatile uint32_t *p_BmiPrsStartOffset=NULL; 1522 volatile uint32_t *p_BmiInitPrsResult=NULL; 1523 volatile uint32_t *p_BmiCcBase=NULL; 1524 uint8_t hdrNum, L3HdrNum, greHdrNum; 1525 int i; 1526 bool isEmptyClsPlanGrp; 1527 uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS]; 1528 uint16_t absoluteProfileId; 1529 uint8_t physicalSchemeId; 1530 uint32_t ccTreePhysOffset; 1531 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 1532 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1533 1534 if (p_FmPort->imEn) 1535 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); 1536 1537 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 1538 (p_FmPort->portType != e_FM_PORT_TYPE_RX) && 1539 (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1540 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 1541 1542 p_FmPort->netEnvId = (uint8_t)(PTR_TO_UINT(p_PcdParams->h_NetEnv)-1); 1543 1544 p_FmPort->pcdEngines = 0; 1545 1546 /* initialize p_FmPort->pcdEngines field in port's structure */ 1547 switch(p_PcdParams->pcdSupport) 1548 { 1549 case(e_FM_PORT_PCD_SUPPORT_NONE): 1550 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected")); 1551 case(e_FM_PORT_PCD_SUPPORT_PRS_ONLY): 1552 p_FmPort->pcdEngines |= FM_PCD_PRS; 1553 break; 1554 case(e_FM_PORT_PCD_SUPPORT_PLCR_ONLY): 1555 if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) 1556 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); 1557 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1558 break; 1559 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): 1560 p_FmPort->pcdEngines |= FM_PCD_PRS; 1561 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1562 break; 1563 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): 1564 p_FmPort->pcdEngines |= FM_PCD_PRS; 1565 p_FmPort->pcdEngines |= FM_PCD_KG; 1566 break; 1567 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): 1568 p_FmPort->pcdEngines |= FM_PCD_PRS; 1569 p_FmPort->pcdEngines |= FM_PCD_CC; 1570 p_FmPort->pcdEngines |= FM_PCD_KG; 1571 break; 1572 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): 1573 p_FmPort->pcdEngines |= FM_PCD_PRS; 1574 p_FmPort->pcdEngines |= FM_PCD_KG; 1575 p_FmPort->pcdEngines |= FM_PCD_CC; 1576 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1577 break; 1578 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): 1579 p_FmPort->pcdEngines |= FM_PCD_PRS; 1580 p_FmPort->pcdEngines |= FM_PCD_KG; 1581 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1582 break; 1583 1584#ifdef FM_CAPWAP_SUPPORT 1585 case(e_FM_PORT_PCD_SUPPORT_CC_ONLY): 1586 if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) 1587 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); 1588 p_FmPort->pcdEngines |= FM_PCD_CC; 1589 break; 1590 case(e_FM_PORT_PCD_SUPPORT_CC_AND_KG): 1591 if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) 1592 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); 1593 p_FmPort->pcdEngines |= FM_PCD_CC; 1594 p_FmPort->pcdEngines |= FM_PCD_KG; 1595 break; 1596 case(e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR): 1597 if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) 1598 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required")); 1599 p_FmPort->pcdEngines |= FM_PCD_CC; 1600 p_FmPort->pcdEngines |= FM_PCD_KG; 1601 p_FmPort->pcdEngines |= FM_PCD_PLCR; 1602 break; 1603#endif /* FM_CAPWAP_SUPPORT */ 1604 default: 1605 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport")); 1606 } 1607 1608 if((p_FmPort->pcdEngines & FM_PCD_PRS) && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams > FM_PCD_PRS_NUM_OF_HDRS)) 1609 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS)); 1610 1611 /* check that parameters exist for each and only each defined engine */ 1612 if((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams) || 1613 (!!(p_FmPort->pcdEngines & FM_PCD_KG) != !!p_PcdParams->p_KgParams) || 1614 (!!(p_FmPort->pcdEngines & FM_PCD_CC) != !!p_PcdParams->p_CcParams)) 1615 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("PCD initialization structure is not consistant with pcdSupport")); 1616 1617 /* get PCD registers pointers */ 1618 switch(p_FmPort->portType) 1619 { 1620 case(e_FM_PORT_TYPE_RX_10G): 1621 case(e_FM_PORT_TYPE_RX): 1622 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; 1623 p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; 1624 p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; 1625 p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[0]; 1626 p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb; 1627 break; 1628 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1629 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; 1630 p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne; 1631 p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; 1632 p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[0]; 1633 p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_occb; 1634 break; 1635 default: 1636 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 1637 } 1638 1639 if(p_FmPort->pcdEngines & FM_PCD_KG) 1640 { 1641 1642 if(p_PcdParams->p_KgParams->numOfSchemes == 0) 1643 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For ports using Keygen, at lease one scheme must be bound. ")); 1644 /* for each scheme */ 1645 for(i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++) 1646 { 1647 physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_Schemes[i])-1); 1648 /* build vector */ 1649 p_FmPort->schemesPerPortVector |= 1 << (31 - (uint32_t)physicalSchemeId); 1650 } 1651 1652 err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd, 1653 p_FmPort->hardwarePortId, 1654 p_FmPort->netEnvId, 1655 p_FmPort->optArray, 1656 &p_FmPort->clsPlanGrpId, 1657 &isEmptyClsPlanGrp); 1658 if(err) 1659 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FmPcdKgSetOrBindToClsPlanGrp failed. ")); 1660 1661 p_FmPort->useClsPlan = !isEmptyClsPlanGrp; 1662 } 1663 1664 /* set PCD port parameter */ 1665 if(p_FmPort->pcdEngines & FM_PCD_CC) 1666 { 1667 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams->p_CcParams->h_CcTree, &ccTreePhysOffset, h_FmPort); 1668 if(err) 1669 RETURN_ERROR(MINOR, err, NO_MSG); 1670 1671 WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); 1672 p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree; 1673 } 1674 1675 /***************************/ 1676 /* configure NIA after BMI */ 1677 /***************************/ 1678 if (!CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) 1679 /* rfne may contain FDCS bits, so first we read them. */ 1680 p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; 1681 1682 /* If policer is used directly after BMI or PRS */ 1683 if((p_FmPort->pcdEngines & FM_PCD_PLCR) && 1684 ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY) || 1685 (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR))) 1686 { 1687 absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_PcdParams->p_PlcrParams->h_Profile)-1); 1688 1689 if(!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) 1690 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Private port profile not valid.")); 1691 1692 tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE); 1693 1694 if(p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ 1695 { 1696 /* update BMI HPNIA */ 1697 WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg)); 1698 } 1699 else /* e_FM_PCD_SUPPORT_PLCR_ONLY */ 1700 /* update BMI NIA */ 1701 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR); 1702 } 1703 1704#ifdef FM_CAPWAP_SUPPORT 1705 /* if CC is used directly after BMI */ 1706 if((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) || 1707 (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) || 1708 (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)) 1709 { 1710 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 1711 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only")); 1712 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); 1713 /* check that prs start offset == RIM[FOF] */ 1714 } 1715#endif /* FM_CAPWAP_SUPPORT */ 1716 1717 if (p_FmPort->pcdEngines & FM_PCD_PRS) 1718 { 1719 ASSERT_COND(p_PcdParams->p_PrsParams); 1720 /* if PRS is used it is always first */ 1721 GET_PRS_HDR_NUM(hdrNum, p_PcdParams->p_PrsParams->firstPrsHdr); 1722 if (hdrNum == ILLEGAL_HDR_NUM) 1723 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); 1724 if (!CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia)) 1725 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum)); 1726 /* set after parser NIA */ 1727 tmpReg = 0; 1728 switch(p_PcdParams->pcdSupport) 1729 { 1730 case(e_FM_PORT_PCD_SUPPORT_PRS_ONLY): 1731 WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); 1732 break; 1733 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): 1734 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): 1735 tmpReg = NIA_KG_CC_EN; 1736 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): 1737 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): 1738 if(p_PcdParams->p_KgParams->directScheme) 1739 { 1740 physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_DirectScheme)-1); 1741 /* check that this scheme was bound to this port */ 1742 for(i=0 ; i<p_PcdParams->p_KgParams->numOfSchemes; i++) 1743 if(p_PcdParams->p_KgParams->h_DirectScheme == p_PcdParams->p_KgParams->h_Schemes[i]) 1744 break; 1745 if(i == p_PcdParams->p_KgParams->numOfSchemes) 1746 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Direct scheme is not one of the port selected schemes.")); 1747 tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId); 1748 } 1749 WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg); 1750 break; 1751 case(e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): 1752 break; 1753 default: 1754 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support")); 1755 } 1756 1757 /* set start parsing offset */ 1758 /* WRITE_UINT32(*p_BmiPrsStartOffset, p_PcdParams->p_PrsParams->parsingOffset); */ 1759 1760 /************************************/ 1761 /* Parser port parameters */ 1762 /************************************/ 1763 /* stop before configuring */ 1764 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); 1765 /* wait for parser to be in idle state */ 1766 while(GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) ; 1767 1768 /* set soft seq attachment register */ 1769 memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t)); 1770 1771 /* set protocol options */ 1772 for(i=0;p_FmPort->optArray[i];i++) 1773 switch(p_FmPort->optArray[i]) 1774 { 1775 case(ETH_BROADCAST): 1776 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH) 1777 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_BC_SHIFT; 1778 break; 1779 case(ETH_MULTICAST): 1780 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH) 1781 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_MC_SHIFT; 1782 break; 1783 case(VLAN_STACKED): 1784 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_VLAN) 1785 tmpHxs[hdrNum] |= (i+1)<< PRS_HDR_VLAN_STACKED_SHIFT; 1786 break; 1787 case(MPLS_STACKED): 1788 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS) 1789 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_MPLS_STACKED_SHIFT; 1790 break; 1791 case(IPV4_BROADCAST_1): 1792 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) 1793 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_BC_SHIFT; 1794 break; 1795 case(IPV4_MULTICAST_1): 1796 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) 1797 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_MC_SHIFT; 1798 break; 1799 case(IPV4_UNICAST_2): 1800 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) 1801 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_UC_SHIFT; 1802 break; 1803 case(IPV4_MULTICAST_BROADCAST_2): 1804 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4) 1805 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_MC_BC_SHIFT; 1806 break; 1807 case(IPV6_MULTICAST_1): 1808 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) 1809 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_1_MC_SHIFT; 1810 break; 1811 case(IPV6_UNICAST_2): 1812 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) 1813 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_2_UC_SHIFT; 1814 break; 1815 case(IPV6_MULTICAST_2): 1816 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6) 1817 tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_2_MC_SHIFT; 1818 break; 1819 } 1820 1821 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP)) 1822 { 1823 p_PcdParams->p_PrsParams->additionalParams 1824 [p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr = HEADER_TYPE_UDP; 1825 p_PcdParams->p_PrsParams->additionalParams 1826 [p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable = TRUE; 1827 p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++; 1828 } 1829 1830 /* set MPLS default next header - HW reset workaround */ 1831 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS) 1832 tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN; 1833 GET_PRS_HDR_NUM(L3HdrNum, HEADER_TYPE_USER_DEFINED_L3); 1834 tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT; 1835 1836 /* for GRE, disable errors */ 1837 GET_PRS_HDR_NUM(greHdrNum, HEADER_TYPE_GRE); 1838 tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS; 1839 1840 /* config additional params for specific headers */ 1841 for(i=0 ; i<p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams ; i++) 1842 { 1843 GET_PRS_HDR_NUM(hdrNum, p_PcdParams->p_PrsParams->additionalParams[i].hdr); 1844 if(hdrNum== ILLEGAL_HDR_NUM) 1845 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1846 if(hdrNum==NO_HDR_NUM) 1847 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Private headers may not use additional parameters")); 1848 1849 err = AdditionalPrsParams(p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i], &tmpReg); 1850 if(err) 1851 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1852 1853 tmpHxs[hdrNum] |= tmpReg; 1854 } 1855#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb 1856 { 1857 t_FmRevisionInfo revInfo; 1858 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 1859 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 1860 { 1861 /* link to sw parser code for L4 shells - only if no other code is applied. */ 1862 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_SCTP) 1863 if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1864 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | SCTP_SW_PATCH_START); 1865 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_DCCP) 1866 if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1867 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | DCCP_SW_PATCH_START); 1868 GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPSEC_AH) 1869 if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) 1870 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | IPSEC_SW_PATCH_START); 1871 } 1872 } 1873#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */ 1874 1875 for(i=0 ; i<FM_PCD_PRS_NUM_OF_HDRS ; i++) 1876 { 1877 /* For all header set LCV as taken from netEnv*/ 1878 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv, FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i)); 1879 /* set HXS register according to default+Additional params+protocol options */ 1880 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach, tmpHxs[i]); 1881 } 1882 1883 /* set tpid. */ 1884 tmpReg = PRS_TPID_DFLT; 1885 if(p_PcdParams->p_PrsParams->setVlanTpid1) 1886 { 1887 tmpReg &= PRS_TPID2_MASK; 1888 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1 << PRS_PCTPID_SHIFT; 1889 } 1890 if(p_PcdParams->p_PrsParams->setVlanTpid2) 1891 { 1892 tmpReg &= PRS_TPID1_MASK; 1893 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2; 1894 } 1895 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg); 1896 1897 /* enable parser */ 1898 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0); 1899 1900 if(p_PcdParams->p_PrsParams->prsResultPrivateInfo) 1901 p_FmPort->privateInfo = p_PcdParams->p_PrsParams->prsResultPrivateInfo; 1902 1903 } /* end parser */ 1904 else 1905 p_FmPort->privateInfo = 0; 1906 1907 WRITE_UINT32(*p_BmiPrsStartOffset, GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset); 1908 1909 /* set initial parser result - used for all engines */ 1910 for (i=0;i<FM_PORT_PRS_RESULT_NUM_OF_WORDS;i++) 1911 { 1912 if (!i) 1913 WRITE_UINT32(*(p_BmiInitPrsResult), (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) 1914 | BMI_PRS_RESULT_HIGH)); 1915 else 1916 if (i< FM_PORT_PRS_RESULT_NUM_OF_WORDS/2) 1917 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH); 1918 else 1919 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW); 1920 } 1921 1922 return E_OK; 1923} 1924 1925static t_Error DeletePcd(t_Handle h_FmPort) 1926{ 1927 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 1928 t_Error err = E_OK; 1929 volatile uint32_t *p_BmiNia=NULL; 1930 1931 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 1932 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 1933 1934 if (p_FmPort->imEn) 1935 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); 1936 1937 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 1938 (p_FmPort->portType != e_FM_PORT_TYPE_RX) && 1939 (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 1940 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 1941 1942 if(!p_FmPort->pcdEngines) 1943 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port")); 1944 1945 /* get PCD registers pointers */ 1946 switch(p_FmPort->portType) 1947 { 1948 case(e_FM_PORT_TYPE_RX_10G): 1949 case(e_FM_PORT_TYPE_RX): 1950 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; 1951 break; 1952 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 1953 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; 1954 break; 1955 default: 1956 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 1957 } 1958 1959 if((GET_UINT32(*p_BmiNia) & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) 1960 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("port has to be detached previousely")); 1961 1962 /* "cut" PCD out of the port's flow - go to BMI */ 1963 /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */ 1964 1965 if(p_FmPort->pcdEngines | FM_PCD_PRS) 1966 { 1967 /* stop parser */ 1968 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); 1969 /* wait for parser to be in idle state */ 1970 while(GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) ; 1971 } 1972 1973 if(p_FmPort->pcdEngines & FM_PCD_KG) 1974 { 1975 err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, p_FmPort->clsPlanGrpId); 1976 if(err) 1977 RETURN_ERROR(MINOR, err, NO_MSG); 1978 p_FmPort->useClsPlan = FALSE; 1979 } 1980 1981 if(p_FmPort->pcdEngines & FM_PCD_CC) 1982 { 1983 /* unbind - we need to get the treeId too */ 1984 err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId); 1985 if(err) 1986 RETURN_ERROR(MINOR, err, NO_MSG); 1987 } 1988 1989 p_FmPort->pcdEngines = 0; 1990 1991 return E_OK; 1992} 1993 1994 1995/********************************************/ 1996/* Inter-module API */ 1997/********************************************/ 1998void FmPortSetMacsecLcv(t_Handle h_FmPort) 1999{ 2000 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2001 volatile uint32_t *p_BmiCfgReg = NULL; 2002 uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC; 2003 uint32_t lcv, walking1Mask = 0x80000000; 2004 uint8_t cnt = 0; 2005 2006 SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); 2007 SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 2008 2009 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2010 { 2011 REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Rx ports only")); 2012 return; 2013 } 2014 2015 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; 2016 /* get LCV for MACSEC */ 2017 if ((p_FmPort->h_FmPcd) && ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))!= 0)) 2018 { 2019 while(!(lcv & walking1Mask)) 2020 { 2021 cnt++; 2022 walking1Mask >>= 1; 2023 } 2024 2025 macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT; 2026 } 2027 2028 WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn); 2029} 2030 2031void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci) 2032{ 2033 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2034 volatile uint32_t *p_BmiCfgReg = NULL; 2035 uint32_t tmpReg; 2036 2037 SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); 2038 SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 2039 2040 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 2041 { 2042 REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only")); 2043 return; 2044 } 2045 2046 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfca; 2047 tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK; 2048 tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED; 2049 tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT) & BMI_CMD_ATTR_MACCMD_SC_MASK); 2050 2051 WRITE_UINT32(*p_BmiCfgReg, tmpReg); 2052} 2053 2054uint8_t FmPortGetNetEnvId(t_Handle h_FmPort) 2055{ 2056 return ((t_FmPort*)h_FmPort)->netEnvId; 2057} 2058 2059uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort) 2060{ 2061 return ((t_FmPort*)h_FmPort)->hardwarePortId; 2062} 2063 2064uint32_t FmPortGetPcdEngines(t_Handle h_FmPort) 2065{ 2066 return ((t_FmPort*)h_FmPort)->pcdEngines; 2067} 2068 2069t_Error FmPortAttachPCD(t_Handle h_FmPort) 2070{ 2071 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2072 volatile uint32_t *p_BmiNia=NULL; 2073 2074/*TODO - to take care about the chnges that were made in the port because of the previously assigned tree. 2075pndn, pnen ... maybe were changed because of the Tree requirement*/ 2076 2077 /* get PCD registers pointers */ 2078 switch(p_FmPort->portType) 2079 { 2080 case(e_FM_PORT_TYPE_RX_10G): 2081 case(e_FM_PORT_TYPE_RX): 2082 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; 2083 break; 2084 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2085 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; 2086 break; 2087 default: 2088 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 2089 } 2090 2091 if(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) 2092 if(FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1)!= E_OK) 2093 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 2094 2095 /* check that current NIA is BMI to BMI */ 2096 if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) 2097 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state.")); 2098 2099 WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia); 2100 2101 if(p_FmPort->requiredAction & UPDATE_NIA_PNEN) 2102 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, p_FmPort->savedQmiPnen); 2103 2104 if(p_FmPort->requiredAction & UPDATE_NIA_PNDN) 2105 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, p_FmPort->savedNonRxQmiRegsPndn); 2106 2107 2108 return E_OK; 2109} 2110 2111t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_CcParams) 2112{ 2113 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2114 int tmpInt; 2115 volatile uint32_t *p_BmiPrsStartOffset = NULL; 2116 2117 /* this function called from Cc for pass and receive parameters port params between CC and PORT*/ 2118 2119 if((p_CcParams->getCcParams.type & OFFSET_OF_PR) && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE)) 2120 { 2121 p_CcParams->getCcParams.prOffset = (uint8_t)p_FmPort->bufferOffsets.prsResultOffset; 2122 p_CcParams->getCcParams.type &= ~OFFSET_OF_PR; 2123 } 2124 if(p_CcParams->getCcParams.type & HW_PORT_ID) 2125 { 2126 p_CcParams->getCcParams.hardwarePortId = (uint8_t)p_FmPort->hardwarePortId; 2127 p_CcParams->getCcParams.type &= ~HW_PORT_ID; 2128 } 2129 if((p_CcParams->getCcParams.type & OFFSET_OF_DATA) && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE)) 2130 { 2131 p_CcParams->getCcParams.dataOffset = (uint16_t)p_FmPort->bufferOffsets.dataOffset; 2132 p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA; 2133 } 2134 if(p_CcParams->getCcParams.type & NUM_OF_TASKS) 2135 { 2136 p_CcParams->getCcParams.numOfTasks = p_FmPort->numOfTasks; 2137 p_CcParams->getCcParams.type &= ~NUM_OF_TASKS; 2138 } 2139 if(p_CcParams->getCcParams.type & BUFFER_POOL_ID_FOR_MANIP) 2140 { 2141 if(p_CcParams->getCcParams.poolIndex < p_FmPort->extBufPools.numOfPoolsUsed) 2142 { 2143 p_CcParams->getCcParams.poolIdForManip = p_FmPort->extBufPools.extBufPool[p_CcParams->getCcParams.poolIndex].id; 2144 p_CcParams->getCcParams.type &= ~BUFFER_POOL_ID_FOR_MANIP; 2145 } 2146 } 2147 2148 if((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)) 2149 { 2150 p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; 2151 } 2152 2153 if((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN)) 2154 { 2155 p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia; 2156 p_FmPort->requiredAction |= UPDATE_NIA_PNEN; 2157 } 2158 else if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) 2159 { 2160 if(p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia) 2161 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("pnen was defined previously different")); 2162 } 2163 2164 if((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN)) 2165 { 2166 p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia; 2167 p_FmPort->requiredAction |= UPDATE_NIA_PNDN; 2168 } 2169 else if(p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) 2170 { 2171 if(p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia) 2172 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("pndn was defined previously different")); 2173 } 2174 2175 2176 if((p_CcParams->setCcParams.type & UPDATE_PSO) && !(p_FmPort->requiredAction & UPDATE_PSO)) 2177 { 2178 /* get PCD registers pointers */ 2179 switch(p_FmPort->portType) 2180 { 2181 case(e_FM_PORT_TYPE_RX_10G): 2182 case(e_FM_PORT_TYPE_RX): 2183 p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; 2184 break; 2185 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2186 p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; 2187 break; 2188 default: 2189 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2190 } 2191 /* set start parsing offset */ 2192 tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)+ p_CcParams->setCcParams.psoSize; 2193 if(tmpInt>0) 2194 WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt); 2195 2196 p_FmPort->requiredAction |= UPDATE_PSO; 2197 p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize; 2198 2199 } 2200 else if (p_CcParams->setCcParams.type & UPDATE_PSO) 2201 { 2202 if(p_FmPort->savedPrsStartOffset != p_CcParams->setCcParams.psoSize) 2203 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser start offset was defoned previousley different")); 2204 } 2205 return E_OK; 2206} 2207/********************************** End of inter-module routines ********************************/ 2208 2209/****************************************/ 2210/* API Init unit functions */ 2211/****************************************/ 2212t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) 2213{ 2214 t_FmPort *p_FmPort; 2215 uintptr_t baseAddr = p_FmPortParams->baseAddr; 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(sizeof(t_FmPortDriverParam)); 2228 if (!p_FmPort->p_FmPortDriverParam) 2229 { 2230 XX_Free(p_FmPort); 2231 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters")); 2232 return NULL; 2233 } 2234 memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam)); 2235 2236 /* Initialize FM port parameters which will be kept by the driver */ 2237 p_FmPort->portType = p_FmPortParams->portType; 2238 p_FmPort->portId = p_FmPortParams->portId; 2239 p_FmPort->pcdEngines = FM_PCD_NONE; 2240 p_FmPort->f_Exception = p_FmPortParams->f_Exception; 2241 p_FmPort->h_App = p_FmPortParams->h_App; 2242 p_FmPort->h_Fm = p_FmPortParams->h_Fm; 2243 2244 /* calculate global portId number */ 2245 SW_PORT_ID_TO_HW_PORT_ID(p_FmPort->hardwarePortId, p_FmPort->portType, p_FmPortParams->portId); 2246 2247 /* Initialize FM port parameters for initialization phase only */ 2248 p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr; 2249 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize = DEFAULT_PORT_bufferPrefixContent_privDataSize; 2250 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult= DEFAULT_PORT_bufferPrefixContent_passPrsResult; 2251 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp= DEFAULT_PORT_bufferPrefixContent_passTimeStamp; 2252 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo 2253 = DEFAULT_PORT_bufferPrefixContent_passTimeStamp; 2254#ifdef DEBUG 2255 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo= DEFAULT_PORT_bufferPrefixContent_debugInfo; 2256#endif /* DEBUG */ 2257 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = DEFAULT_PORT_bufferPrefixContent_dataAlign; 2258 p_FmPort->p_FmPortDriverParam->dmaSwapData = DEFAULT_PORT_dmaSwapData; 2259 p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = DEFAULT_PORT_dmaIntContextCacheAttr; 2260 p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = DEFAULT_PORT_dmaHeaderCacheAttr; 2261 p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = DEFAULT_PORT_dmaScatterGatherCacheAttr; 2262 p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize; 2263 p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase; 2264 2265 /* resource distribution. */ 2266 p_FmPort->fifoBufs.num = DEFAULT_PORT_sizeOfFifo(p_FmPort->portType); 2267 p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraSizeOfFifo(p_FmPort->portType); 2268 p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType); 2269 p_FmPort->openDmas.extra = DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType); 2270 p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType); 2271 p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType); 2272 p_FmPort->numOfTasks = (uint8_t)p_FmPort->tasks.num; 2273#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 2274 { 2275 t_FmRevisionInfo revInfo; 2276 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2277 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 2278 { 2279 p_FmPort->fifoBufs.extra = 0; 2280 p_FmPort->openDmas.extra = 0; 2281 p_FmPort->tasks.extra = 0; 2282 } 2283 } 2284#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ 2285 2286 p_FmPort->p_FmPortDriverParam->color = DEFAULT_PORT_color; 2287#ifdef FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 2288 { 2289 t_FmRevisionInfo revInfo; 2290 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2291 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && 2292 (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 2293 p_FmPort->p_FmPortDriverParam->color = e_FM_PORT_COLOR_OVERRIDE; 2294 } 2295#endif /* FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 */ 2296 2297 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 2298 p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReqForHc; 2299 else 2300 p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReq; 2301 2302#ifdef FM_PORT_SYNC_ERRATA_FMAN6 2303 { 2304 t_FmRevisionInfo revInfo; 2305 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2306 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && 2307 (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 2308 p_FmPort->p_FmPortDriverParam->syncReq = FALSE; 2309 } 2310#endif /* FM_PORT_SYNC_ERRATA_FMAN6 */ 2311 2312 /* Port type specific initialization: */ 2313 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX) && 2314 (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) 2315 p_FmPort->p_FmPortDriverParam->frmDiscardOverride = DEFAULT_PORT_frmDiscardOverride; 2316 2317 switch(p_FmPort->portType) 2318 { 2319 case(e_FM_PORT_TYPE_RX): 2320 case(e_FM_PORT_TYPE_RX_10G): 2321 /* Initialize FM port parameters for initialization phase only */ 2322 p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = DEFAULT_PORT_cutBytesFromEnd; 2323 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE; 2324 p_FmPort->p_FmPortDriverParam->frmDiscardOverride = DEFAULT_PORT_frmDiscardOverride; 2325 p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = DEFAULT_PORT_rxFifoPriElevationLevel; 2326 p_FmPort->p_FmPortDriverParam->rxFifoThreshold = DEFAULT_PORT_rxFifoThreshold; 2327 p_FmPort->p_FmPortDriverParam->bufMargins.endMargins = DEFAULT_PORT_BufMargins_endMargins; 2328 p_FmPort->p_FmPortDriverParam->errorsToDiscard = DEFAULT_PORT_errorsToDiscard; 2329 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_PORT_cheksumLastBytesIgnore; 2330 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = DEFAULT_PORT_forwardIntContextReuse; 2331 break; 2332 2333 case(e_FM_PORT_TYPE_TX): 2334 p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_1G; 2335 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE; 2336 case(e_FM_PORT_TYPE_TX_10G): 2337 if(p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) 2338 p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_10G; 2339 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_PORT_cheksumLastBytesIgnore; 2340 p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = DEFAULT_PORT_txFifoMinFillLevel; 2341 p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = DEFAULT_PORT_txFifoLowComfLevel; 2342 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2343 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 2344 p_FmPort->p_FmPortDriverParam->deqHighPriority = DEFAULT_PORT_deqHighPriority; 2345 p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; 2346#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT 2347 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = DEFAULT_PORT_deqPrefetchOption; 2348#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ 2349 p_FmPort->p_FmPortDriverParam->deqByteCnt = DEFAULT_PORT_deqByteCnt; 2350 2351 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2352 p_FmPort->p_FmPortDriverParam->errorsToDiscard = DEFAULT_PORT_errorsToDiscard; 2353 break; 2354 2355 default: 2356 XX_Free(p_FmPort->p_FmPortDriverParam); 2357 XX_Free(p_FmPort); 2358 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2359 return NULL; 2360 } 2361#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT 2362 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 2363 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = DEFAULT_PORT_deqPrefetchOption_HC; 2364#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ 2365 2366 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || 2367 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 2368 p_FmPort->txFifoDeqPipelineDepth = OH_PIPELINE_DEPTH; 2369 2370 p_FmPort->imEn = p_FmPortParams->independentModeEnable; 2371 2372 if (p_FmPort->imEn) 2373 { 2374 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) || 2375 (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) 2376 p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_IM; 2377 FmPortConfigIM(p_FmPort, p_FmPortParams); 2378 } 2379 else 2380 { 2381 switch(p_FmPort->portType) 2382 { 2383 case(e_FM_PORT_TYPE_RX): 2384 case(e_FM_PORT_TYPE_RX_10G): 2385 /* Initialize FM port parameters for initialization phase only */ 2386 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, 2387 &p_FmPortParams->specificParams.rxParams.extBufPools, 2388 sizeof(t_FmPortExtPools)); 2389 p_FmPort->p_FmPortDriverParam->errFqid = p_FmPortParams->specificParams.rxParams.errFqid; 2390 p_FmPort->p_FmPortDriverParam->dfltFqid = p_FmPortParams->specificParams.rxParams.dfltFqid; 2391 p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.rxParams.liodnOffset; 2392 break; 2393 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2394#ifdef FM_OP_PARTITION_ERRATA_FMANx8 2395 { 2396 t_FmRevisionInfo revInfo; 2397 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2398 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 2399 p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.nonRxParams.opLiodnOffset; 2400 } 2401#endif /* FM_OP_PARTITION_ERRATA_FMANx8 */ 2402 case(e_FM_PORT_TYPE_TX): 2403 case(e_FM_PORT_TYPE_TX_10G): 2404 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 2405 p_FmPort->p_FmPortDriverParam->errFqid = p_FmPortParams->specificParams.nonRxParams.errFqid; 2406 p_FmPort->p_FmPortDriverParam->deqSubPortal = 2407 (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel & QMI_DEQ_CFG_SUBPORTAL_MASK); 2408 p_FmPort->p_FmPortDriverParam->dfltFqid = p_FmPortParams->specificParams.nonRxParams.dfltFqid; 2409 break; 2410 default: 2411 XX_Free(p_FmPort->p_FmPortDriverParam); 2412 XX_Free(p_FmPort); 2413 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 2414 return NULL; 2415 } 2416 } 2417 2418 memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE); 2419 if(Sprint (p_FmPort->name, "FM-%d-port-%s-%d", 2420 FmGetId(p_FmPort->h_Fm), 2421 ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING || 2422 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? 2423 "OH" : (p_FmPort->portType == e_FM_PORT_TYPE_RX ? 2424 "1g-RX" : (p_FmPort->portType == e_FM_PORT_TYPE_TX ? 2425 "1g-TX" : (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G ? 2426 "10g-RX" : "10g-TX")))), 2427 p_FmPort->portId) == 0) 2428 { 2429 XX_Free(p_FmPort->p_FmPortDriverParam); 2430 XX_Free(p_FmPort); 2431 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 2432 return NULL; 2433 } 2434 2435 p_FmPort->h_Spinlock = XX_InitSpinlock(); 2436 if (!p_FmPort->h_Spinlock) 2437 { 2438 XX_Free(p_FmPort->p_FmPortDriverParam); 2439 XX_Free(p_FmPort); 2440 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); 2441 return NULL; 2442 } 2443 2444 return p_FmPort; 2445} 2446 2447/**************************************************************************//** 2448 @Function FM_PORT_Init 2449 2450 @Description Initializes the FM module 2451 2452 @Param[in] h_FmPort - FM module descriptor 2453 2454 @Return E_OK on success; Error code otherwise. 2455*//***************************************************************************/ 2456t_Error FM_PORT_Init(t_Handle h_FmPort) 2457{ 2458 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2459 t_FmPortDriverParam *p_Params; 2460 t_Error err = E_OK; 2461 t_FmInterModulePortInitParams fmParams; 2462 uint32_t minFifoSizeRequired = 0; 2463 2464 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 2465 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2466 2467 if ((err = BuildBufferStructure(p_FmPort)) != E_OK) 2468 RETURN_ERROR(MINOR, err, NO_MSG); 2469 2470 CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters); 2471 2472 p_Params = p_FmPort->p_FmPortDriverParam; 2473 2474 /* set memory map pointers */ 2475 p_FmPort->p_FmPortQmiRegs = (t_FmPortQmiRegs *)UINT_TO_PTR(p_Params->baseAddr + QMI_PORT_REGS_OFFSET); 2476 p_FmPort->p_FmPortBmiRegs = (u_FmPortBmiRegs *)UINT_TO_PTR(p_Params->baseAddr + BMI_PORT_REGS_OFFSET); 2477 p_FmPort->p_FmPortPrsRegs = (t_FmPortPrsRegs *)UINT_TO_PTR(p_Params->baseAddr + PRS_PORT_REGS_OFFSET); 2478 2479 /* For O/H ports, check fifo size and update if necessary */ 2480 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 2481 { 2482 minFifoSizeRequired = (uint32_t)((p_FmPort->txFifoDeqPipelineDepth+4)*BMI_FIFO_UNITS); 2483 if (p_FmPort->fifoBufs.num < minFifoSizeRequired) 2484 { 2485 p_FmPort->fifoBufs.num = minFifoSizeRequired; 2486 DBG(WARNING, ("FIFO size enlarged to %d due to txFifoDeqPipelineDepth size", minFifoSizeRequired)); 2487 } 2488 } 2489 2490 /* For Rx Ports, call the external Buffer routine which also checks fifo 2491 size and updates it if necessary */ 2492 if(((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 2493 && !p_FmPort->imEn) 2494 { 2495 /* define external buffer pools and pool depletion*/ 2496 err = SetExtBufferPools(p_FmPort); 2497 if(err) 2498 RETURN_ERROR(MAJOR, err, NO_MSG); 2499 } 2500 2501 /************************************************************/ 2502 /* Call FM module routine for communicating parameters */ 2503 /************************************************************/ 2504 memset(&fmParams, 0, sizeof(fmParams)); 2505 fmParams.hardwarePortId = p_FmPort->hardwarePortId; 2506 fmParams.portType = (e_FmPortType)p_FmPort->portType; 2507 fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; 2508 fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra; 2509 fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num; 2510 fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra; 2511 fmParams.sizeOfFifo = p_FmPort->fifoBufs.num; 2512 fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra; 2513 fmParams.independentMode = p_FmPort->imEn; 2514 fmParams.liodnOffset = p_Params->liodnOffset; 2515 fmParams.liodnBase = p_Params->liodnBase; 2516 2517 switch(p_FmPort->portType) 2518 { 2519 case(e_FM_PORT_TYPE_RX_10G): 2520 case(e_FM_PORT_TYPE_RX): 2521 break; 2522 case(e_FM_PORT_TYPE_TX_10G): 2523 case(e_FM_PORT_TYPE_TX): 2524 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2525 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 2526 fmParams.deqPipelineDepth = p_FmPort->txFifoDeqPipelineDepth; 2527 break; 2528 default: 2529 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 2530 } 2531 2532 err = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams); 2533 if(err) 2534 RETURN_ERROR(MAJOR, err, NO_MSG); 2535 2536 p_FmPort->tasks.num = fmParams.numOfTasks; 2537 p_FmPort->tasks.extra = fmParams.numOfExtraTasks; 2538 p_FmPort->openDmas.num = fmParams.numOfOpenDmas; 2539 p_FmPort->openDmas.extra = fmParams.numOfExtraOpenDmas; 2540 p_FmPort->fifoBufs.num = fmParams.sizeOfFifo; 2541 p_FmPort->fifoBufs.extra = fmParams.extraSizeOfFifo; 2542 2543 /* get params for use in init */ 2544 p_Params->fmMuramPhysBaseAddr = 2545 (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low) | 2546 ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32)); 2547 2548 /**********************/ 2549 /* Init BMI Registers */ 2550 /**********************/ 2551 switch(p_FmPort->portType) 2552 { 2553 case(e_FM_PORT_TYPE_RX_10G): 2554 case(e_FM_PORT_TYPE_RX): 2555 err = BmiRxPortInit(p_FmPort); 2556 if(err) 2557 RETURN_ERROR(MAJOR, err, NO_MSG); 2558 break; 2559 case(e_FM_PORT_TYPE_TX_10G): 2560 case(e_FM_PORT_TYPE_TX): 2561 err = BmiTxPortInit(p_FmPort); 2562 if(err) 2563 RETURN_ERROR(MAJOR, err, NO_MSG); 2564 break; 2565 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 2566 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 2567 err = BmiOhPortInit(p_FmPort); 2568 if(err) 2569 RETURN_ERROR(MAJOR, err, NO_MSG); 2570 break; 2571 default: 2572 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 2573 } 2574 2575 /**********************/ 2576 /* Init QMI Registers */ 2577 /**********************/ 2578 if (!p_FmPort->imEn && ((err = QmiInit(p_FmPort)) != E_OK)) 2579 RETURN_ERROR(MAJOR, err, NO_MSG); 2580 2581 if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK)) 2582 RETURN_ERROR(MAJOR, err, NO_MSG); 2583 2584 FmPortDriverParamFree(p_FmPort); 2585 2586 return E_OK; 2587} 2588 2589/**************************************************************************//** 2590 @Function FM_PORT_Free 2591 2592 @Description Frees all resources that were assigned to FM module. 2593 2594 Calling this routine invalidates the descriptor. 2595 2596 @Param[in] h_FmPort - FM module descriptor 2597 2598 @Return E_OK on success; Error code otherwise. 2599*//***************************************************************************/ 2600t_Error FM_PORT_Free(t_Handle h_FmPort) 2601{ 2602 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2603 t_FmInterModulePortFreeParams fmParams; 2604 2605 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2606 2607 if(p_FmPort->pcdEngines) 2608 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first.")); 2609 2610 if (p_FmPort->enabled) 2611 { 2612 if (FM_PORT_Disable(p_FmPort) != E_OK) 2613 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED")); 2614 } 2615 2616 FmPortDriverParamFree(p_FmPort); 2617 2618 if (p_FmPort->imEn) 2619 FmPortImFree(p_FmPort); 2620 2621 fmParams.hardwarePortId = p_FmPort->hardwarePortId; 2622 fmParams.portType = (e_FmPortType)p_FmPort->portType; 2623#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT 2624 fmParams.deqPipelineDepth = p_FmPort->txFifoDeqPipelineDepth; 2625#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ 2626 2627 FmFreePortParams(p_FmPort->h_Fm, &fmParams); 2628 2629 if (p_FmPort->h_Spinlock) 2630 XX_FreeSpinlock(p_FmPort->h_Spinlock); 2631 2632 XX_Free(p_FmPort); 2633 2634 return E_OK; 2635} 2636 2637 2638/*************************************************/ 2639/* API Advanced Init unit functions */ 2640/*************************************************/ 2641 2642t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri) 2643{ 2644 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2645 2646 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2647 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2648 if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2649 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports")); 2650 2651 p_FmPort->p_FmPortDriverParam->deqHighPriority = highPri; 2652 2653 return E_OK; 2654} 2655 2656t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType) 2657{ 2658 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2659 2660 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2661 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2662 if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2663 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports")); 2664 2665 p_FmPort->p_FmPortDriverParam->deqType = deqType; 2666 2667 return E_OK; 2668} 2669 2670#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT 2671t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption) 2672{ 2673 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2674 2675 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2676 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2677 if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2678 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports")); 2679 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = deqPrefetchOption; 2680 return E_OK; 2681} 2682#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */ 2683 2684t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmPortBackupBmPools *p_BackupBmPools) 2685{ 2686 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2687#ifdef FM_NO_BACKUP_POOLS 2688 t_FmRevisionInfo revInfo; 2689#endif /* FM_NO_BACKUP_POOLS */ 2690 2691 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2692 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2693 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2694 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 2695 2696#ifdef FM_NO_BACKUP_POOLS 2697 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2698 if (revInfo.majorRev != 4) 2699 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigBackupPools")); 2700#endif /* FM_NO_BACKUP_POOLS */ 2701 2702 p_FmPort->p_FmPortDriverParam->p_BackupBmPools = (t_FmPortBackupBmPools *)XX_Malloc(sizeof(t_FmPortBackupBmPools)); 2703 if(!p_FmPort->p_FmPortDriverParam->p_BackupBmPools) 2704 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed")); 2705 memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmPortBackupBmPools)); 2706 2707 return E_OK; 2708} 2709 2710t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt) 2711{ 2712 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2713 2714 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2715 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2716 if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) 2717 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports")); 2718 2719 p_FmPort->p_FmPortDriverParam->deqByteCnt = deqByteCnt; 2720 2721 return E_OK; 2722} 2723 2724t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort, t_FmPortBufferPrefixContent *p_FmPortBufferPrefixContent) 2725{ 2726 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2727 2728 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2729 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2730 2731 memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent, p_FmPortBufferPrefixContent, sizeof(t_FmPortBufferPrefixContent)); 2732 /* if dataAlign was not initialized by user, we return to driver's deafult */ 2733 if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign) 2734 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = DEFAULT_PORT_bufferPrefixContent_dataAlign; 2735 2736 return E_OK; 2737} 2738 2739t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore) 2740{ 2741 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2742 2743 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2744 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2745 if((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 2746 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx & Tx ports only")); 2747 2748 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = cheksumLastBytesIgnore; 2749 2750 return E_OK; 2751} 2752 2753t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd) 2754{ 2755 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2756 2757 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2758 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2759 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2760 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 2761 2762 p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = cutBytesFromEnd; 2763 2764 return E_OK; 2765} 2766 2767t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmPortBufPoolDepletion *p_BufPoolDepletion) 2768{ 2769 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2770 2771 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2772 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2773 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2774 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 2775 2776 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; 2777 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmPortBufPoolDepletion)); 2778 2779 return E_OK; 2780} 2781 2782t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort, t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion) 2783{ 2784 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2785 2786 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2787 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2788 if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2789 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for OP ports only")); 2790 2791 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; 2792 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, &p_FmPortObservedBufPoolDepletion->poolDepletionParams, sizeof(t_FmPortBufPoolDepletion)); 2793 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, &p_FmPortObservedBufPoolDepletion->poolsParams, sizeof(t_FmPortExtPools)); 2794 2795 return E_OK; 2796} 2797 2798t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmPortExtPools *p_FmPortExtPools) 2799{ 2800 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2801 2802 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2803 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2804 if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 2805 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for OP ports only")); 2806 2807 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmPortExtPools, sizeof(t_FmPortExtPools)); 2808 2809 return E_OK; 2810} 2811 2812t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold) 2813{ 2814 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2815 2816 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2817 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2818 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2819 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 2820 2821 p_FmPort->p_FmPortDriverParam->rxFifoThreshold = fifoThreshold; 2822 2823 return E_OK; 2824} 2825 2826t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel) 2827{ 2828 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2829 2830 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2831 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2832 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 2833 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 2834 2835 p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = priElevationLevel; 2836 2837 return E_OK; 2838} 2839 2840t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel) 2841{ 2842 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2843 2844 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2845 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2846 if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 2847 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); 2848 2849 p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = minFillLevel; 2850 2851 return E_OK; 2852} 2853 2854t_Error FM_PORT_ConfigTxFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth) 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_TX_10G) && 2861 (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 2862 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); 2863 if (p_FmPort->imEn) 2864 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for IM ports!")); 2865 2866 p_FmPort->txFifoDeqPipelineDepth = deqPipelineDepth; 2867 2868 return E_OK; 2869} 2870 2871t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel) 2872{ 2873 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2874 2875 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2876 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2877 if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 2878 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); 2879 2880 p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = fifoLowComfLevel; 2881 2882 return E_OK; 2883} 2884 2885t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort) 2886{ 2887 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2888 2889 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2890 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2891 if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) 2892 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only")); 2893 2894 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE; 2895 2896 return E_OK; 2897} 2898 2899t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color) 2900{ 2901 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2902 2903 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2904 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2905#ifdef FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 2906 { 2907 t_FmRevisionInfo revInfo; 2908 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2909 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 2910 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigDfltColor!")); 2911 } 2912#endif /* FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 */ 2913 p_FmPort->p_FmPortDriverParam->color = color; 2914 2915 return E_OK; 2916} 2917 2918t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq) 2919{ 2920 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2921 2922 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2923 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2924#ifdef FM_PORT_SYNC_ERRATA_FMAN6 2925 { 2926 t_FmRevisionInfo revInfo; 2927 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 2928 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)) 2929 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("port-sync!")); 2930 } 2931#endif /* FM_PORT_SYNC_ERRATA_FMAN6 */ 2932 2933 p_FmPort->p_FmPortDriverParam->syncReq = syncReq; 2934 2935 return E_OK; 2936} 2937 2938 2939t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override) 2940{ 2941 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2942 2943 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2944 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2945 if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType == e_FM_PORT_TYPE_TX)) 2946 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Tx ports")); 2947 2948 p_FmPort->p_FmPortDriverParam->frmDiscardOverride = override; 2949 2950 return E_OK; 2951} 2952 2953t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs) 2954{ 2955 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2956 2957 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2958 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2959 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX) && 2960 (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 2961 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 2962 2963 p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs; 2964 2965 return E_OK; 2966} 2967 2968t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmPortDmaSwap swapData) 2969{ 2970 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2971 2972 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2973 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2974 2975 p_FmPort->p_FmPortDriverParam->dmaSwapData = swapData; 2976 2977 return E_OK; 2978} 2979 2980t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmPortDmaCache intContextCacheAttr) 2981{ 2982 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2983 2984 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2985 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2986 2987 p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = intContextCacheAttr; 2988 2989 return E_OK; 2990} 2991 2992t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmPortDmaCache headerCacheAttr) 2993{ 2994 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 2995 2996 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 2997 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 2998 2999 p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = headerCacheAttr; 3000 3001 return E_OK; 3002} 3003 3004t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmPortDmaCache scatterGatherCacheAttr) 3005{ 3006 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3007 3008 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3009 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3010 3011 p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = scatterGatherCacheAttr; 3012 3013 return E_OK; 3014} 3015 3016t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize) 3017{ 3018 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3019 3020 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3021 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3022 3023 if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) 3024 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for Tx ports")); 3025 3026 p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = optimize; 3027 3028 return E_OK; 3029} 3030 3031t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool forwardReuse) 3032{ 3033 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3034 3035 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3036 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3037 3038 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 3039 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 3040 3041 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse; 3042 3043 return E_OK; 3044} 3045 3046 3047/****************************************************/ 3048/* PCD Advaced config API */ 3049/****************************************************/ 3050 3051/****************************************************/ 3052/* API Run-time Control unit functions */ 3053/****************************************************/ 3054 3055t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas) 3056{ 3057 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3058 t_Error err; 3059 3060 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3061 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3062 3063#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 3064 { 3065 t_FmRevisionInfo revInfo; 3066 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 3067 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && 3068 (p_NumOfOpenDmas->extra)) 3069 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources")); 3070 } 3071#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ 3072 3073 if((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS)) 3074 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS)); 3075 if(p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS) 3076 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); 3077 err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId, (uint8_t)p_NumOfOpenDmas->num, (uint8_t)p_NumOfOpenDmas->extra, FALSE); 3078 if(err) 3079 RETURN_ERROR(MINOR, err, NO_MSG); 3080 3081 memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc)); 3082 3083 return E_OK; 3084} 3085 3086t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) 3087{ 3088 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3089 t_Error err; 3090 3091 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3092 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3093 3094 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) 3095 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for host command port where number is always 1")); 3096 3097#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 3098 { 3099 t_FmRevisionInfo revInfo; 3100 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 3101 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && 3102 (p_NumOfTasks->extra)) 3103 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources")); 3104 } 3105#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ 3106 3107 if((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS)) 3108 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS)); 3109 if(p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS) 3110 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); 3111 3112 err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId, (uint8_t)p_NumOfTasks->num, (uint8_t)p_NumOfTasks->extra, FALSE); 3113 if(err) 3114 RETURN_ERROR(MINOR, err, NO_MSG); 3115 3116 /* update driver's struct */ 3117 memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc)); 3118 return E_OK; 3119} 3120 3121t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo) 3122{ 3123 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3124 t_Error err; 3125 t_FmInterModulePortRxPoolsParams rxPoolsParams; 3126 uint32_t minFifoSizeRequired; 3127 3128 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3129 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3130 3131#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 3132 { 3133 t_FmRevisionInfo revInfo; 3134 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 3135 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) && 3136 (p_SizeOfFifo->extra)) 3137 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources")); 3138 } 3139#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */ 3140 if(!p_SizeOfFifo->num || (p_SizeOfFifo->num > BMI_MAX_FIFO_SIZE)) 3141 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-num has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE)); 3142 if(p_SizeOfFifo->num % BMI_FIFO_UNITS) 3143 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS)); 3144 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 3145 { 3146 /* extra FIFO size (allowed only to Rx ports) */ 3147 if(p_SizeOfFifo->extra % BMI_FIFO_UNITS) 3148 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS)); 3149 } 3150 else 3151 if(p_SizeOfFifo->extra) 3152 RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" No SizeOfFifo-extra for non Rx ports")); 3153 3154 /* For O/H ports, check fifo size and update if necessary */ 3155 if((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 3156 { 3157 minFifoSizeRequired = (uint32_t)((p_FmPort->txFifoDeqPipelineDepth+4)*BMI_FIFO_UNITS); 3158 if (p_FmPort->fifoBufs.num < minFifoSizeRequired) 3159 { 3160 p_FmPort->fifoBufs.num = minFifoSizeRequired; 3161 DBG(INFO, ("FIFO size enlarged to %d", minFifoSizeRequired)); 3162 } 3163 } 3164 memcpy(&rxPoolsParams, &p_FmPort->rxPoolsParams, sizeof(rxPoolsParams)); 3165 err = FmSetSizeOfFifo(p_FmPort->h_Fm, 3166 p_FmPort->hardwarePortId, 3167 p_FmPort->portType, 3168 p_FmPort->imEn, 3169 &p_SizeOfFifo->num, 3170 p_SizeOfFifo->extra, 3171 p_FmPort->txFifoDeqPipelineDepth, 3172 &rxPoolsParams, 3173 FALSE); 3174 if(err) 3175 RETURN_ERROR(MINOR, err, NO_MSG); 3176 3177 /* update driver's structure AFTER the FM routine, as it may change by the FM. */ 3178 memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc)); 3179 3180 return E_OK; 3181} 3182 3183uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort) 3184{ 3185 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3186 3187 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 3188 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); 3189 3190 return p_FmPort->bufferOffsets.dataOffset; 3191} 3192 3193uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data) 3194{ 3195 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3196 3197 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 3198 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); 3199 3200 if(p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE) 3201 return NULL; 3202 3203 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset); 3204} 3205 3206#ifdef DEBUG 3207uint8_t * FM_PORT_GetBufferDebugInfo(t_Handle h_FmPort, char *p_Data) 3208{ 3209 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3210 3211 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 3212 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); 3213 3214 if(p_FmPort->bufferOffsets.debugOffset == ILLEGAL_BASE) 3215 return NULL; 3216 3217 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.debugOffset); 3218} 3219#endif /* DEBUG */ 3220 3221t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data) 3222{ 3223 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3224 3225 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); 3226 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, NULL); 3227 3228 if(p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE) 3229 return NULL; 3230 3231 return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset); 3232} 3233 3234uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data) 3235{ 3236 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3237 3238 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); 3239 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, NULL); 3240 3241 if(p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE) 3242 return NULL; 3243 3244 return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset); 3245} 3246 3247uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data) 3248{ 3249 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3250 3251 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 3252 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0); 3253 3254 if(p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE) 3255 return NULL; 3256 3257 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset); 3258} 3259 3260t_Error FM_PORT_Disable(t_Handle h_FmPort) 3261{ 3262 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3263 volatile uint32_t *p_BmiCfgReg = NULL; 3264 volatile uint32_t *p_BmiStatusReg = NULL; 3265 bool rxPort = FALSE; 3266 int tries; 3267 3268 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3269 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3270 3271 switch(p_FmPort->portType) 3272 { 3273 case(e_FM_PORT_TYPE_RX_10G): 3274 case(e_FM_PORT_TYPE_RX): 3275 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; 3276 p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rst; 3277 rxPort = TRUE; 3278 break; 3279 case(e_FM_PORT_TYPE_TX_10G): 3280 case(e_FM_PORT_TYPE_TX): 3281 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg; 3282 p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tst; 3283 break; 3284 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3285 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3286 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg; 3287 p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ost; 3288 break; 3289 default: 3290 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3291 } 3292 /* check if port is already disabled */ 3293 if(!(GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN)) 3294 { 3295 if (!rxPort && !p_FmPort->imEn) 3296 { 3297 if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN)) 3298 /* port is disabled */ 3299 return E_OK; 3300 else 3301 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Inconsistency: Port's QMI is enabled but BMI disabled")); 3302 } 3303 /* port is disabled */ 3304 return E_OK; 3305 } 3306 3307 /* Disable QMI */ 3308 if (!rxPort && !p_FmPort->imEn) 3309 { 3310 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, 3311 GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & ~QMI_PORT_CFG_EN); 3312 /* wait for QMI to finish Handling dequeue tnums */ 3313 tries=1000; 3314 while ((GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pns) & QMI_PORT_STATUS_DEQ_FD_BSY) && 3315 --tries) 3316 XX_UDelay(1); 3317 if (!tries) 3318 RETURN_ERROR(MINOR, E_BUSY, ("%s: can't disable!", p_FmPort->name)); 3319 } 3320 3321 /* Disable BMI */ 3322 WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) & ~BMI_PORT_CFG_EN); 3323 3324 if (p_FmPort->imEn) 3325 FmPortImDisable(p_FmPort); 3326 3327 tries=5000; 3328 while ((GET_UINT32(*p_BmiStatusReg) & BMI_PORT_STATUS_BSY) && 3329 --tries) 3330 XX_UDelay(1); 3331 3332 if (!tries) 3333 RETURN_ERROR(MINOR, E_BUSY, ("%s: can't disable!", p_FmPort->name)); 3334 3335 p_FmPort->enabled = 0; 3336 3337 return E_OK; 3338} 3339 3340t_Error FM_PORT_Enable(t_Handle h_FmPort) 3341{ 3342 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3343 volatile uint32_t *p_BmiCfgReg = NULL; 3344 bool rxPort = FALSE; 3345 3346 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3347 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3348 3349 switch(p_FmPort->portType) 3350 { 3351 case(e_FM_PORT_TYPE_RX_10G): 3352 case(e_FM_PORT_TYPE_RX): 3353 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg; 3354 rxPort = TRUE; 3355 break; 3356 case(e_FM_PORT_TYPE_TX_10G): 3357 case(e_FM_PORT_TYPE_TX): 3358 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg; 3359 break; 3360 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3361 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3362 p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg; 3363 break; 3364 default: 3365 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3366 } 3367 3368 /* check if port is already enabled */ 3369 if(GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN) 3370 { 3371 if (!rxPort && !p_FmPort->imEn) 3372 { 3373 if(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN) 3374 /* port is enabled */ 3375 return E_OK; 3376 else 3377 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Inconsistency: Port's BMI is enabled but QMI disabled")); 3378 } 3379 /* port is enabled */ 3380 return E_OK; 3381 } 3382 3383 if (p_FmPort->imEn) 3384 FmPortImEnable(p_FmPort); 3385 3386 /* Enable QMI */ 3387 if (!rxPort && !p_FmPort->imEn) 3388 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, 3389 GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) | QMI_PORT_CFG_EN); 3390 3391 /* Enable BMI */ 3392 WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | BMI_PORT_CFG_EN); 3393 3394 p_FmPort->enabled = 1; 3395 3396 return E_OK; 3397} 3398 3399t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit) 3400{ 3401 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3402 uint32_t tmpRateLimit, tmpRateLimitScale; 3403 volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg; 3404 uint8_t factor, countUnitBit; 3405 uint16_t baseGran; 3406 3407 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3408 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3409 3410 if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || 3411 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 3412 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx and Offline parsing ports only")); 3413 3414 switch(p_FmPort->portType) 3415 { 3416 case(e_FM_PORT_TYPE_TX_10G): 3417 case(e_FM_PORT_TYPE_TX): 3418 p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt; 3419 p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts; 3420 baseGran = 16000; 3421 break; 3422 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3423 p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt; 3424 p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts; 3425 baseGran = 10000; 3426 break; 3427 default: 3428 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3429 } 3430 3431 countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */ 3432 /* normally, we use 1 usec as the reference count */ 3433 factor = 1; 3434 /* if ratelimit is too small for a 1usec factor, multiply the factor */ 3435 while (p_RateLimit->rateLimit < baseGran/factor) 3436 { 3437 if (countUnitBit==31) 3438 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small")); 3439 3440 countUnitBit++; 3441 factor <<= 1; 3442 } 3443 /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/ 3444 if (p_RateLimit->rateLimit > ((uint32_t)baseGran * (1<<10) * (uint32_t)factor)) 3445 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large")); 3446 3447 tmpRateLimit = (uint32_t)(p_RateLimit->rateLimit*factor/baseGran - 1); 3448 3449 if(!p_RateLimit->maxBurstSize || (p_RateLimit->maxBurstSize > MAX_BURST_SIZE)) 3450 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxBurstSize must be between 1K and %dk", MAX_BURST_SIZE)); 3451 3452 tmpRateLimitScale = ((31 - (uint32_t)countUnitBit) << BMI_COUNT_RATE_UNIT_SHIFT) | BMI_RATE_LIMIT_EN; 3453 3454 if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) 3455 tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT; 3456 else 3457 { 3458#ifndef FM_NO_ADVANCED_RATE_LIMITER 3459 t_FmRevisionInfo revInfo; 3460 3461 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 3462 if (revInfo.majorRev == 4) 3463 { 3464 switch(p_RateLimit->rateLimitDivider) 3465 { 3466 case(e_FM_PORT_DUAL_RATE_LIMITER_NONE): 3467 break; 3468 case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2): 3469 tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_2; 3470 break; 3471 case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4): 3472 tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_4; 3473 break; 3474 case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8): 3475 tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_8; 3476 break; 3477 default: 3478 break; 3479 } 3480 tmpRateLimit |= BMI_RATE_LIMIT_BURST_SIZE_GRAN; 3481 } 3482 else 3483#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */ 3484 { 3485 if(p_RateLimit->rateLimitDivider != e_FM_PORT_DUAL_RATE_LIMITER_NONE) 3486 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigDualRateLimitScaleDown")); 3487 3488 if(p_RateLimit->maxBurstSize % 1000) 3489 { 3490 p_RateLimit->maxBurstSize = (uint16_t)((p_RateLimit->maxBurstSize/1000)+1); 3491 DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000)); 3492 } 3493 else 3494 p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize/1000); 3495 } 3496 tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT; 3497 3498 } 3499 WRITE_UINT32(*p_RateLimitScaleReg, tmpRateLimitScale); 3500 WRITE_UINT32(*p_RateLimitReg, tmpRateLimit); 3501 3502 return E_OK; 3503} 3504 3505t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort) 3506{ 3507 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3508 volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg; 3509 3510 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3511 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); 3512 3513 if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || 3514 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 3515 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx and Offline parsing ports only")); 3516 3517 switch(p_FmPort->portType) 3518 { 3519 case(e_FM_PORT_TYPE_TX_10G): 3520 case(e_FM_PORT_TYPE_TX): 3521 p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt; 3522 p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts; 3523 break; 3524 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3525 p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt; 3526 p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts; 3527 break; 3528 default: 3529 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3530 } 3531 3532 WRITE_UINT32(*p_RateLimitScaleReg, 0); 3533 WRITE_UINT32(*p_RateLimitReg, 0); 3534 3535 return E_OK; 3536} 3537 3538 3539t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable) 3540{ 3541 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3542 uint32_t tmpReg; 3543 3544 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3545 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3546 3547 tmpReg = GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc); 3548 if(enable) 3549 tmpReg |= QMI_PORT_CFG_EN_COUNTERS ; 3550 else 3551 tmpReg &= ~QMI_PORT_CFG_EN_COUNTERS; 3552 3553 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, tmpReg); 3554 3555 return E_OK; 3556} 3557 3558t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable) 3559{ 3560 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3561 volatile uint32_t *p_BmiPcReg = NULL; 3562 3563 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3564 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3565 3566 switch(p_FmPort->portType) 3567 { 3568 case(e_FM_PORT_TYPE_RX_10G): 3569 case(e_FM_PORT_TYPE_RX): 3570 p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpc; 3571 break; 3572 case(e_FM_PORT_TYPE_TX_10G): 3573 case(e_FM_PORT_TYPE_TX): 3574 p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpc; 3575 break; 3576 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3577 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3578 p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opc; 3579 break; 3580 default: 3581 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3582 } 3583 3584 if(enable) 3585 WRITE_UINT32(*p_BmiPcReg, BMI_COUNTERS_EN); 3586 else 3587 WRITE_UINT32(*p_BmiPcReg, 0); 3588 3589 return E_OK; 3590} 3591 3592t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt) 3593{ 3594 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3595 uint32_t tmpReg; 3596 volatile uint32_t *p_BmiPcpReg = NULL; 3597 3598 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3599 3600 switch(p_FmPort->portType) 3601 { 3602 case(e_FM_PORT_TYPE_RX_10G): 3603 case(e_FM_PORT_TYPE_RX): 3604 p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpcp; 3605 break; 3606 case(e_FM_PORT_TYPE_TX_10G): 3607 case(e_FM_PORT_TYPE_TX): 3608 p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpcp; 3609 break; 3610 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3611 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3612 p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opcp; 3613 break; 3614 default: 3615 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3616 } 3617 3618 /* check parameters */ 3619 if (!p_FmPortPerformanceCnt->taskCompVal || 3620 (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num)) 3621 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3622 ("performanceCnt.taskCompVal has to be in the range of 1 - %d (current value)!", 3623 p_FmPort->tasks.num)); 3624 if (!p_FmPortPerformanceCnt->dmaCompVal || 3625 (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num)) 3626 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3627 ("performanceCnt.dmaCompVal has to be in the range of 1 - %d (current value)!", 3628 p_FmPort->openDmas.num)); 3629 if (!p_FmPortPerformanceCnt->fifoCompVal || 3630 (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num)) 3631 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3632 ("performanceCnt.fifoCompVal has to be in the range of 256 - %d (current value)!", 3633 p_FmPort->fifoBufs.num)); 3634 if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS) 3635 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3636 ("performanceCnt.fifoCompVal has to be divisible by %d", 3637 BMI_FIFO_UNITS)); 3638 switch(p_FmPort->portType) 3639 { 3640 case(e_FM_PORT_TYPE_RX_10G): 3641 case(e_FM_PORT_TYPE_RX): 3642 if (!p_FmPortPerformanceCnt->queueCompVal || 3643 (p_FmPortPerformanceCnt->queueCompVal > MAX_PERFORMANCE_RX_QUEUE_COMP)) 3644 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3645 ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", 3646 MAX_PERFORMANCE_RX_QUEUE_COMP)); 3647 break; 3648 case(e_FM_PORT_TYPE_TX_10G): 3649 case(e_FM_PORT_TYPE_TX): 3650 if (!p_FmPortPerformanceCnt->queueCompVal || 3651 (p_FmPortPerformanceCnt->queueCompVal > MAX_PERFORMANCE_TX_QUEUE_COMP)) 3652 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 3653 ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", 3654 MAX_PERFORMANCE_TX_QUEUE_COMP)); 3655 break; 3656 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3657 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3658 if (p_FmPortPerformanceCnt->queueCompVal) 3659 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("performanceCnt.queueCompVal is not relevant for H/O ports.")); 3660 break; 3661 default: 3662 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3663 } 3664 3665 tmpReg = 0; 3666 tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->queueCompVal - 1) << BMI_PERFORMANCE_PORT_COMP_SHIFT); 3667 tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->dmaCompVal- 1) << BMI_PERFORMANCE_DMA_COMP_SHIFT); 3668 tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->fifoCompVal/BMI_FIFO_UNITS - 1) << BMI_PERFORMANCE_FIFO_COMP_SHIFT); 3669 if ((p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && (p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND)) 3670 tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->taskCompVal - 1) << BMI_PERFORMANCE_TASK_COMP_SHIFT); 3671 3672 WRITE_UINT32(*p_BmiPcpReg, tmpReg); 3673 3674 return E_OK; 3675} 3676 3677t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort) 3678{ 3679 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3680 t_FmPortPerformanceCnt currParams, savedParams; 3681 t_Error err; 3682 bool underTest, failed = FALSE; 3683 3684 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3685 3686 XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n", 3687 p_FmPort->portType, p_FmPort->portId); 3688 3689 currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; 3690 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || 3691 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) 3692 currParams.queueCompVal = 0; 3693 else 3694 currParams.queueCompVal = 1; 3695 currParams.dmaCompVal =(uint8_t) p_FmPort->openDmas.num; 3696 currParams.fifoCompVal = p_FmPort->fifoBufs.num; 3697 3698 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); 3699 ClearPerfCnts(p_FmPort); 3700 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) != E_OK) 3701 RETURN_ERROR(MAJOR, err, NO_MSG); 3702 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); 3703 XX_UDelay(1000000); 3704 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); 3705 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) 3706 { 3707 XX_Print ("Max num of defined port tasks (%d) utilized - Please enlarge\n",p_FmPort->tasks.num); 3708 failed = TRUE; 3709 } 3710 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) 3711 { 3712 XX_Print ("Max num of defined port openDmas (%d) utilized - Please enlarge\n",p_FmPort->openDmas.num); 3713 failed = TRUE; 3714 } 3715 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) 3716 { 3717 XX_Print ("Max size of defined port fifo (%d) utilized - Please enlarge\n",p_FmPort->fifoBufs.num*BMI_FIFO_UNITS); 3718 failed = TRUE; 3719 } 3720 if (failed) 3721 RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 3722 3723 memset(&savedParams, 0, sizeof(savedParams)); 3724 while (TRUE) 3725 { 3726 underTest = FALSE; 3727 if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal) 3728 { 3729 currParams.taskCompVal--; 3730 underTest = TRUE; 3731 } 3732 if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal) 3733 { 3734 currParams.dmaCompVal--; 3735 underTest = TRUE; 3736 } 3737 if ((currParams.fifoCompVal != BMI_FIFO_UNITS) && !savedParams.fifoCompVal) 3738 { 3739 currParams.fifoCompVal -= BMI_FIFO_UNITS; 3740 underTest = TRUE; 3741 } 3742 if (!underTest) 3743 break; 3744 3745 ClearPerfCnts(p_FmPort); 3746 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) != E_OK) 3747 RETURN_ERROR(MAJOR, err, NO_MSG); 3748 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); 3749 XX_UDelay(1000000); 3750 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); 3751 3752 if (!savedParams.taskCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) 3753 savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal+2); 3754 if (!savedParams.dmaCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) 3755 savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal+2); 3756 if (!savedParams.fifoCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) 3757 savedParams.fifoCompVal = currParams.fifoCompVal+2; 3758 } 3759 3760 XX_Print("best vals: tasks %d, dmas %d, fifos %d\n", 3761 savedParams.taskCompVal, savedParams.dmaCompVal, savedParams.fifoCompVal); 3762 return E_OK; 3763} 3764 3765t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable) 3766{ 3767 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3768 uint32_t tmpReg; 3769 volatile uint32_t *p_BmiStcReg = NULL; 3770 3771 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3772 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3773 3774 switch(p_FmPort->portType) 3775 { 3776 case(e_FM_PORT_TYPE_RX_10G): 3777 case(e_FM_PORT_TYPE_RX): 3778 p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rstc; 3779 break; 3780 case(e_FM_PORT_TYPE_TX_10G): 3781 case(e_FM_PORT_TYPE_TX): 3782 p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tstc; 3783 break; 3784 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3785 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3786 p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ostc; 3787 break; 3788 default: 3789 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 3790 } 3791 3792 tmpReg = GET_UINT32(*p_BmiStcReg); 3793 3794 if(enable) 3795 tmpReg |= BMI_COUNTERS_EN; 3796 else 3797 tmpReg &= ~BMI_COUNTERS_EN; 3798 3799 WRITE_UINT32(*p_BmiStcReg, tmpReg); 3800 3801 return E_OK; 3802} 3803 3804t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs) 3805{ 3806 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3807 volatile uint32_t *p_ErrQReg, *p_ErrDiscard; 3808 3809 switch(p_FmPort->portType) 3810 { 3811 case(e_FM_PORT_TYPE_RX_10G): 3812 case(e_FM_PORT_TYPE_RX): 3813 p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem; 3814 p_ErrDiscard = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm; 3815 break; 3816 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3817 p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem; 3818 p_ErrDiscard = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm; 3819 break; 3820 default: 3821 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 3822 } 3823 3824 if (GET_UINT32(*p_ErrDiscard) & errs) 3825 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Selectd Errors that were configured to cause frame discard.")); 3826 3827 WRITE_UINT32(*p_ErrQReg, errs); 3828 3829 return E_OK; 3830} 3831 3832t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable) 3833{ 3834 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3835 uint32_t tmpReg; 3836 int i; 3837 3838 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3839 SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE); 3840 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3841 3842 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 3843 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 3844 3845 for(i=0 ; i< FM_PORT_MAX_NUM_OF_EXT_POOLS ; i++) 3846 { 3847 tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); 3848 if ((uint8_t)((tmpReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT) == poolId) 3849 { 3850 if(enable) 3851 tmpReg |= BMI_EXT_BUF_POOL_EN_COUNTER; 3852 else 3853 tmpReg &= ~BMI_EXT_BUF_POOL_EN_COUNTER; 3854 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], tmpReg); 3855 break; 3856 } 3857 } 3858 if (i == FM_PORT_MAX_NUM_OF_EXT_POOLS) 3859 RETURN_ERROR(MINOR, E_INVALID_VALUE,("poolId %d is not included in this ports pools", poolId)); 3860 3861 return E_OK; 3862} 3863 3864uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter) 3865{ 3866 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3867 bool bmiCounter = FALSE; 3868 volatile uint32_t *p_Reg; 3869 3870 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 3871 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3872 3873 switch(counter) 3874 { 3875 case(e_FM_PORT_COUNTERS_DEQ_TOTAL): 3876 case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 3877 case(e_FM_PORT_COUNTERS_DEQ_CONFIRM ): 3878 /* check that counter is available for the port type */ 3879 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 3880 { 3881 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); 3882 return 0; 3883 } 3884 bmiCounter = FALSE; 3885 case(e_FM_PORT_COUNTERS_ENQ_TOTAL): 3886 bmiCounter = FALSE; 3887 break; 3888 default: /* BMI counters (or error - will be checked in BMI routine )*/ 3889 bmiCounter = TRUE; 3890 break; 3891 } 3892 3893 if(bmiCounter) 3894 { 3895 switch(p_FmPort->portType) 3896 { 3897 case(e_FM_PORT_TYPE_RX_10G): 3898 case(e_FM_PORT_TYPE_RX): 3899 if(BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) 3900 { 3901 REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 3902 return 0; 3903 } 3904 break; 3905 case(e_FM_PORT_TYPE_TX_10G): 3906 case(e_FM_PORT_TYPE_TX): 3907 if(BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) 3908 { 3909 REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 3910 return 0; 3911 } 3912 break; 3913 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3914 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3915 if(BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) 3916 { 3917 REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 3918 return 0; 3919 } 3920 break; 3921 default: 3922 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); 3923 return 0; 3924 } 3925 return GET_UINT32(*p_Reg); 3926 } 3927 else /* QMI counter */ 3928 { 3929 3930 /* check that counters are enabled */ 3931 if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN_COUNTERS)) 3932 { 3933 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 3934 return 0; 3935 } 3936 3937 /* Set counter */ 3938 switch(counter) 3939 { 3940 case(e_FM_PORT_COUNTERS_ENQ_TOTAL): 3941 return GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc); 3942 case(e_FM_PORT_COUNTERS_DEQ_TOTAL): 3943 return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc); 3944 case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 3945 return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc); 3946 case(e_FM_PORT_COUNTERS_DEQ_CONFIRM): 3947 return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc); 3948 default: 3949 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); 3950 return 0; 3951 } 3952 } 3953 3954 return 0; 3955} 3956 3957t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, uint32_t value) 3958{ 3959 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 3960 bool bmiCounter = FALSE; 3961 volatile uint32_t *p_Reg; 3962 3963 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 3964 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 3965 3966 switch(counter) 3967 { 3968 case(e_FM_PORT_COUNTERS_DEQ_TOTAL): 3969 case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 3970 case(e_FM_PORT_COUNTERS_DEQ_CONFIRM ): 3971 /* check that counter is available for the port type */ 3972 if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 3973 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports")); 3974 case(e_FM_PORT_COUNTERS_ENQ_TOTAL): 3975 bmiCounter = FALSE; 3976 break; 3977 default: /* BMI counters (or error - will be checked in BMI routine )*/ 3978 bmiCounter = TRUE; 3979 break; 3980 } 3981 3982 if(bmiCounter) 3983 { 3984 switch(p_FmPort->portType) 3985 { 3986 case(e_FM_PORT_TYPE_RX_10G): 3987 case(e_FM_PORT_TYPE_RX): 3988 if(BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) 3989 RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 3990 break; 3991 case(e_FM_PORT_TYPE_TX_10G): 3992 case(e_FM_PORT_TYPE_TX): 3993 if(BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) 3994 RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 3995 break; 3996 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 3997 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 3998 if(BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg)) 3999 RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 4000 break; 4001 default: 4002 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); 4003 } 4004 WRITE_UINT32(*p_Reg, value); 4005 } 4006 else /* QMI counter */ 4007 { 4008 4009 /* check that counters are enabled */ 4010 if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN_COUNTERS)) 4011 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); 4012 4013 /* Set counter */ 4014 switch(counter) 4015 { 4016 case(e_FM_PORT_COUNTERS_ENQ_TOTAL): 4017 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc, value); 4018 break; 4019 case(e_FM_PORT_COUNTERS_DEQ_TOTAL): 4020 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc, value); 4021 break; 4022 case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): 4023 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc, value); 4024 break; 4025 case(e_FM_PORT_COUNTERS_DEQ_CONFIRM): 4026 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc, value); 4027 break; 4028 default: 4029 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); 4030 } 4031 } 4032 4033 return E_OK; 4034} 4035 4036uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId) 4037{ 4038 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4039 uint32_t extPoolReg; 4040 uint8_t tmpPool; 4041 uint8_t i; 4042 4043 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); 4044 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4045 4046 if((p_FmPort->portType != e_FM_PORT_TYPE_RX) && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 4047 { 4048 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports")); 4049 return 0; 4050 } 4051 4052 for(i=0;i<FM_PORT_MAX_NUM_OF_EXT_POOLS;i++) 4053 { 4054 extPoolReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); 4055 if (extPoolReg & BMI_EXT_BUF_POOL_VALID) 4056 { 4057 tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT); 4058 if(tmpPool == poolId) 4059 { 4060 if(extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER) 4061 return GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i]); 4062 else 4063 { 4064 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled")); 4065 return 0; 4066 } 4067 } 4068 } 4069 } 4070 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId)); 4071 return 0; 4072} 4073 4074t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value) 4075{ 4076 t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; 4077 uint32_t extPoolReg; 4078 uint8_t tmpPool; 4079 uint8_t i; 4080 4081 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4082 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4083 4084 if((p_FmPort->portType != e_FM_PORT_TYPE_RX) && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) 4085 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports")); 4086 4087 4088 for(i=0;i<FM_PORT_MAX_NUM_OF_EXT_POOLS;i++) 4089 { 4090 extPoolReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]); 4091 if (extPoolReg & BMI_EXT_BUF_POOL_VALID) 4092 { 4093 tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT); 4094 if(tmpPool == poolId) 4095 { 4096 if(extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER) 4097 { 4098 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], value); 4099 return E_OK; 4100 } 4101 else 4102 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled")); 4103 } 4104 } 4105 } 4106 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId)); 4107} 4108 4109bool FM_PORT_IsStalled(t_Handle h_FmPort) 4110{ 4111 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4112 t_Error err; 4113 bool isStalled; 4114 4115 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE); 4116 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, FALSE); 4117 4118 err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled); 4119 if(err != E_OK) 4120 { 4121 REPORT_ERROR(MINOR, err, NO_MSG); 4122 return TRUE; 4123 } 4124 return isStalled; 4125} 4126 4127t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort) 4128{ 4129 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4130 4131 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4132 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4133 4134 return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId); 4135} 4136 4137t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum) 4138{ 4139 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4140 uint32_t tmpReg; 4141 4142 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4143 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4144 4145 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 4146 (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 4147 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only")); 4148 4149 tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); 4150 if (l4Checksum) 4151 tmpReg &= ~BMI_PORT_RFNE_FRWD_DCL4C; 4152 else 4153 tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C; 4154 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, tmpReg); 4155 4156 return E_OK; 4157} 4158 4159 4160/* API Run-time PCD Control unit functions */ 4161 4162t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles) 4163{ 4164 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4165 t_Error err = E_OK; 4166 4167 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); 4168 ASSERT_COND(p_FmPort->h_FmPcd); 4169 4170 if(numOfProfiles) 4171 { 4172 err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, numOfProfiles); 4173 if(err) 4174 RETURN_ERROR(MAJOR, err,NO_MSG); 4175 } 4176 FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId); 4177 4178 return E_OK; 4179} 4180 4181t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort) 4182{ 4183 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4184 t_Error err = E_OK; 4185 4186 err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId); 4187 if(err) 4188 RETURN_ERROR(MAJOR, err,NO_MSG); 4189 return E_OK; 4190} 4191 4192t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme) 4193{ 4194 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4195 volatile uint32_t *p_BmiHpnia = NULL; 4196 uint32_t tmpReg; 4197 uint8_t relativeSchemeId; 4198 uint8_t physicalSchemeId; 4199 4200 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4201 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4202 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE); 4203 4204 tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC)? NIA_KG_CC_EN:0); 4205 switch(p_FmPort->portType) 4206 { 4207 case(e_FM_PORT_TYPE_RX_10G): 4208 case(e_FM_PORT_TYPE_RX): 4209 p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; 4210 break; 4211 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4212 p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne; 4213 break; 4214 default: 4215 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 4216 } 4217 4218 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4219 return ERROR_CODE(E_BUSY); 4220 /* if we want to change to direct scheme, we need to check that this scheme is valid */ 4221 if(p_FmPcdKgScheme->direct) 4222 { 4223 physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_FmPcdKgScheme->h_DirectScheme)-1); 4224 /* check that this scheme is bound to this port */ 4225 if(!(p_FmPort->schemesPerPortVector & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId)))) 4226 { 4227 RELEASE_LOCK(p_FmPort->lock); 4228 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("called with a scheme that is not bound to this port")); 4229 } 4230 4231 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd, physicalSchemeId); 4232 if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 4233 { 4234 RELEASE_LOCK(p_FmPort->lock); 4235 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("called with invalid Scheme ")); 4236 } 4237 4238 if(!FmPcdKgIsSchemeValidSw(p_FmPort->h_FmPcd, relativeSchemeId)) 4239 { 4240 RELEASE_LOCK(p_FmPort->lock); 4241 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("called with uninitialized Scheme ")); 4242 } 4243 4244 WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId); 4245 } 4246 else /* change to indirect scheme */ 4247 WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg); 4248 RELEASE_LOCK(p_FmPort->lock); 4249 4250 return E_OK; 4251} 4252 4253t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile) 4254{ 4255 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4256 volatile uint32_t *p_BmiNia; 4257 volatile uint32_t *p_BmiHpnia; 4258 uint32_t tmpReg; 4259 uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1); 4260 4261 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4262 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4263 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR , E_INVALID_STATE); 4264 4265 /* check relevancy of this routine - only when policer is used 4266 directly after BMI or Parser */ 4267 if((p_FmPort->pcdEngines & FM_PCD_KG) || (p_FmPort->pcdEngines & FM_PCD_CC)) 4268 RETURN_ERROR(MINOR, E_INVALID_STATE, ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR")); 4269 4270 switch(p_FmPort->portType) 4271 { 4272 case(e_FM_PORT_TYPE_RX_10G): 4273 case(e_FM_PORT_TYPE_RX): 4274 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; 4275 p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne; 4276 tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; 4277 break; 4278 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4279 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; 4280 p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne; 4281 tmpReg = 0; 4282 break; 4283 default: 4284 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 4285 } 4286 4287 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4288 return ERROR_CODE(E_BUSY); 4289 if(!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) 4290 { 4291 RELEASE_LOCK(p_FmPort->lock); 4292 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile")); 4293 } 4294 4295 tmpReg = (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId); 4296 4297 if(p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ 4298 { 4299 /* update BMI HPNIA */ 4300 WRITE_UINT32(*p_BmiHpnia, tmpReg); 4301 } 4302 else /* e_FM_PCD_SUPPORT_PLCR_ONLY */ 4303 { 4304 /* rfne may contain FDCS bits, so first we read them. */ 4305 tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK); 4306 /* update BMI NIA */ 4307 WRITE_UINT32(*p_BmiNia, tmpReg); 4308 } 4309 RELEASE_LOCK(p_FmPort->lock); 4310 4311 return E_OK; 4312} 4313 4314 4315t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree) 4316{ 4317 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4318 t_Error err = E_OK; 4319 volatile uint32_t *p_BmiCcBase=NULL; 4320 volatile uint32_t *p_BmiNia=NULL; 4321 uint32_t ccTreePhysOffset; 4322 4323 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_VALUE); 4324 4325 if (p_FmPort->imEn) 4326 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); 4327 4328 /* get PCD registers pointers */ 4329 switch(p_FmPort->portType) 4330 { 4331 case(e_FM_PORT_TYPE_RX_10G): 4332 case(e_FM_PORT_TYPE_RX): 4333 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; 4334 break; 4335 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4336 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; 4337 break; 4338 default: 4339 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 4340 } 4341 4342 /* check that current NIA is BMI to BMI */ 4343 if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) 4344 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state.")); 4345 4346/*TODO - to take care of changes due to previous tree. Maybe in the previous tree where chnged pndn, pnen ... 4347 it has to be returned to the default state - initially*/ 4348 4349 p_FmPort->requiredAction = 0; 4350 4351 if(p_FmPort->pcdEngines & FM_PCD_CC) 4352 { 4353 switch(p_FmPort->portType) 4354 { 4355 case(e_FM_PORT_TYPE_RX_10G): 4356 case(e_FM_PORT_TYPE_RX): 4357 p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb; 4358 break; 4359 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4360 p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_occb; 4361 break; 4362 default: 4363 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); 4364 } 4365 4366 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4367 return ERROR_CODE(E_BUSY); 4368 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, h_CcTree, &ccTreePhysOffset, h_FmPort); 4369 if(err) 4370 { 4371 RELEASE_LOCK(p_FmPort->lock); 4372 RETURN_ERROR(MINOR, err, NO_MSG); 4373 } 4374 WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); 4375 4376 p_FmPort->ccTreeId = h_CcTree; 4377 RELEASE_LOCK(p_FmPort->lock); 4378 } 4379 else 4380 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Coarse CLassification not defined for this port.")); 4381 4382 return E_OK; 4383} 4384 4385t_Error FM_PORT_AttachPCD(t_Handle h_FmPort) 4386{ 4387 4388 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4389 t_Error err = E_OK; 4390 4391 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4392 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4393 4394 if (p_FmPort->imEn) 4395 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); 4396 4397 /* TODO - may add here checks for: 4398 SP (or in sw: schemes) 4399 CPP (or in sw clsPlan) 4400 Parser enabled and configured(?) 4401 Tree(?) 4402 Profile - only if direct. 4403 Scheme - only if direct 4404 */ 4405 4406 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4407 return ERROR_CODE(E_BUSY); 4408 err = FmPortAttachPCD(h_FmPort); 4409 RELEASE_LOCK(p_FmPort->lock); 4410 4411 return err; 4412} 4413 4414t_Error FM_PORT_DetachPCD(t_Handle h_FmPort) 4415{ 4416 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4417 volatile uint32_t *p_BmiNia=NULL; 4418 4419 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4420 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4421 4422 if (p_FmPort->imEn) 4423 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); 4424 4425 /* get PCD registers pointers */ 4426 switch(p_FmPort->portType) 4427 { 4428 case(e_FM_PORT_TYPE_RX_10G): 4429 case(e_FM_PORT_TYPE_RX): 4430 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; 4431 break; 4432 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4433 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; 4434 break; 4435 default: 4436 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 4437 } 4438 4439 WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); 4440 4441/*TODO - not atomic - it seems that port has to be disabled*/ 4442 if(p_FmPort->requiredAction & UPDATE_NIA_PNEN) 4443 { 4444 switch(p_FmPort->portType) 4445 { 4446 case(e_FM_PORT_TYPE_TX_10G): 4447 case(e_FM_PORT_TYPE_TX): 4448 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); 4449 break; 4450 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 4451 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4452 case(e_FM_PORT_TYPE_RX): 4453 case(e_FM_PORT_TYPE_RX_10G): 4454 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE); 4455 break; 4456 default: 4457 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage")); 4458 } 4459 } 4460 4461 if(p_FmPort->requiredAction & UPDATE_NIA_PNDN) 4462 { 4463 switch(p_FmPort->portType) 4464 { 4465 case(e_FM_PORT_TYPE_TX_10G): 4466 case(e_FM_PORT_TYPE_TX): 4467 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX); 4468 break; 4469 case(e_FM_PORT_TYPE_OH_HOST_COMMAND): 4470 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4471 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH); 4472 break; 4473 default: 4474 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage")); 4475 } 4476 } 4477 4478 4479 if(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) 4480 if(FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2)!= E_OK) 4481 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 4482 return E_OK; 4483} 4484 4485t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams) 4486{ 4487 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4488 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 4489 t_Error err = E_OK; 4490 uint8_t i; 4491 4492 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4493 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4494 4495 if (p_FmPort->imEn) 4496 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independent mode ports only")); 4497 4498 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4499 return ERROR_CODE(E_BUSY); 4500 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); 4501 ASSERT_COND(p_FmPort->h_FmPcd); 4502 4503 err = SetPcd( h_FmPort, p_PcdParams); 4504 if(err) 4505 { 4506 RELEASE_LOCK(p_FmPort->lock); 4507 RETURN_ERROR(MAJOR, err, NO_MSG); 4508 } 4509 4510 if(p_FmPort->pcdEngines & FM_PCD_KG) 4511 { 4512 schemeBind.netEnvId = p_FmPort->netEnvId; 4513 schemeBind.hardwarePortId = p_FmPort->hardwarePortId; 4514 schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes; 4515 schemeBind.useClsPlan = p_FmPort->useClsPlan; 4516 for(i = 0;i<schemeBind.numOfSchemes;i++) 4517 schemeBind.schemesIds[i] = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_Schemes[i])-1); 4518 4519 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 4520 if(err) 4521 { 4522 DeletePcd(p_FmPort); 4523 RELEASE_LOCK(p_FmPort->lock); 4524 RETURN_ERROR(MAJOR, err, NO_MSG); 4525 } 4526 } 4527 4528 if ((p_FmPort->pcdEngines & FM_PCD_PRS) && (p_PcdParams->p_PrsParams->includeInPrsStatistics)) 4529 FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, TRUE); 4530 4531 FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); 4532 4533 err = FmPortAttachPCD(h_FmPort); 4534 RELEASE_LOCK(p_FmPort->lock); 4535 4536 return err; 4537} 4538 4539t_Error FM_PORT_DeletePCD(t_Handle h_FmPort) 4540{ 4541 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4542 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 4543 t_Error err = E_OK; 4544 4545 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4546 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4547 4548 if (p_FmPort->imEn) 4549 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only")); 4550 4551 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4552 return ERROR_CODE(E_BUSY); 4553 4554 err = FM_PORT_DetachPCD(h_FmPort); 4555 if(err) 4556 { 4557 RELEASE_LOCK(p_FmPort->lock); 4558 RETURN_ERROR(MAJOR, err, NO_MSG); 4559 } 4560 4561 FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); 4562 4563 /* we do it anyway, instead of checking if included */ 4564 if (FmIsMaster(p_FmPort->h_Fm) && 4565 (p_FmPort->pcdEngines & FM_PCD_PRS)) 4566 FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, FALSE); 4567 4568 if(p_FmPort->pcdEngines & FM_PCD_KG) 4569 { 4570 /* unbind all schemes */ 4571 p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort, &schemeBind); 4572 4573 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 4574 if(err) 4575 { 4576 RELEASE_LOCK(p_FmPort->lock); 4577 RETURN_ERROR(MAJOR, err, NO_MSG); 4578 } 4579 } 4580 4581 err = DeletePcd(h_FmPort); 4582 RELEASE_LOCK(p_FmPort->lock); 4583 4584 return err; 4585} 4586 4587t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme) 4588{ 4589 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4590 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 4591 t_Error err = E_OK; 4592 uint32_t tmpScmVec=0; 4593 int i; 4594 4595 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4596 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4597 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE); 4598 4599 schemeBind.netEnvId = p_FmPort->netEnvId; 4600 schemeBind.hardwarePortId = p_FmPort->hardwarePortId; 4601 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; 4602 schemeBind.useClsPlan = p_FmPort->useClsPlan; 4603 for (i=0; i<schemeBind.numOfSchemes; i++) 4604 { 4605 schemeBind.schemesIds[i] = (uint8_t)(PTR_TO_UINT(p_PortScheme->h_Schemes[i])-1); 4606 /* build vector */ 4607 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); 4608 } 4609 4610 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4611 return ERROR_CODE(E_BUSY); 4612 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 4613 if (err == E_OK) 4614 p_FmPort->schemesPerPortVector |= tmpScmVec; 4615 RELEASE_LOCK(p_FmPort->lock); 4616 4617 return err; 4618} 4619 4620t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme) 4621{ 4622 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4623 t_FmPcdKgInterModuleBindPortToSchemes schemeBind; 4624 t_Error err = E_OK; 4625 uint32_t tmpScmVec=0; 4626 int i; 4627 4628 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4629 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4630 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE); 4631 4632 schemeBind.netEnvId = p_FmPort->netEnvId; 4633 schemeBind.hardwarePortId = p_FmPort->hardwarePortId; 4634 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; 4635 for (i=0; i<schemeBind.numOfSchemes; i++) 4636 { 4637 schemeBind.schemesIds[i] = (uint8_t)(PTR_TO_UINT(p_PortScheme->h_Schemes[i])-1); 4638 /* build vector */ 4639 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); 4640 } 4641 4642 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4643 return ERROR_CODE(E_BUSY); 4644 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); 4645 if (err == E_OK) 4646 p_FmPort->schemesPerPortVector &= ~tmpScmVec; 4647 RELEASE_LOCK(p_FmPort->lock); 4648 4649 return err; 4650} 4651 4652t_Error FM_PORT_PcdPrsModifyStartOffset (t_Handle h_FmPort, t_FmPcdPrsStart *p_FmPcdPrsStart) 4653{ 4654 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4655 volatile uint32_t *p_BmiPrsStartOffset = NULL; 4656 volatile uint32_t *p_BmiNia = NULL; 4657 uint32_t tmpReg; 4658 uint8_t hdrNum; 4659 4660 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4661 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4662 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PRS , E_INVALID_STATE); 4663 4664 switch(p_FmPort->portType) 4665 { 4666 case(e_FM_PORT_TYPE_RX_10G): 4667 case(e_FM_PORT_TYPE_RX): 4668 p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso; 4669 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne; 4670 tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; 4671 break; 4672 case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4673 p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso; 4674 p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne; 4675 tmpReg = 0; 4676 break; 4677 default: 4678 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only")); 4679 } 4680 4681 /* check that current NIA is BMI to BMI */ 4682 if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) 4683 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state.")); 4684 4685 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) 4686 return ERROR_CODE(E_BUSY); 4687 /* set the first header */ 4688 GET_PRS_HDR_NUM(hdrNum, p_FmPcdPrsStart->firstPrsHdr); 4689 if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM)) 4690 { 4691 RELEASE_LOCK(p_FmPort->lock); 4692 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); 4693 } 4694 WRITE_UINT32(*p_BmiNia, (uint32_t)(NIA_ENG_PRS | (uint32_t)hdrNum | tmpReg)); 4695 4696 /* set start parsing offset */ 4697 WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)(p_FmPcdPrsStart->parsingOffset + p_FmPort->internalBufferOffset)); 4698 RELEASE_LOCK(p_FmPort->lock); 4699 4700 return E_OK; 4701} 4702 4703#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) 4704t_Error FM_PORT_DumpRegs(t_Handle h_FmPort) 4705{ 4706 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4707 t_Error err = E_OK; 4708 char arr[30]; 4709 uint8_t flag; 4710 int i=0; 4711 4712 DECLARE_DUMP; 4713 4714 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4715 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); 4716 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortQmiRegs, E_INVALID_HANDLE); 4717 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortBmiRegs, E_INVALID_HANDLE); 4718 4719 switch (p_FmPort->portType) 4720 { 4721 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): 4722 strcpy(arr, "PORT_TYPE_OFFLINE_PARSING"); 4723 flag = 0; 4724 break; 4725 case (e_FM_PORT_TYPE_OH_HOST_COMMAND): 4726 strcpy(arr, "PORT_TYPE_HOST_COMMAND"); 4727 flag = 0; 4728 break; 4729 case (e_FM_PORT_TYPE_RX): 4730 strcpy(arr, "PORT_TYPE_RX"); 4731 flag = 1; 4732 break; 4733 case (e_FM_PORT_TYPE_RX_10G): 4734 strcpy(arr, "PORT_TYPE_RX_10G"); 4735 flag = 1; 4736 break; 4737 case (e_FM_PORT_TYPE_TX): 4738 strcpy(arr, "PORT_TYPE_TX"); 4739 flag = 2; 4740 break; 4741 case (e_FM_PORT_TYPE_TX_10G): 4742 strcpy(arr, "PORT_TYPE_TX_10G"); 4743 flag = 2; 4744 break; 4745 default: 4746 return ERROR_CODE(E_INVALID_VALUE); 4747 } 4748 4749 DUMP_TITLE(UINT_TO_PTR(p_FmPort->hardwarePortId), ("PortId for %s %d", arr, p_FmPort->portId )); 4750 DUMP_TITLE(p_FmPort->p_FmPortBmiRegs, ("Bmi Port Regs")); 4751 4752 err = FmDumpPortRegs(p_FmPort->h_Fm, p_FmPort->hardwarePortId); 4753 if(err) 4754 RETURN_ERROR(MAJOR, err, NO_MSG); 4755 4756 switch(flag) 4757 { 4758 case(0): 4759 4760 DUMP_SUBTITLE(("\n")); 4761 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocfg); 4762 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ost); 4763 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oda); 4764 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdne); 4765 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofne); 4766 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofca); 4767 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofpne); 4768 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opso); 4769 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opp); 4770 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occb); 4771 4772 DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai), ("fmbm_oprai")); 4773 DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS) 4774 { 4775 DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[i]), sizeof(uint32_t)); 4776 } 4777 DUMP_SUBTITLE(("\n")); 4778 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofqid ); 4779 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oefqid); 4780 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsdm ); 4781 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsem ); 4782 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofene ); 4783 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmts); 4784 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmt); 4785 4786 { 4787#ifndef FM_NO_OP_OBSERVED_POOLS 4788 t_FmRevisionInfo revInfo; 4789 4790 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 4791 if (revInfo.majorRev == 4) 4792#endif /* !FM_NO_OP_OBSERVED_POOLS */ 4793 { 4794 DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi, ("fmbm_oebmpi")); 4795 4796 DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS) 4797 { 4798 DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi[i], sizeof(uint32_t)); 4799 } 4800 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocgm); 4801 } 4802 } 4803 4804 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ostc); 4805 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofrc ); 4806 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdc ); 4807 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofledc); 4808 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofufdc); 4809 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_offc); 4810 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofwdc); 4811 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofldec); 4812 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opc); 4813 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opcp); 4814 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occn); 4815 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_otuc); 4816 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oduc); 4817 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofuc); 4818 break; 4819 case(1): 4820 DUMP_SUBTITLE(("\n")); 4821 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rcfg); 4822 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rst); 4823 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rda); 4824 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfp); 4825 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_reth); 4826 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfed); 4827 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_ricp); 4828 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rebm); 4829 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfne); 4830 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfca); 4831 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfpne); 4832 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpso); 4833 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpp); 4834 4835 DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai), ("fmbm_rprai")); 4836 DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS) 4837 { 4838 DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[i]), sizeof(uint32_t)); 4839 } 4840 DUMP_SUBTITLE(("\n")); 4841 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfqid); 4842 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_refqid); 4843 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsdm); 4844 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsem); 4845 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfene); 4846 DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi, ("fmbm_ebmpi")); 4847 DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS) 4848 { 4849 DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], sizeof(uint32_t)); 4850 } 4851 DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt, ("fmbm_acnt")); 4852 DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS) 4853 { 4854 DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], sizeof(uint32_t)); 4855 } 4856 DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm, ("fmbm_cgm")); 4857 DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_NUM_OF_CONGESTION_GRPS/32) 4858 { 4859 DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[i], sizeof(uint32_t)); 4860 } 4861 DUMP_SUBTITLE(("\n")); 4862 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_mpd); 4863 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rstc); 4864 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfrc); 4865 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfbc); 4866 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rlfc); 4867 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rffc); 4868 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfcd); 4869 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfldec); 4870 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rodc); 4871 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpc); 4872 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpcp); 4873 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rccn); 4874 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rtuc); 4875 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rrquc); 4876 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rduc); 4877 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfuc); 4878 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpac); 4879 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rdbg); 4880 break; 4881 case(2): 4882 4883 DUMP_SUBTITLE(("\n")); 4884 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfg); 4885 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tst); 4886 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tda); 4887 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfp); 4888 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfed); 4889 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ticp); 4890 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfne); 4891 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfca); 4892 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfqid); 4893 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfeqid); 4894 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfene); 4895 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmts); 4896 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmt); 4897 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tstc); 4898 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfrc); 4899 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfdc); 4900 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfledc); 4901 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfufdc); 4902 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpc); 4903 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpcp); 4904 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tccn); 4905 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttuc); 4906 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttcquc); 4907 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tduc); 4908 DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfuc); 4909 break; 4910 4911 default: 4912 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid flag")); 4913 } 4914 4915 DUMP_TITLE(p_FmPort->p_FmPortQmiRegs, ("Qmi Port Regs")); 4916 4917 DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnc); 4918 DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pns); 4919 DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnts); 4920 DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnen); 4921 DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnetfc); 4922 4923 if(flag !=1) 4924 { 4925 DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndn); 4926 DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndc); 4927 DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndtfc); 4928 DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndfdc); 4929 DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndcc); 4930 } 4931 4932 return E_OK; 4933} 4934#endif /* (defined(DEBUG_ERRORS) && ... */ 4935 4936t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps) 4937{ 4938 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 4939 bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort; 4940 int i; 4941 uint8_t mod; 4942 uint32_t tmpReg = 0; 4943 4944 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 4945 4946 { 4947#ifdef FM_NO_OP_OBSERVED_CGS 4948 t_FmRevisionInfo revInfo; 4949 4950 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 4951 if (revInfo.majorRev != 4) 4952 { 4953 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 4954 (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 4955 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); 4956 } 4957 else 4958#endif /* FM_NO_OP_OBSERVED_CGS */ 4959 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 4960 (p_FmPort->portType != e_FM_PORT_TYPE_RX) && 4961 (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 4962 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx & OP ports only")); 4963 } 4964 4965 opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE); 4966 4967 /* to minimize memory access (groups may belong to the same regsiter, and may 4968 be out of order), we first collect all information into a 256 booleans array, 4969 representing each possible group. */ 4970 4971 memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool)); 4972 for(i=0;i<p_CongestionGrps->numOfCongestionGrpsToConsider;i++) 4973 tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE; 4974 4975 for(i=0;i<FM_PORT_NUM_OF_CONGESTION_GRPS;i++) 4976 { 4977 mod = (uint8_t)(i%32); 4978 /* each 32 congestion groups are represented by a register */ 4979 if (mod == 0) /* first in a 32 bunch of congestion groups, get the currest register state */ 4980 tmpReg = opPort ? GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm): 4981 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32]); 4982 4983 /* set in the register, the bit representing the relevant congestion group. */ 4984 if(tmpArray[i]) 4985 tmpReg |= (0x00000001 << (uint32_t)mod); 4986 4987 if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */ 4988 { 4989 if(opPort) 4990 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg); 4991 else 4992 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32], tmpReg); 4993 } 4994 } 4995 4996 return E_OK; 4997} 4998 4999t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps) 5000{ 5001 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; 5002 bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort; 5003 int i; 5004 uint8_t mod; 5005 uint32_t tmpReg = 0; 5006 5007 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); 5008 5009 { 5010#ifdef FM_NO_OP_OBSERVED_CGS 5011 t_FmRevisionInfo revInfo; 5012 5013 FM_GetRevision(p_FmPort->h_Fm, &revInfo); 5014 if (revInfo.majorRev != 4) 5015 { 5016 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 5017 (p_FmPort->portType != e_FM_PORT_TYPE_RX)) 5018 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); 5019 } 5020 else 5021#endif /* FM_NO_OP_OBSERVED_CGS */ 5022 if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && 5023 (p_FmPort->portType != e_FM_PORT_TYPE_RX) && 5024 (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) 5025 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx & OP ports only")); 5026 } 5027 5028 opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE); 5029 5030 /* to minimize memory access (groups may belong to the same regsiter, and may 5031 be out of order), we first collect all information into a 256 booleans array, 5032 representing each possible group. */ 5033 memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool)); 5034 for(i=0;i<p_CongestionGrps->numOfCongestionGrpsToConsider;i++) 5035 tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE; 5036 5037 for(i=0;i<FM_PORT_NUM_OF_CONGESTION_GRPS;i++) 5038 { 5039 mod = (uint8_t)(i%32); 5040 /* each 32 congestion groups are represented by a register */ 5041 if (mod == 0) /* first in a 32 bunch of congestion groups, get the currest register state */ 5042 tmpReg = opPort ? GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm): 5043 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32]); 5044 5045 /* set in the register, the bit representing the relevant congestion group. */ 5046 if(tmpArray[i]) 5047 tmpReg &= ~(0x00000001 << (uint32_t)mod); 5048 5049 if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */ 5050 { 5051 if(opPort) 5052 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg); 5053 else 5054 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32], tmpReg); 5055 } 5056 } 5057 5058 return E_OK; 5059} 5060 5061