1 /* 2 * Copyright 2008-2012 Freescale Semiconductor Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * * Neither the name of Freescale Semiconductor nor the 12 * names of its contributors may be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * 16 * ALTERNATIVELY, this software may be distributed under the terms of the 17 * GNU General Public License ("GPL") as published by the Free Software 18 * Foundation, either version 2 of that License or (at your option) any 19 * later version. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 34 /****************************************************************************** 35 @File fm_manip.c 36 37 @Description FM PCD manip ... 38 *//***************************************************************************/ 39 #include "std_ext.h" 40 #include "error_ext.h" 41 #include "string_ext.h" 42 #include "debug_ext.h" 43 #include "fm_pcd_ext.h" 44 #include "fm_port_ext.h" 45 #include "fm_muram_ext.h" 46 #include "memcpy_ext.h" 47 48 #include "fm_common.h" 49 #include "fm_hc.h" 50 #include "fm_manip.h" 51 52 /****************************************/ 53 /* static functions */ 54 /****************************************/ 55 static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo) 56 { 57 t_FmPcdManip *p_CurManip = p_Manip; 58 59 if (!MANIP_IS_UNIFIED(p_Manip)) 60 p_CurManip = p_Manip; 61 else 62 { 63 /* go to first unified */ 64 while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) 65 p_CurManip = p_CurManip->h_PrevManip; 66 } 67 68 switch (manipInfo) 69 { 70 case (e_MANIP_HMCT): 71 return p_CurManip->p_Hmct; 72 case (e_MANIP_HMTD): 73 return p_CurManip->h_Ad; 74 case (e_MANIP_HANDLER_TABLE_OWNER): 75 return (t_Handle)p_CurManip; 76 default: 77 return NULL; 78 } 79 } 80 81 static uint16_t GetHmctSize(t_FmPcdManip *p_Manip) 82 { 83 uint16_t size = 0; 84 t_FmPcdManip *p_CurManip = p_Manip; 85 86 if (!MANIP_IS_UNIFIED(p_Manip)) 87 return p_Manip->tableSize; 88 89 /* accumulate sizes, starting with the first node */ 90 while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) 91 p_CurManip = p_CurManip->h_PrevManip; 92 93 while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) 94 { 95 size += p_CurManip->tableSize; 96 p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip; 97 } 98 size += p_CurManip->tableSize; /* add last size */ 99 100 return (size); 101 } 102 103 static uint16_t GetDataSize(t_FmPcdManip *p_Manip) 104 { 105 uint16_t size = 0; 106 t_FmPcdManip *p_CurManip = p_Manip; 107 108 if (!MANIP_IS_UNIFIED(p_Manip)) 109 return p_Manip->dataSize; 110 111 /* accumulate sizes, starting with the first node */ 112 while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) 113 p_CurManip = p_CurManip->h_PrevManip; 114 115 while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) 116 { 117 size += p_CurManip->dataSize; 118 p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip; 119 } 120 size += p_CurManip->dataSize; /* add last size */ 121 122 return (size); 123 } 124 125 static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams, 126 uint16_t *p_TableSize, uint8_t *p_DataSize) 127 { 128 uint8_t localDataSize, remain, tableSize = 0, dataSize = 0; 129 130 if (p_FmPcdManipParams->u.hdr.rmv) 131 { 132 switch (p_FmPcdManipParams->u.hdr.rmvParams.type) 133 { 134 case (e_FM_PCD_MANIP_RMV_GENERIC): 135 tableSize += HMCD_BASIC_SIZE; 136 break; 137 case (e_FM_PCD_MANIP_RMV_BY_HDR): 138 switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type) 139 { 140 case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): 141 #if (DPAA_VERSION >= 11) 142 case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): 143 case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): 144 #endif /* (DPAA_VERSION >= 11) */ 145 tableSize += HMCD_BASIC_SIZE; 146 break; 147 default: 148 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 149 ("Unknown byHdr.type")); 150 } 151 break; 152 default: 153 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 154 ("Unknown rmvParams.type")); 155 } 156 } 157 158 if (p_FmPcdManipParams->u.hdr.insrt) 159 { 160 switch (p_FmPcdManipParams->u.hdr.insrtParams.type) 161 { 162 case (e_FM_PCD_MANIP_INSRT_GENERIC): 163 remain = 164 (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size 165 % 4); 166 if (remain) 167 localDataSize = 168 (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size 169 + 4 - remain); 170 else 171 localDataSize = 172 p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size; 173 tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize); 174 break; 175 case (e_FM_PCD_MANIP_INSRT_BY_HDR): 176 { 177 switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type) 178 { 179 180 case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): 181 tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE; 182 switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2) 183 { 184 case (e_FM_PCD_MANIP_HDR_INSRT_MPLS): 185 case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE): 186 dataSize += 187 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size; 188 break; 189 default: 190 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); 191 } 192 break; 193 #if (DPAA_VERSION >= 11) 194 case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): 195 tableSize += 196 (HMCD_BASIC_SIZE + HMCD_PTR_SIZE 197 + HMCD_PARAM_SIZE 198 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size); 199 dataSize += 2; 200 break; 201 202 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): 203 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): 204 tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE); 205 206 break; 207 208 case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): 209 tableSize += 210 (HMCD_BASIC_SIZE 211 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); 212 break; 213 #endif /* (DPAA_VERSION >= 11) */ 214 default: 215 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 216 ("Unknown byHdr.type")); 217 } 218 } 219 break; 220 default: 221 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 222 ("Unknown insrtParams.type")); 223 } 224 } 225 226 if (p_FmPcdManipParams->u.hdr.fieldUpdate) 227 { 228 switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type) 229 { 230 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN): 231 tableSize += HMCD_BASIC_SIZE; 232 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType 233 == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) 234 { 235 tableSize += HMCD_PTR_SIZE; 236 dataSize += DSCP_TO_VLAN_TABLE_SIZE; 237 } 238 break; 239 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4): 240 tableSize += HMCD_BASIC_SIZE; 241 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 242 & HDR_MANIP_IPV4_ID) 243 { 244 tableSize += HMCD_PARAM_SIZE; 245 dataSize += 2; 246 } 247 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 248 & HDR_MANIP_IPV4_SRC) 249 tableSize += HMCD_IPV4_ADDR_SIZE; 250 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 251 & HDR_MANIP_IPV4_DST) 252 tableSize += HMCD_IPV4_ADDR_SIZE; 253 break; 254 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6): 255 tableSize += HMCD_BASIC_SIZE; 256 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 257 & HDR_MANIP_IPV6_SRC) 258 tableSize += HMCD_IPV6_ADDR_SIZE; 259 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 260 & HDR_MANIP_IPV6_DST) 261 tableSize += HMCD_IPV6_ADDR_SIZE; 262 break; 263 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP): 264 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates 265 == HDR_MANIP_TCP_UDP_CHECKSUM) 266 /* we implement this case with the update-checksum descriptor */ 267 tableSize += HMCD_BASIC_SIZE; 268 else 269 /* we implement this case with the TCP/UDP-update descriptor */ 270 tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE; 271 break; 272 default: 273 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 274 ("Unknown fieldUpdateParams.type")); 275 } 276 } 277 278 if (p_FmPcdManipParams->u.hdr.custom) 279 { 280 switch (p_FmPcdManipParams->u.hdr.customParams.type) 281 { 282 case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE): 283 { 284 tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE; 285 dataSize += 286 p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize; 287 if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType 288 == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) 289 && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)) 290 dataSize += 2; 291 } 292 break; 293 case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE): 294 tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE; 295 break; 296 default: 297 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 298 ("Unknown customParams.type")); 299 } 300 } 301 302 *p_TableSize = tableSize; 303 *p_DataSize = dataSize; 304 305 return E_OK; 306 } 307 308 static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo, 309 uint8_t *parseArrayOffset) 310 { 311 e_NetHeaderType hdr = p_HdrInfo->hdr; 312 e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex; 313 bool byField = p_HdrInfo->byField; 314 t_FmPcdFields field; 315 316 if (byField) 317 field = p_HdrInfo->fullField; 318 319 if (byField) 320 { 321 switch (hdr) 322 { 323 case (HEADER_TYPE_ETH): 324 switch (field.eth) 325 { 326 case (NET_HEADER_FIELD_ETH_TYPE): 327 *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; 328 break; 329 default: 330 RETURN_ERROR( 331 MAJOR, 332 E_NOT_SUPPORTED, 333 ("Header manipulation of the type Ethernet with this field not supported")); 334 } 335 break; 336 case (HEADER_TYPE_VLAN): 337 switch (field.vlan) 338 { 339 case (NET_HEADER_FIELD_VLAN_TCI): 340 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) 341 || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 342 *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; 343 else 344 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 345 *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; 346 break; 347 default: 348 RETURN_ERROR( 349 MAJOR, 350 E_NOT_SUPPORTED, 351 ("Header manipulation of the type VLAN with this field not supported")); 352 } 353 break; 354 default: 355 RETURN_ERROR( 356 MAJOR, 357 E_NOT_SUPPORTED, 358 ("Header manipulation of this header by field not supported")); 359 } 360 } 361 else 362 { 363 switch (hdr) 364 { 365 case (HEADER_TYPE_ETH): 366 *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET; 367 break; 368 case (HEADER_TYPE_USER_DEFINED_SHIM1): 369 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET; 370 break; 371 case (HEADER_TYPE_USER_DEFINED_SHIM2): 372 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET; 373 break; 374 case (HEADER_TYPE_LLC_SNAP): 375 *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET; 376 break; 377 case (HEADER_TYPE_PPPoE): 378 *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET; 379 break; 380 case (HEADER_TYPE_MPLS): 381 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) 382 || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 383 *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; 384 else 385 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 386 *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; 387 break; 388 case (HEADER_TYPE_IPv4): 389 case (HEADER_TYPE_IPv6): 390 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) 391 || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 392 *parseArrayOffset = CC_PC_PR_IP1_OFFSET; 393 else 394 if (hdrIndex == e_FM_PCD_HDR_INDEX_2) 395 *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; 396 break; 397 case (HEADER_TYPE_MINENCAP): 398 *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; 399 break; 400 case (HEADER_TYPE_GRE): 401 *parseArrayOffset = CC_PC_PR_GRE_OFFSET; 402 break; 403 case (HEADER_TYPE_TCP): 404 case (HEADER_TYPE_UDP): 405 case (HEADER_TYPE_IPSEC_AH): 406 case (HEADER_TYPE_IPSEC_ESP): 407 case (HEADER_TYPE_DCCP): 408 case (HEADER_TYPE_SCTP): 409 *parseArrayOffset = CC_PC_PR_L4_OFFSET; 410 break; 411 case (HEADER_TYPE_CAPWAP): 412 case (HEADER_TYPE_CAPWAP_DTLS): 413 *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET; 414 break; 415 default: 416 RETURN_ERROR( 417 MAJOR, 418 E_NOT_SUPPORTED, 419 ("Header manipulation of this header is not supported")); 420 } 421 } 422 return E_OK; 423 } 424 425 static t_Error BuildHmct(t_FmPcdManip *p_Manip, 426 t_FmPcdManipParams *p_FmPcdManipParams, 427 uint8_t *p_DestHmct, uint8_t *p_DestData, bool new) 428 { 429 uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData; 430 uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr; 431 uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData = 432 p_DestData; 433 t_Handle h_FmPcd = p_Manip->h_FmPcd; 434 uint8_t j = 0; 435 436 if (p_FmPcdManipParams->u.hdr.rmv) 437 { 438 if (p_FmPcdManipParams->u.hdr.rmvParams.type 439 == e_FM_PCD_MANIP_RMV_GENERIC) 440 { 441 /* initialize HMCD */ 442 tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT; 443 /* tmp, should be conditional */ 444 tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset 445 << HMCD_RMV_OFFSET_SHIFT; 446 tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size 447 << HMCD_RMV_SIZE_SHIFT; 448 } 449 else 450 if (p_FmPcdManipParams->u.hdr.rmvParams.type 451 == e_FM_PCD_MANIP_RMV_BY_HDR) 452 { 453 switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type) 454 { 455 case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): 456 { 457 uint8_t hmcdOpt; 458 459 /* initialize HMCD */ 460 tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT; 461 462 switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2) 463 { 464 case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET): 465 hmcdOpt = HMCD_RMV_L2_ETHERNET; 466 break; 467 case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS): 468 hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS; 469 break; 470 case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS): 471 hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS; 472 break; 473 case (e_FM_PCD_MANIP_HDR_RMV_MPLS): 474 hmcdOpt = HMCD_RMV_L2_MPLS; 475 break; 476 case (e_FM_PCD_MANIP_HDR_RMV_PPPOE): 477 hmcdOpt = HMCD_RMV_L2_PPPOE; 478 break; 479 default: 480 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); 481 } 482 tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT; 483 break; 484 } 485 #if (DPAA_VERSION >= 11) 486 case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): 487 tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV) 488 << HMCD_OC_SHIFT; 489 break; 490 case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): 491 { 492 uint8_t prsArrayOffset; 493 t_Error err = E_OK; 494 495 tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL) 496 << HMCD_OC_SHIFT; 497 498 err = 499 GetPrOffsetByHeaderOrField( 500 &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo, 501 &prsArrayOffset); 502 ASSERT_COND(!err); 503 /* was previously checked */ 504 505 tmpReg |= ((uint32_t)prsArrayOffset << 16); 506 } 507 break; 508 #endif /* (DPAA_VERSION >= 11) */ 509 default: 510 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, 511 ("manip header remove by hdr type!")); 512 } 513 } 514 515 WRITE_UINT32(*p_TmpHmct, tmpReg); 516 /* save a pointer to the "last" indication word */ 517 p_Last = p_TmpHmct; 518 /* advance to next command */ 519 p_TmpHmct += HMCD_BASIC_SIZE / 4; 520 } 521 522 if (p_FmPcdManipParams->u.hdr.insrt) 523 { 524 if (p_FmPcdManipParams->u.hdr.insrtParams.type 525 == e_FM_PCD_MANIP_INSRT_GENERIC) 526 { 527 /* initialize HMCD */ 528 if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace) 529 tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE) 530 << HMCD_OC_SHIFT; 531 else 532 tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT; 533 534 tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset 535 << HMCD_INSRT_OFFSET_SHIFT; 536 tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size 537 << HMCD_INSRT_SIZE_SHIFT; 538 539 size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size; 540 p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data; 541 542 WRITE_UINT32(*p_TmpHmct, tmpReg); 543 /* save a pointer to the "last" indication word */ 544 p_Last = p_TmpHmct; 545 546 p_TmpHmct += HMCD_BASIC_SIZE / 4; 547 548 /* initialize data to be inserted */ 549 /* if size is not a multiple of 4, padd with 0's */ 550 origSize = size; 551 remain = (uint8_t)(size % 4); 552 if (remain) 553 { 554 size += (uint8_t)(4 - remain); 555 p_LocalData = (uint32_t *)XX_Malloc(size); 556 memset((uint8_t *)p_LocalData, 0, size); 557 memcpy((uint8_t *)p_LocalData, p_UsrData, origSize); 558 } 559 else 560 p_LocalData = (uint32_t*)p_UsrData; 561 562 /* initialize data and advance pointer to next command */ 563 MemCpy8(p_TmpHmct, p_LocalData, size); 564 p_TmpHmct += size / sizeof(uint32_t); 565 566 if (remain) 567 XX_Free(p_LocalData); 568 } 569 570 else 571 if (p_FmPcdManipParams->u.hdr.insrtParams.type 572 == e_FM_PCD_MANIP_INSRT_BY_HDR) 573 { 574 switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type) 575 { 576 case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): 577 { 578 uint8_t hmcdOpt; 579 580 /* initialize HMCD */ 581 tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT) 582 << HMCD_OC_SHIFT; 583 584 switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2) 585 { 586 case (e_FM_PCD_MANIP_HDR_INSRT_MPLS): 587 if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update) 588 hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS; 589 else 590 hmcdOpt = HMCD_INSRT_L2_MPLS; 591 break; 592 case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE): 593 hmcdOpt = HMCD_INSRT_L2_PPPOE; 594 break; 595 default: 596 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); 597 } 598 tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT; 599 600 WRITE_UINT32(*p_TmpHmct, tmpReg); 601 /* save a pointer to the "last" indication word */ 602 p_Last = p_TmpHmct; 603 604 p_TmpHmct += HMCD_BASIC_SIZE / 4; 605 606 /* set size and pointer of user's data */ 607 size = 608 (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size; 609 610 ASSERT_COND(p_TmpData); 611 MemCpy8( 612 p_TmpData, 613 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data, 614 size); 615 tmpReg = 616 (size << HMCD_INSRT_L2_SIZE_SHIFT) 617 | (uint32_t)(XX_VirtToPhys(p_TmpData) 618 - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)); 619 WRITE_UINT32(*p_TmpHmct, tmpReg); 620 p_TmpHmct += HMCD_PTR_SIZE / 4; 621 p_TmpData += size; 622 } 623 break; 624 #if (DPAA_VERSION >= 11) 625 case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): 626 tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT) 627 << HMCD_OC_SHIFT; 628 if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum) 629 tmpReg |= HMCD_IP_L4_CS_CALC; 630 if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode 631 == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS) 632 tmpReg |= HMCD_IP_OR_QOS; 633 tmpReg |= 634 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset 635 & HMCD_IP_LAST_PID_MASK; 636 tmpReg |= 637 ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size 638 << HMCD_IP_SIZE_SHIFT) 639 & HMCD_IP_SIZE_MASK); 640 if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite) 641 tmpReg |= HMCD_IP_DF_MODE; 642 643 WRITE_UINT32(*p_TmpHmct, tmpReg); 644 645 /* save a pointer to the "last" indication word */ 646 p_Last = p_TmpHmct; 647 648 p_TmpHmct += HMCD_BASIC_SIZE / 4; 649 650 /* set IP id */ 651 ASSERT_COND(p_TmpData); 652 WRITE_UINT16( 653 *(uint16_t*)p_TmpData, 654 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id); 655 WRITE_UINT32( 656 *p_TmpHmct, 657 (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); 658 p_TmpData += 2; 659 p_TmpHmct += HMCD_PTR_SIZE / 4; 660 661 WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset); 662 p_TmpHmct += HMCD_PARAM_SIZE / 4; 663 664 MemCpy8( 665 p_TmpHmct, 666 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data, 667 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size); 668 p_TmpHmct += 669 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size 670 / 4; 671 break; 672 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): 673 tmpReg = HMCD_INSRT_UDP_LITE; 674 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): 675 tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT) 676 << HMCD_OC_SHIFT; 677 678 WRITE_UINT32(*p_TmpHmct, tmpReg); 679 680 /* save a pointer to the "last" indication word */ 681 p_Last = p_TmpHmct; 682 683 p_TmpHmct += HMCD_BASIC_SIZE / 4; 684 685 MemCpy8( 686 p_TmpHmct, 687 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data, 688 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); 689 p_TmpHmct += 690 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size 691 / 4; 692 break; 693 case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): 694 tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT) 695 << HMCD_OC_SHIFT; 696 tmpReg |= HMCD_CAPWAP_INSRT; 697 698 WRITE_UINT32(*p_TmpHmct, tmpReg); 699 700 /* save a pointer to the "last" indication word */ 701 p_Last = p_TmpHmct; 702 703 p_TmpHmct += HMCD_BASIC_SIZE / 4; 704 705 MemCpy8( 706 p_TmpHmct, 707 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data, 708 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); 709 p_TmpHmct += 710 p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size 711 / 4; 712 break; 713 #endif /* (DPAA_VERSION >= 11) */ 714 default: 715 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, 716 ("manip header insert by header type!")); 717 718 } 719 } 720 } 721 722 if (p_FmPcdManipParams->u.hdr.fieldUpdate) 723 { 724 switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type) 725 { 726 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN): 727 /* set opcode */ 728 tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE) 729 << HMCD_OC_SHIFT; 730 731 /* set mode & table pointer */ 732 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType 733 == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) 734 { 735 /* set Mode */ 736 tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI) 737 << HMCD_VLAN_PRI_REP_MODE_SHIFT; 738 /* set VPRI default */ 739 tmpReg |= 740 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal; 741 WRITE_UINT32(*p_TmpHmct, tmpReg); 742 /* save a pointer to the "last" indication word */ 743 p_Last = p_TmpHmct; 744 /* write the table pointer into the Manip descriptor */ 745 p_TmpHmct += HMCD_BASIC_SIZE / 4; 746 747 tmpReg = 0; 748 ASSERT_COND(p_TmpData); 749 for (i = 0; i < HMCD_DSCP_VALUES; i++) 750 { 751 /* first we build from each 8 values a 32bit register */ 752 tmpReg |= 753 (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]) 754 << (32 - 4 * (j + 1)); 755 j++; 756 /* Than we write this register to the next table word 757 * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */ 758 if ((i % 8) == 7) 759 { 760 WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1), 761 tmpReg); 762 tmpReg = 0; 763 j = 0; 764 } 765 } 766 767 WRITE_UINT32( 768 *p_TmpHmct, 769 (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase))); 770 p_TmpHmct += HMCD_PTR_SIZE / 4; 771 772 p_TmpData += DSCP_TO_VLAN_TABLE_SIZE; 773 } 774 else 775 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType 776 == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI) 777 { 778 /* set Mode */ 779 /* line commented out as it has no-side-effect ('0' value). */ 780 /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/; 781 /* set VPRI parameter */ 782 tmpReg |= 783 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri; 784 WRITE_UINT32(*p_TmpHmct, tmpReg); 785 /* save a pointer to the "last" indication word */ 786 p_Last = p_TmpHmct; 787 p_TmpHmct += HMCD_BASIC_SIZE / 4; 788 } 789 break; 790 791 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4): 792 /* set opcode */ 793 tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT; 794 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 795 & HDR_MANIP_IPV4_TTL) 796 tmpReg |= HMCD_IPV4_UPDATE_TTL; 797 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 798 & HDR_MANIP_IPV4_TOS) 799 { 800 tmpReg |= HMCD_IPV4_UPDATE_TOS; 801 tmpReg |= 802 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos 803 << HMCD_IPV4_UPDATE_TOS_SHIFT; 804 } 805 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 806 & HDR_MANIP_IPV4_ID) 807 tmpReg |= HMCD_IPV4_UPDATE_ID; 808 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 809 & HDR_MANIP_IPV4_SRC) 810 tmpReg |= HMCD_IPV4_UPDATE_SRC; 811 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 812 & HDR_MANIP_IPV4_DST) 813 tmpReg |= HMCD_IPV4_UPDATE_DST; 814 /* write the first 4 bytes of the descriptor */ 815 WRITE_UINT32(*p_TmpHmct, tmpReg); 816 /* save a pointer to the "last" indication word */ 817 p_Last = p_TmpHmct; 818 819 p_TmpHmct += HMCD_BASIC_SIZE / 4; 820 821 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 822 & HDR_MANIP_IPV4_ID) 823 { 824 ASSERT_COND(p_TmpData); 825 WRITE_UINT16( 826 *(uint16_t*)p_TmpData, 827 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id); 828 WRITE_UINT32( 829 *p_TmpHmct, 830 (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); 831 p_TmpData += 2; 832 p_TmpHmct += HMCD_PTR_SIZE / 4; 833 } 834 835 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 836 & HDR_MANIP_IPV4_SRC) 837 { 838 WRITE_UINT32( 839 *p_TmpHmct, 840 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src); 841 p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4; 842 } 843 844 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates 845 & HDR_MANIP_IPV4_DST) 846 { 847 WRITE_UINT32( 848 *p_TmpHmct, 849 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst); 850 p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4; 851 } 852 break; 853 854 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6): 855 /* set opcode */ 856 tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT; 857 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates 858 & HDR_MANIP_IPV6_HL) 859 tmpReg |= HMCD_IPV6_UPDATE_HL; 860 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates 861 & HDR_MANIP_IPV6_TC) 862 { 863 tmpReg |= HMCD_IPV6_UPDATE_TC; 864 tmpReg |= 865 p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass 866 << HMCD_IPV6_UPDATE_TC_SHIFT; 867 } 868 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates 869 & HDR_MANIP_IPV6_SRC) 870 tmpReg |= HMCD_IPV6_UPDATE_SRC; 871 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates 872 & HDR_MANIP_IPV6_DST) 873 tmpReg |= HMCD_IPV6_UPDATE_DST; 874 /* write the first 4 bytes of the descriptor */ 875 WRITE_UINT32(*p_TmpHmct, tmpReg); 876 /* save a pointer to the "last" indication word */ 877 p_Last = p_TmpHmct; 878 879 p_TmpHmct += HMCD_BASIC_SIZE / 4; 880 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates 881 & HDR_MANIP_IPV6_SRC) 882 { 883 for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4) 884 { 885 memcpy(&tmp_ipv6_addr, 886 &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i], 887 sizeof(uint32_t)); 888 WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr); 889 p_TmpHmct += HMCD_PTR_SIZE / 4; 890 } 891 } 892 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates 893 & HDR_MANIP_IPV6_DST) 894 { 895 for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4) 896 { 897 memcpy(&tmp_ipv6_addr, 898 &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i], 899 sizeof(uint32_t)); 900 WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr); 901 p_TmpHmct += HMCD_PTR_SIZE / 4; 902 } 903 } 904 break; 905 906 case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP): 907 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates 908 == HDR_MANIP_TCP_UDP_CHECKSUM) 909 { 910 /* we implement this case with the update-checksum descriptor */ 911 /* set opcode */ 912 tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM) 913 << HMCD_OC_SHIFT; 914 /* write the first 4 bytes of the descriptor */ 915 WRITE_UINT32(*p_TmpHmct, tmpReg); 916 /* save a pointer to the "last" indication word */ 917 p_Last = p_TmpHmct; 918 919 p_TmpHmct += HMCD_BASIC_SIZE / 4; 920 } 921 else 922 { 923 /* we implement this case with the TCP/UDP update descriptor */ 924 /* set opcode */ 925 tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE) 926 << HMCD_OC_SHIFT; 927 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates 928 & HDR_MANIP_TCP_UDP_DST) 929 tmpReg |= HMCD_TCP_UDP_UPDATE_DST; 930 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates 931 & HDR_MANIP_TCP_UDP_SRC) 932 tmpReg |= HMCD_TCP_UDP_UPDATE_SRC; 933 /* write the first 4 bytes of the descriptor */ 934 WRITE_UINT32(*p_TmpHmct, tmpReg); 935 /* save a pointer to the "last" indication word */ 936 p_Last = p_TmpHmct; 937 938 p_TmpHmct += HMCD_BASIC_SIZE / 4; 939 940 tmpReg = 0; 941 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates 942 & HDR_MANIP_TCP_UDP_SRC) 943 tmpReg |= 944 ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src) 945 << HMCD_TCP_UDP_UPDATE_SRC_SHIFT; 946 if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates 947 & HDR_MANIP_TCP_UDP_DST) 948 tmpReg |= 949 ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst); 950 WRITE_UINT32(*p_TmpHmct, tmpReg); 951 p_TmpHmct += HMCD_PTR_SIZE / 4; 952 } 953 break; 954 955 default: 956 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 957 ("Unknown fieldUpdateParams.type")); 958 } 959 } 960 961 if (p_FmPcdManipParams->u.hdr.custom) 962 { 963 switch (p_FmPcdManipParams->u.hdr.customParams.type) 964 { 965 case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE): 966 /* set opcode */ 967 tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT; 968 969 if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl) 970 tmpReg |= HMCD_IP_REPLACE_TTL_HL; 971 if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType 972 == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6) 973 /* line commented out as it has no-side-effect ('0' value). */ 974 /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/; 975 else 976 if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType 977 == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) 978 { 979 tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6; 980 if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id) 981 tmpReg |= HMCD_IP_REPLACE_ID; 982 } 983 else 984 RETURN_ERROR( 985 MINOR, 986 E_NOT_SUPPORTED, 987 ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set.")); 988 989 /* write the first 4 bytes of the descriptor */ 990 WRITE_UINT32(*p_TmpHmct, tmpReg); 991 /* save a pointer to the "last" indication word */ 992 p_Last = p_TmpHmct; 993 994 p_TmpHmct += HMCD_BASIC_SIZE / 4; 995 996 size = 997 p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize; 998 ASSERT_COND(p_TmpData); 999 MemCpy8( 1000 p_TmpData, 1001 p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr, 1002 size); 1003 tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT); 1004 tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData) 1005 - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)); 1006 WRITE_UINT32(*p_TmpHmct, tmpReg); 1007 p_TmpHmct += HMCD_PTR_SIZE / 4; 1008 p_TmpData += size; 1009 1010 if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType 1011 == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) 1012 && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)) 1013 { 1014 WRITE_UINT16( 1015 *(uint16_t*)p_TmpData, 1016 p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id); 1017 WRITE_UINT32( 1018 *p_TmpHmct, 1019 (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase))); 1020 p_TmpData += 2; 1021 } 1022 p_TmpHmct += HMCD_PTR_SIZE / 4; 1023 break; 1024 case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE): 1025 /* set opcode */ 1026 tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT; 1027 tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT; 1028 tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT; 1029 tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT; 1030 if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask) 1031 tmpReg |= HMCD_GEN_FIELD_MASK_EN; 1032 1033 /* write the first 4 bytes of the descriptor */ 1034 WRITE_UINT32(*p_TmpHmct, tmpReg); 1035 /* save a pointer to the "last" indication word */ 1036 p_Last = p_TmpHmct; 1037 1038 p_TmpHmct += HMCD_BASIC_SIZE/4; 1039 1040 if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask) 1041 { 1042 tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT; 1043 tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT; 1044 /* write the next 4 bytes of the descriptor */ 1045 WRITE_UINT32(*p_TmpHmct, tmpReg); 1046 } 1047 p_TmpHmct += HMCD_PARAM_SIZE/4; 1048 break; 1049 default: 1050 RETURN_ERROR(MINOR, E_INVALID_SELECTION, 1051 ("Unknown customParams.type")); 1052 } 1053 } 1054 1055 /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table 1056 the old table and should be freed */ 1057 if (p_FmPcdManipParams->h_NextManip 1058 && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) 1059 && (MANIP_DONT_REPARSE(p_Manip))) 1060 { 1061 if (new) 1062 { 1063 /* If this is the first time this manip is created we need to free unused memory. If it 1064 * is a dynamic changes case, the memory used is either the CC shadow or the existing 1065 * table - no allocation, no free */ 1066 MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip); 1067 1068 p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST; 1069 } 1070 } 1071 else 1072 { 1073 ASSERT_COND(p_Last); 1074 /* set the "last" indication on the last command of the current table */ 1075 WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST); 1076 } 1077 1078 return E_OK; 1079 } 1080 1081 static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip, 1082 t_FmPcdManipParams *p_FmPcdManipParams) 1083 { 1084 t_FmPcdManip *p_CurManip; 1085 t_Error err; 1086 uint32_t nextSize = 0, totalSize; 1087 uint16_t tmpReg; 1088 uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr; 1089 1090 /* set Manip structure */ 1091 1092 p_Manip->dontParseAfterManip = 1093 p_FmPcdManipParams->u.hdr.dontParseAfterManip; 1094 1095 if (p_FmPcdManipParams->h_NextManip) 1096 { /* Next Header manipulation exists */ 1097 p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip); 1098 1099 if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip) 1100 nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip) 1101 + GetDataSize(p_FmPcdManipParams->h_NextManip)); 1102 else /* either parsing is required or next manip is Frag; no table merging. */ 1103 p_Manip->cascaded = TRUE; 1104 /* pass up the "cascaded" attribute. The whole chain is cascaded 1105 * if something is cascaded along the way. */ 1106 if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip)) 1107 p_Manip->cascaded = TRUE; 1108 } 1109 1110 /* Allocate new table */ 1111 /* calculate table size according to manip parameters */ 1112 err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize, 1113 &p_Manip->dataSize); 1114 if (err) 1115 RETURN_ERROR(MINOR, err, NO_MSG); 1116 1117 totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize); 1118 1119 p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem( 1120 ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4); 1121 if (!p_Manip->p_Hmct) 1122 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed")); 1123 1124 if (p_Manip->dataSize) 1125 p_Manip->p_Data = 1126 (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize)); 1127 1128 /* update shadow size to allow runtime replacement of Header manipulation */ 1129 /* The allocated shadow is divided as follows: 1130 0 . . . 16 . . . 1131 -------------------------------- 1132 | Shadow | Shadow HMTD | 1133 | HMTD | Match Table | 1134 | (16 bytes) | (maximal size) | 1135 -------------------------------- 1136 */ 1137 1138 err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16), 1139 (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN); 1140 if (err != E_OK) 1141 { 1142 FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct); 1143 RETURN_ERROR(MAJOR, E_NO_MEMORY, 1144 ("MURAM allocation for HdrManip node shadow")); 1145 } 1146 1147 if (p_FmPcdManipParams->h_NextManip 1148 && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) 1149 && (MANIP_DONT_REPARSE(p_Manip))) 1150 { 1151 p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip, 1152 e_MANIP_HMCT); 1153 p_CurManip = p_FmPcdManipParams->h_NextManip; 1154 /* Run till the last Manip (which is the first to configure) */ 1155 while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) 1156 p_CurManip = p_CurManip->h_NextManip; 1157 1158 while (p_CurManip) 1159 { 1160 /* If this is a unified table, point to the part of the table 1161 * which is the relative offset in HMCT. 1162 */ 1163 p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, 1164 (p_Manip->tableSize + 1165 (PTR_TO_UINT(p_CurManip->p_Hmct) - 1166 PTR_TO_UINT(p_OldHmct)))); 1167 if (p_CurManip->p_Data) 1168 p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, 1169 (p_Manip->tableSize + 1170 (PTR_TO_UINT(p_CurManip->p_Data) - 1171 PTR_TO_UINT(p_OldHmct)))); 1172 else 1173 p_TmpDataPtr = NULL; 1174 1175 BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, 1176 p_TmpDataPtr, FALSE); 1177 /* update old manip table pointer */ 1178 MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr); 1179 MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr); 1180 1181 p_CurManip = p_CurManip->h_PrevManip; 1182 } 1183 /* We copied the HMCT to create a new large HMCT so we can free the old one */ 1184 FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip), 1185 p_OldHmct); 1186 } 1187 1188 /* Fill table */ 1189 err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, 1190 p_Manip->p_Data, TRUE); 1191 if (err) 1192 { 1193 FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct); 1194 RETURN_ERROR(MINOR, err, NO_MSG); 1195 } 1196 1197 /* Build HMTD (table descriptor) */ 1198 tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */ 1199 1200 /* add parseAfterManip */ 1201 if (!p_Manip->dontParseAfterManip) 1202 tmpReg |= HMTD_CFG_PRS_AFTER_HM; 1203 1204 /* create cascade */ 1205 /*if (p_FmPcdManipParams->h_NextManip 1206 && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/ 1207 if (p_Manip->cascaded) 1208 { 1209 uint16_t nextAd; 1210 /* indicate that there's another HM table descriptor */ 1211 tmpReg |= HMTD_CFG_NEXT_AD_EN; 1212 /* get address of next HMTD (table descriptor; h_Ad). 1213 * If the next HMTD was removed due to table unifing, get the address 1214 * of the "next next" as written in the h_Ad of the next h_Manip node. 1215 */ 1216 if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST) 1217 nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4); 1218 else 1219 nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx; 1220 1221 WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd); 1222 } 1223 1224 WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg); 1225 WRITE_UINT32( 1226 ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr, 1227 (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); 1228 1229 WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC); 1230 1231 if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST) 1232 { 1233 /* The HMTD of the next Manip is never going to be used */ 1234 if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate) 1235 FM_MURAM_FreeMem( 1236 ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram, 1237 ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad); 1238 else 1239 XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad); 1240 ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL; 1241 } 1242 1243 return E_OK; 1244 } 1245 1246 static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip, 1247 t_FmPcdManipParams *p_FmPcdManipParams) 1248 { 1249 uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL; 1250 uint16_t newSize; 1251 t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; 1252 t_Error err; 1253 t_FmPcdManip *p_CurManip = p_Manip; 1254 1255 err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize); 1256 if (err) 1257 RETURN_ERROR(MINOR, err, NO_MSG); 1258 1259 /* check coherency of new table parameters */ 1260 if (newSize > p_Manip->tableSize) 1261 RETURN_ERROR( 1262 MINOR, 1263 E_INVALID_VALUE, 1264 ("New Hdr Manip configuration requires larger size than current one (command table).")); 1265 if (newDataSize > p_Manip->dataSize) 1266 RETURN_ERROR( 1267 MINOR, 1268 E_INVALID_VALUE, 1269 ("New Hdr Manip configuration requires larger size than current one (data).")); 1270 if (p_FmPcdManipParams->h_NextManip) 1271 RETURN_ERROR( 1272 MINOR, E_INVALID_VALUE, 1273 ("New Hdr Manip configuration can not contain h_NextManip.")); 1274 if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize)) 1275 RETURN_ERROR( 1276 MINOR, 1277 E_INVALID_VALUE, 1278 ("New Hdr Manip configuration in a chained manipulation requires different size than current one.")); 1279 if (p_Manip->dontParseAfterManip 1280 != p_FmPcdManipParams->u.hdr.dontParseAfterManip) 1281 RETURN_ERROR( 1282 MINOR, 1283 E_INVALID_VALUE, 1284 ("New Hdr Manip configuration differs in dontParseAfterManip value.")); 1285 1286 p_Manip->tableSize = newSize; 1287 p_Manip->dataSize = newDataSize; 1288 1289 /* Build the new table in the shadow */ 1290 if (!MANIP_IS_UNIFIED(p_Manip)) 1291 { 1292 p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16); 1293 if (p_Manip->p_Data) 1294 p_TmpDataPtr = 1295 (uint8_t*)PTR_MOVE(p_TmpHmctPtr, 1296 (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct))); 1297 1298 BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data, 1299 FALSE); 1300 } 1301 else 1302 { 1303 p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); 1304 ASSERT_COND(p_WholeHmct); 1305 1306 /* Run till the last Manip (which is the first to configure) */ 1307 while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) 1308 p_CurManip = p_CurManip->h_NextManip; 1309 1310 while (p_CurManip) 1311 { 1312 /* If this is a non-head node in a unified table, point to the part of the shadow 1313 * which is the relative offset in HMCT. 1314 * else, point to the beginning of the 1315 * shadow table (we save 16 for the HMTD. 1316 */ 1317 p_TmpHmctPtr = 1318 (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 1319 (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct))); 1320 if (p_CurManip->p_Data) 1321 p_TmpDataPtr = 1322 (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 1323 (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct))); 1324 1325 BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, 1326 p_TmpDataPtr, FALSE); 1327 p_CurManip = p_CurManip->h_PrevManip; 1328 } 1329 } 1330 1331 return E_OK; 1332 } 1333 1334 static t_Error CreateManipActionBackToOrig( 1335 t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams) 1336 { 1337 uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr; 1338 t_FmPcdManip *p_CurManip = p_Manip; 1339 1340 /* Build the new table in the shadow */ 1341 if (!MANIP_IS_UNIFIED(p_Manip)) 1342 BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data, 1343 FALSE); 1344 else 1345 { 1346 p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); 1347 ASSERT_COND(p_WholeHmct); 1348 1349 /* Run till the last Manip (which is the first to configure) */ 1350 while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) 1351 p_CurManip = p_CurManip->h_NextManip; 1352 1353 while (p_CurManip) 1354 { 1355 /* If this is a unified table, point to the part of the table 1356 * which is the relative offset in HMCT. 1357 */ 1358 p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/ 1359 p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/ 1360 1361 BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, 1362 p_TmpDataPtr, FALSE); 1363 1364 p_CurManip = p_CurManip->h_PrevManip; 1365 } 1366 } 1367 1368 return E_OK; 1369 } 1370 1371 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 1372 static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset) 1373 { 1374 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 1375 t_Handle p_Ad; 1376 uint32_t tmpReg32 = 0; 1377 SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); 1378 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); 1379 1380 switch (p_Manip->opcode) 1381 { 1382 case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): 1383 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 1384 if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) 1385 { 1386 tmpReg32 = 1387 *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets; 1388 tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); 1389 *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets = 1390 tmpReg32; 1391 p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET; 1392 p_Manip->icOffset = icOffset; 1393 } 1394 else 1395 { 1396 if (p_Manip->icOffset != icOffset) 1397 RETURN_ERROR( 1398 MAJOR, 1399 E_INVALID_VALUE, 1400 ("this manipulation was updated previously by different value");); 1401 } 1402 break; 1403 case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): 1404 if (p_Manip->h_Frag) 1405 { 1406 if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) 1407 { 1408 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 1409 tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets); 1410 tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); 1411 WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32); 1412 p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET; 1413 p_Manip->icOffset = icOffset; 1414 } 1415 else 1416 { 1417 if (p_Manip->icOffset != icOffset) 1418 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value");); 1419 } 1420 } 1421 break; 1422 } 1423 1424 return E_OK; 1425 } 1426 1427 static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix( 1428 t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate) 1429 { 1430 1431 t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; 1432 t_FmPortGetSetCcParams fmPortGetSetCcParams; 1433 t_Error err; 1434 uint32_t tmpReg32; 1435 1436 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); 1437 1438 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 1439 SANITY_CHECK_RETURN_ERROR( 1440 (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX), 1441 E_INVALID_STATE); 1442 SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE); 1443 1444 if (p_Manip->updateParams) 1445 { 1446 if ((!(p_Manip->updateParams & OFFSET_OF_PR)) 1447 || (p_Manip->shadowUpdateParams & OFFSET_OF_PR)) 1448 RETURN_ERROR( 1449 MAJOR, E_INVALID_STATE, 1450 ("in this stage parameters from Port has not be updated")); 1451 1452 fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; 1453 fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO; 1454 fmPortGetSetCcParams.setCcParams.psoSize = 16; 1455 1456 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 1457 if (err) 1458 RETURN_ERROR(MAJOR, err, NO_MSG); 1459 if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) 1460 RETURN_ERROR( 1461 MAJOR, E_INVALID_STATE, 1462 ("Parser result offset wasn't configured previousely")); 1463 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 1464 ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16)); 1465 #endif 1466 } 1467 else 1468 if (validate) 1469 { 1470 if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) 1471 || (p_Manip->updateParams & OFFSET_OF_PR)) 1472 RETURN_ERROR( 1473 MAJOR, E_INVALID_STATE, 1474 ("in this stage parameters from Port has be updated")); 1475 fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; 1476 fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO; 1477 fmPortGetSetCcParams.setCcParams.psoSize = 16; 1478 1479 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 1480 if (err) 1481 RETURN_ERROR(MAJOR, err, NO_MSG); 1482 if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) 1483 RETURN_ERROR( 1484 MAJOR, E_INVALID_STATE, 1485 ("Parser result offset wasn't configured previousely")); 1486 1487 } 1488 1489 ASSERT_COND(p_Ad); 1490 1491 if (p_Manip->updateParams & OFFSET_OF_PR) 1492 { 1493 tmpReg32 = 0; 1494 tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset; 1495 WRITE_UINT32(p_Ad->matchTblPtr, 1496 (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32)); 1497 p_Manip->updateParams &= ~OFFSET_OF_PR; 1498 p_Manip->shadowUpdateParams |= OFFSET_OF_PR; 1499 } 1500 else 1501 if (validate) 1502 { 1503 tmpReg32 = GET_UINT32(p_Ad->matchTblPtr); 1504 if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset) 1505 RETURN_ERROR( 1506 MAJOR, 1507 E_INVALID_STATE, 1508 ("this manipulation was updated previousely by different value");); 1509 } 1510 1511 return E_OK; 1512 } 1513 1514 static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree) 1515 { 1516 t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; 1517 t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL; 1518 uint32_t tmpReg32 = 0; 1519 1520 SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); 1521 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); 1522 SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE); 1523 SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); 1524 1525 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; 1526 1527 if (p_Manip->updateParams) 1528 { 1529 1530 if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) || 1531 ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA))) 1532 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); 1533 p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree); 1534 if (!p_SavedManipParams) 1535 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); 1536 p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset; 1537 1538 tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets); 1539 tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16); 1540 WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32); 1541 1542 p_Manip->updateParams &= ~OFFSET_OF_DATA; 1543 p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; 1544 } 1545 else if (validate) 1546 { 1547 1548 p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree); 1549 if (!p_SavedManipParams) 1550 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); 1551 if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset) 1552 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); 1553 } 1554 1555 return E_OK; 1556 } 1557 1558 static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort, 1559 t_FmPcdManip *p_Manip, 1560 t_Handle h_Ad, 1561 bool validate, 1562 t_Handle h_FmTree) 1563 { 1564 t_AdOfTypeContLookup *p_Ad; 1565 t_FmPortGetSetCcParams fmPortGetSetCcParams; 1566 t_Error err; 1567 uint32_t tmpReg32 = 0; 1568 t_FmPcdCcSavedManipParams *p_SavedManipParams; 1569 1570 UNUSED(h_Ad); 1571 1572 SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); 1573 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); 1574 SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE); 1575 SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || 1576 (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); 1577 1578 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; 1579 1580 if (p_Manip->updateParams) 1581 { 1582 if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) || 1583 ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA))) 1584 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); 1585 fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; 1586 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; 1587 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; 1588 /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */ 1589 fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1; 1590 1591 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 1592 if (err) 1593 RETURN_ERROR(MAJOR, err, NO_MSG); 1594 1595 if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) 1596 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); 1597 1598 p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams)); 1599 p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; 1600 1601 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 1602 ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16)); 1603 #endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ 1604 1605 FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams); 1606 } 1607 else if (validate) 1608 { 1609 if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) || 1610 ((p_Manip->updateParams & OFFSET_OF_DATA))) 1611 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); 1612 fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; 1613 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; 1614 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; 1615 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 1616 if (err) 1617 RETURN_ERROR(MAJOR, err, NO_MSG); 1618 1619 if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) 1620 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); 1621 } 1622 1623 if (p_Manip->updateParams) 1624 { 1625 tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets); 1626 tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16); 1627 WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32); 1628 1629 p_Manip->updateParams &= ~OFFSET_OF_DATA; 1630 p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; 1631 p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; 1632 } 1633 else if (validate) 1634 { 1635 if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset) 1636 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); 1637 } 1638 1639 return E_OK; 1640 } 1641 1642 static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd, 1643 t_Handle h_FmPort, 1644 t_FmPcdManip *p_Manip, 1645 t_Handle h_Ad, 1646 bool validate) 1647 { 1648 t_CapwapReasmPram *p_ReassmTbl; 1649 t_Error err; 1650 t_FmPortGetSetCcParams fmPortGetSetCcParams; 1651 uint8_t i = 0; 1652 uint16_t size; 1653 uint32_t tmpReg32; 1654 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1655 t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams; 1656 1657 SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); 1658 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); 1659 SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE); 1660 SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE); 1661 SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE); 1662 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE); 1663 1664 if (p_Manip->h_FmPcd != h_FmPcd) 1665 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1666 ("handler of PCD previously was initiated by different value")); 1667 1668 UNUSED(h_Ad); 1669 1670 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); 1671 p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag; 1672 1673 if (p_Manip->updateParams) 1674 { 1675 if ((!(p_Manip->updateParams & NUM_OF_TASKS) && 1676 !(p_Manip->updateParams & OFFSET_OF_DATA) && 1677 !(p_Manip->updateParams & OFFSET_OF_PR) && 1678 !(p_Manip->updateParams & HW_PORT_ID)) || 1679 ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || 1680 (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) || 1681 (p_Manip->shadowUpdateParams & HW_PORT_ID))) 1682 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); 1683 1684 fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; 1685 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; 1686 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; 1687 1688 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 1689 if (err) 1690 RETURN_ERROR(MAJOR, err, NO_MSG); 1691 1692 if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) 1693 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely")); 1694 if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) 1695 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely")); 1696 if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) 1697 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); 1698 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 1699 ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0); 1700 #endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ 1701 } 1702 else if (validate) 1703 { 1704 if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && 1705 !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) && 1706 !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) && 1707 !(p_Manip->shadowUpdateParams & HW_PORT_ID)) && 1708 ((p_Manip->updateParams & NUM_OF_TASKS) || 1709 (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) || 1710 (p_Manip->updateParams & HW_PORT_ID))) 1711 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); 1712 1713 fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; 1714 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; 1715 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; 1716 1717 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 1718 if (err) 1719 RETURN_ERROR(MAJOR, err, NO_MSG); 1720 1721 if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) 1722 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously")); 1723 if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) 1724 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously")); 1725 if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) 1726 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); 1727 } 1728 1729 if (p_Manip->updateParams) 1730 { 1731 if (p_Manip->updateParams & NUM_OF_TASKS) 1732 { 1733 /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */ 1734 size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks); 1735 if (size > 255) 1736 RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256")); 1737 1738 p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks; 1739 1740 /*p_ReassmFrmDescrIndxPoolTbl*/ 1741 p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl = 1742 (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 1743 (uint32_t)(size + 1), 1744 4); 1745 if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) 1746 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table")); 1747 1748 MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1)); 1749 1750 for ( i = 0; i < size; i++) 1751 WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1)); 1752 1753 tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase); 1754 1755 WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32); 1756 1757 /*p_ReassmFrmDescrPoolTbl*/ 1758 p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl = 1759 (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 1760 (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE), 1761 4); 1762 1763 if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) 1764 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table")); 1765 1766 MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE)); 1767 1768 tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase); 1769 1770 WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32); 1771 1772 /*p_TimeOutTbl*/ 1773 1774 p_Manip->capwapFragParams.p_TimeOutTbl = 1775 (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 1776 (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE), 1777 4); 1778 1779 if (!p_Manip->capwapFragParams.p_TimeOutTbl) 1780 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table")); 1781 1782 MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE)); 1783 1784 tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase); 1785 WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32); 1786 1787 p_Manip->updateParams &= ~NUM_OF_TASKS; 1788 p_Manip->shadowUpdateParams |= NUM_OF_TASKS; 1789 } 1790 1791 if (p_Manip->updateParams & OFFSET_OF_DATA) 1792 { 1793 p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; 1794 tmpReg32 = GET_UINT32(p_ReassmTbl->mode); 1795 tmpReg32|= p_Manip->capwapFragParams.dataOffset; 1796 WRITE_UINT32(p_ReassmTbl->mode, tmpReg32); 1797 p_Manip->updateParams &= ~OFFSET_OF_DATA; 1798 p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; 1799 } 1800 1801 if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) 1802 { 1803 p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset; 1804 1805 tmpReg32 = GET_UINT32(p_ReassmTbl->mode); 1806 tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY; 1807 WRITE_UINT32(p_ReassmTbl->mode, tmpReg32); 1808 1809 tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr); 1810 tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24; 1811 WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32); 1812 p_Manip->updateParams &= ~OFFSET_OF_PR; 1813 p_Manip->shadowUpdateParams |= OFFSET_OF_PR; 1814 } 1815 else 1816 { 1817 p_Manip->capwapFragParams.prOffset = 0xff; 1818 p_Manip->updateParams &= ~OFFSET_OF_PR; 1819 p_Manip->shadowUpdateParams |= OFFSET_OF_PR; 1820 } 1821 1822 p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId; 1823 p_Manip->updateParams &= ~HW_PORT_ID; 1824 p_Manip->shadowUpdateParams |= HW_PORT_ID; 1825 1826 /*timeout hc */ 1827 ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames; 1828 ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24; 1829 ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase)); 1830 ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2; 1831 return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams); 1832 } 1833 1834 else if (validate) 1835 { 1836 if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId) 1837 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port")); 1838 if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks) 1839 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value ")); 1840 1841 if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) 1842 { 1843 if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset) 1844 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); 1845 } 1846 else 1847 { 1848 if (p_Manip->capwapFragParams.prOffset != 0xff) 1849 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); 1850 } 1851 if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset) 1852 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value ")); 1853 } 1854 1855 return E_OK; 1856 } 1857 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 1858 1859 t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl) 1860 { 1861 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1862 t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 }; 1863 t_Error err = E_OK; 1864 uint8_t result; 1865 uint32_t bitFor1Micro, tsbs, log2num; 1866 1867 ASSERT_COND(p_FmPcd); 1868 ASSERT_COND(h_ReasmCommonPramTbl); 1869 1870 bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); 1871 if (bitFor1Micro == 0) 1872 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); 1873 1874 bitFor1Micro = 32 - bitFor1Micro; 1875 LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num); 1876 tsbs = bitFor1Micro - log2num; 1877 1878 ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys( 1879 h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); 1880 ccReassmTimeoutParams.tsbs = (uint8_t)tsbs; 1881 ccReassmTimeoutParams.activate = TRUE; 1882 if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, 1883 &result)) != E_OK) 1884 RETURN_ERROR(MAJOR, err, NO_MSG); 1885 1886 switch (result) 1887 { 1888 case (0): 1889 return E_OK; 1890 case (1): 1891 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM")); 1892 case (2): 1893 RETURN_ERROR( 1894 MAJOR, E_NO_MEMORY, 1895 ("failed to allocate internal buffer from the HC-Port")); 1896 case (3): 1897 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1898 ("'Disable Timeout Task' with invalid IPRCPT")); 1899 case (4): 1900 RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks")); 1901 case (5): 1902 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command")); 1903 default: 1904 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); 1905 } 1906 return E_OK; 1907 } 1908 1909 static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip) 1910 { 1911 uint32_t tmpReg32 = 0, i, bitFor1Micro; 1912 uint64_t tmpReg64, size; 1913 t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; 1914 t_Error err = E_OK; 1915 1916 bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); 1917 if (bitFor1Micro == 0) 1918 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); 1919 1920 /* Allocation of the Reassembly Common Parameters table. This table is located in the 1921 MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */ 1922 p_Manip->reassmParams.p_ReassCommonTbl = 1923 (t_ReassCommonTbl *)FM_MURAM_AllocMem( 1924 p_FmPcd->h_FmMuram, 1925 FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE, 1926 FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN); 1927 1928 if (!p_Manip->reassmParams.p_ReassCommonTbl) 1929 RETURN_ERROR(MAJOR, E_NO_MEMORY, 1930 ("MURAM alloc for Reassembly common parameters table")); 1931 1932 MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0, 1933 FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE); 1934 1935 /* Setting the TimeOut Mode.*/ 1936 tmpReg32 = 0; 1937 if (p_Manip->reassmParams.timeOutMode 1938 == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) 1939 tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES; 1940 1941 /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID. 1942 In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/ 1943 tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames; 1944 WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid, 1945 tmpReg32); 1946 1947 /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/ 1948 size = p_Manip->reassmParams.maxNumFramesInProcess + 129; 1949 1950 /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */ 1951 p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr = 1952 PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 1953 (uint32_t)(size * 2), 1954 256)); 1955 if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr) 1956 RETURN_ERROR( 1957 MAJOR, E_NO_MEMORY, 1958 ("MURAM alloc for Reassembly frame descriptor indexes pool")); 1959 1960 MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), 1961 0, (uint32_t)(size * 2)); 1962 1963 /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to 1964 the maximum number of frames that are allowed to be reassembled simultaneously + 128. 1965 The last entry in this pool must contain the index zero*/ 1966 for (i = 0; i < (size - 1); i++) 1967 WRITE_UINT16( 1968 *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)), 1969 (uint16_t)(i+1)); 1970 1971 /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */ 1972 tmpReg32 = (uint32_t)(XX_VirtToPhys( 1973 UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)) 1974 - p_FmPcd->physicalMuramBase); 1975 WRITE_UINT32( 1976 p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr, 1977 tmpReg32); 1978 1979 /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory. 1980 The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/ 1981 p_Manip->reassmParams.reassFrmDescrPoolTblAddr = 1982 PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64)); 1983 1984 if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr) 1985 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); 1986 1987 MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0, 1988 (uint32_t)(size * 64)); 1989 1990 /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/ 1991 tmpReg64 = (uint64_t)(XX_VirtToPhys( 1992 UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr))); 1993 tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset 1994 & FM_PCD_MANIP_REASM_LIODN_MASK) 1995 << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); 1996 tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset 1997 & FM_PCD_MANIP_REASM_ELIODN_MASK) 1998 << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); 1999 WRITE_UINT32( 2000 p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi, 2001 (uint32_t)(tmpReg64 >> 32)); 2002 WRITE_UINT32( 2003 p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow, 2004 (uint32_t)tmpReg64); 2005 2006 /*Allocation of the TimeOut table - This table resides in the MURAM. 2007 The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/ 2008 p_Manip->reassmParams.timeOutTblAddr = 2009 PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8)); 2010 2011 if (!p_Manip->reassmParams.timeOutTblAddr) 2012 RETURN_ERROR(MAJOR, E_NO_MEMORY, 2013 ("MURAM alloc for Reassembly timeout table")); 2014 2015 MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0, 2016 (uint16_t)(size * 8)); 2017 2018 /* Sets the TimeOut table offset from MURAM */ 2019 tmpReg32 = (uint32_t)(XX_VirtToPhys( 2020 UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr)) 2021 - p_FmPcd->physicalMuramBase); 2022 WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr, 2023 tmpReg32); 2024 2025 /* Sets the Expiration Delay */ 2026 tmpReg32 = 0; 2027 tmpReg32 |= (((uint32_t)(1 << bitFor1Micro)) 2028 * p_Manip->reassmParams.timeoutThresholdForReassmProcess); 2029 WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay, 2030 tmpReg32); 2031 2032 err = FmPcdRegisterReassmPort(p_FmPcd, 2033 p_Manip->reassmParams.p_ReassCommonTbl); 2034 if (err != E_OK) 2035 { 2036 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2037 p_Manip->reassmParams.p_ReassCommonTbl); 2038 RETURN_ERROR(MAJOR, err, ("port registration")); 2039 } 2040 2041 return err; 2042 } 2043 2044 static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr) 2045 { 2046 t_FmPcd *p_FmPcd = p_Manip->h_FmPcd; 2047 uint32_t tmpReg32, autoLearnHashTblSize; 2048 uint32_t numOfWays, setSize, setSizeCode, keySize; 2049 uint32_t waySize, numOfSets, numOfEntries; 2050 uint64_t tmpReg64; 2051 uint16_t minFragSize; 2052 uint16_t maxReassemSize; 2053 uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr; 2054 t_ReassTbl **p_ReassTbl; 2055 2056 switch (hdr) 2057 { 2058 case HEADER_TYPE_IPv4: 2059 p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl; 2060 p_AutoLearnHashTblAddr = 2061 &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr; 2062 p_AutoLearnSetLockTblAddr = 2063 &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr; 2064 minFragSize = p_Manip->reassmParams.ip.minFragSize[0]; 2065 maxReassemSize = 0; 2066 numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0]; 2067 keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */ 2068 break; 2069 case HEADER_TYPE_IPv6: 2070 p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl; 2071 p_AutoLearnHashTblAddr = 2072 &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr; 2073 p_AutoLearnSetLockTblAddr = 2074 &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr; 2075 minFragSize = p_Manip->reassmParams.ip.minFragSize[1]; 2076 maxReassemSize = 0; 2077 numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1]; 2078 keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */ 2079 if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH) 2080 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways")); 2081 break; 2082 case HEADER_TYPE_CAPWAP: 2083 p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl; 2084 p_AutoLearnHashTblAddr = 2085 &p_Manip->reassmParams.capwap.autoLearnHashTblAddr; 2086 p_AutoLearnSetLockTblAddr = 2087 &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr; 2088 minFragSize = 0; 2089 maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize; 2090 numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry; 2091 keySize = 4; 2092 break; 2093 default: 2094 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type")); 2095 } 2096 keySize += 2; /* 2 bytes reserved for RFDIndex */ 2097 #if (DPAA_VERSION >= 11) 2098 keySize += 2; /* 2 bytes reserved */ 2099 #endif /* (DPAA_VERSION >= 11) */ 2100 waySize = ROUND_UP(keySize, 8); 2101 2102 /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/ 2103 *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem( 2104 p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE, 2105 FM_PCD_MANIP_REASM_TABLE_ALIGN); 2106 if (!*p_ReassTbl) 2107 RETURN_ERROR( MAJOR, E_NO_MEMORY, 2108 ("MURAM alloc for Reassembly specific parameters table")); 2109 memset(*p_ReassTbl, 0, sizeof(t_ReassTbl)); 2110 2111 /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/ 2112 tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl) 2113 - p_FmPcd->physicalMuramBase); 2114 WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32); 2115 2116 /* Calculate set size (set size is rounded-up to next power of 2) */ 2117 NEXT_POWER_OF_2(numOfWays * waySize, setSize); 2118 2119 /* Get set size code */ 2120 LOG2(setSize, setSizeCode); 2121 2122 /* Sets ways number and set size code */ 2123 WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize, 2124 (uint16_t)((numOfWays << 8) | setSizeCode)); 2125 2126 /* It is recommended that the total number of entries in this table 2127 (number of sets * number of ways) will be twice the number of frames that 2128 are expected to be reassembled simultaneously.*/ 2129 numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2); 2130 2131 /* sets number calculation - number of entries = number of sets * number of ways */ 2132 numOfSets = numOfEntries / numOfWays; 2133 2134 /* Sets AutoLearnHashKeyMask*/ 2135 NEXT_POWER_OF_2(numOfSets, numOfSets); 2136 2137 WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask, 2138 (uint16_t)(numOfSets - 1)); 2139 2140 /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory. 2141 The size of this table is determined by the number of sets and the set size. 2142 Table size = set size * number of sets 2143 This table base address should be aligned to SetSize.*/ 2144 autoLearnHashTblSize = numOfSets * setSize; 2145 2146 *p_AutoLearnHashTblAddr = 2147 PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize)); 2148 if (!*p_AutoLearnHashTblAddr) 2149 { 2150 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl); 2151 *p_ReassTbl = NULL; 2152 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); 2153 } 2154 MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize); 2155 2156 /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */ 2157 tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset 2158 & FM_PCD_MANIP_REASM_LIODN_MASK) 2159 << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); 2160 tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset 2161 & FM_PCD_MANIP_REASM_ELIODN_MASK) 2162 << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); 2163 tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); 2164 WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi, 2165 (uint32_t)(tmpReg64 >> 32)); 2166 WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64); 2167 2168 /* Allocation of the Set Lock table - This table resides in external memory 2169 The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes. 2170 This table resides in external memory and its base address should be 4-byte aligned */ 2171 *p_AutoLearnSetLockTblAddr = 2172 PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4)); 2173 if (!*p_AutoLearnSetLockTblAddr) 2174 { 2175 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl); 2176 *p_ReassTbl = NULL; 2177 XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); 2178 *p_AutoLearnHashTblAddr = 0; 2179 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); 2180 } 2181 MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4)); 2182 2183 /* sets Set Lock table pointer and liodn offset*/ 2184 tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset 2185 & FM_PCD_MANIP_REASM_LIODN_MASK) 2186 << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); 2187 tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset 2188 & FM_PCD_MANIP_REASM_ELIODN_MASK) 2189 << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); 2190 tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr)); 2191 WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi, 2192 (uint32_t)(tmpReg64 >> 32)); 2193 WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64); 2194 2195 /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */ 2196 WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize); 2197 2198 WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize); 2199 2200 return E_OK; 2201 } 2202 2203 static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams, 2204 t_Handle h_FmPort, t_FmPcdManip *p_Manip, 2205 t_Handle h_Ad, bool validate) 2206 { 2207 t_FmPortGetSetCcParams fmPortGetSetCcParams; 2208 uint32_t tmpReg32; 2209 t_Error err; 2210 t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams; 2211 #if (DPAA_VERSION >= 11) 2212 t_FmPcdCtrlParamsPage *p_ParamsPage; 2213 #endif /* (DPAA_VERSION >= 11) */ 2214 2215 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 2216 SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE); 2217 SANITY_CHECK_RETURN_ERROR( 2218 (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY), 2219 E_INVALID_STATE); 2220 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 2221 SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams, 2222 E_INVALID_HANDLE); 2223 2224 UNUSED(h_Ad); 2225 2226 if (!p_Manip->updateParams) 2227 return E_OK; 2228 2229 if (p_Manip->h_FmPcd != h_FmPcd) 2230 RETURN_ERROR( 2231 MAJOR, E_INVALID_STATE, 2232 ("handler of PCD previously was initiated by different value")); 2233 2234 if (p_Manip->updateParams) 2235 { 2236 if ((!(p_Manip->updateParams 2237 & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))) 2238 || ((p_Manip->shadowUpdateParams 2239 & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))) 2240 RETURN_ERROR( 2241 MAJOR, E_INVALID_STATE, 2242 ("in this stage parameters from Port has not be updated")); 2243 2244 fmPortGetSetCcParams.setCcParams.type = 0; 2245 if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) 2246 { 2247 fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE; 2248 fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF; 2249 } 2250 fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV; 2251 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) 2252 != E_OK) 2253 RETURN_ERROR(MAJOR, err, NO_MSG); 2254 if (fmPortGetSetCcParams.getCcParams.type 2255 & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV)) 2256 RETURN_ERROR(MAJOR, E_INVALID_STATE, 2257 ("offset of the data wasn't configured previously")); 2258 if (p_Manip->updateParams 2259 & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)) 2260 { 2261 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2262 uint8_t *p_Ptr, i, totalNumOfTnums; 2263 2264 totalNumOfTnums = 2265 (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks 2266 + fmPortGetSetCcParams.getCcParams.numOfExtraTasks); 2267 2268 p_Manip->reassmParams.internalBufferPoolAddr = 2269 PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2270 (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS), 2271 BMI_FIFO_UNITS)); 2272 if (!p_Manip->reassmParams.internalBufferPoolAddr) 2273 RETURN_ERROR( 2274 MAJOR, E_NO_MEMORY, 2275 ("MURAM alloc for Reassembly internal buffers pool")); 2276 MemSet8( 2277 UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr), 2278 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS)); 2279 2280 p_Manip->reassmParams.internalBufferPoolManagementIndexAddr = 2281 PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2282 (uint32_t)(5 + totalNumOfTnums), 2283 4)); 2284 if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr) 2285 RETURN_ERROR( 2286 MAJOR, 2287 E_NO_MEMORY, 2288 ("MURAM alloc for Reassembly internal buffers management")); 2289 2290 p_Ptr = 2291 (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr); 2292 WRITE_UINT32( 2293 *(uint32_t*)p_Ptr, 2294 (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase)); 2295 for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++) 2296 WRITE_UINT8(*p_Ptr, i); 2297 WRITE_UINT8(*p_Ptr, 0xFF); 2298 2299 tmpReg32 = 2300 (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT) 2301 | ((uint32_t)(XX_VirtToPhys( 2302 UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)) 2303 - p_FmPcd->physicalMuramBase)); 2304 WRITE_UINT32( 2305 p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement, 2306 tmpReg32); 2307 2308 p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS 2309 | DISCARD_MASK); 2310 p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS 2311 | DISCARD_MASK); 2312 } 2313 } 2314 2315 if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) 2316 { 2317 if (p_Manip->reassmParams.capwap.h_Scheme) 2318 { 2319 p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = 2320 p_Manip->reassmParams.capwap.h_Scheme; 2321 p_PcdParams->p_KgParams->numOfSchemes++; 2322 } 2323 2324 } 2325 else 2326 { 2327 if (p_Manip->reassmParams.ip.h_Ipv4Scheme) 2328 { 2329 p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = 2330 p_Manip->reassmParams.ip.h_Ipv4Scheme; 2331 p_PcdParams->p_KgParams->numOfSchemes++; 2332 } 2333 if (p_Manip->reassmParams.ip.h_Ipv6Scheme) 2334 { 2335 p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = 2336 p_Manip->reassmParams.ip.h_Ipv6Scheme; 2337 p_PcdParams->p_KgParams->numOfSchemes++; 2338 } 2339 #if (DPAA_VERSION >= 11) 2340 if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6) 2341 { 2342 if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE, 2343 (void**)&p_ParamsPage)) != E_OK) 2344 RETURN_ERROR(MAJOR, err, NO_MSG); 2345 2346 tmpReg32 = NIA_ENG_KG; 2347 if (p_Manip->reassmParams.ip.h_Ipv4Scheme) 2348 { 2349 tmpReg32 |= NIA_KG_DIRECT; 2350 tmpReg32 |= NIA_KG_CC_EN; 2351 tmpReg32 |= FmPcdKgGetSchemeId( 2352 p_Manip->reassmParams.ip.h_Ipv4Scheme); 2353 WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32); 2354 } 2355 if (p_Manip->reassmParams.ip.h_Ipv6Scheme) 2356 { 2357 tmpReg32 &= ~NIA_AC_MASK; 2358 tmpReg32 |= NIA_KG_DIRECT; 2359 tmpReg32 |= NIA_KG_CC_EN; 2360 tmpReg32 |= FmPcdKgGetSchemeId( 2361 p_Manip->reassmParams.ip.h_Ipv6Scheme); 2362 WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32); 2363 } 2364 } 2365 #else 2366 if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6) 2367 { 2368 WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask, 2369 fmPortGetSetCcParams.getCcParams.discardMask); 2370 } 2371 #endif /* (DPAA_VERSION >= 11) */ 2372 } 2373 return E_OK; 2374 } 2375 2376 #if (DPAA_VERSION == 10) 2377 static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid) 2378 { 2379 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2380 t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams; 2381 t_Error err; 2382 2383 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 2384 2385 memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams)); 2386 2387 fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS; 2388 fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid; 2389 if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK) 2390 RETURN_ERROR(MAJOR, err, NO_MSG); 2391 2392 if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0) 2393 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed," 2394 "Failed to release %d buffers to the BM (missing FBPRs)", 2395 fmPcdCcFragScratchPoolCmdParams.numOfBuffers)); 2396 2397 return E_OK; 2398 } 2399 2400 static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid) 2401 { 2402 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2403 t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams; 2404 t_Error err; 2405 2406 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 2407 2408 memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams)); 2409 2410 fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid; 2411 if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK) 2412 RETURN_ERROR(MAJOR, err, NO_MSG); 2413 2414 return E_OK; 2415 } 2416 #endif /* (DPAA_VERSION == 10) */ 2417 2418 static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) 2419 { 2420 if (p_Manip->h_Ad) 2421 { 2422 if (p_Manip->muramAllocate) 2423 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad); 2424 else 2425 XX_Free(p_Manip->h_Ad); 2426 p_Manip->h_Ad = NULL; 2427 } 2428 if (p_Manip->p_Template) 2429 { 2430 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template); 2431 p_Manip->p_Template = NULL; 2432 } 2433 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 2434 if (p_Manip->h_Frag) 2435 { 2436 if (p_Manip->capwapFragParams.p_AutoLearnHashTbl) 2437 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2438 p_Manip->capwapFragParams.p_AutoLearnHashTbl); 2439 if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) 2440 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2441 p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl); 2442 if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) 2443 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2444 p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl); 2445 if (p_Manip->capwapFragParams.p_TimeOutTbl) 2446 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2447 p_Manip->capwapFragParams.p_TimeOutTbl); 2448 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag); 2449 2450 } 2451 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 2452 if (p_Manip->frag) 2453 { 2454 if (p_Manip->fragParams.p_Frag) 2455 { 2456 #if (DPAA_VERSION == 10) 2457 FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid); 2458 #endif /* (DPAA_VERSION == 10) */ 2459 2460 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag); 2461 } 2462 } 2463 else 2464 if (p_Manip->reassm) 2465 { 2466 FmPcdUnregisterReassmPort(p_FmPcd, 2467 p_Manip->reassmParams.p_ReassCommonTbl); 2468 2469 if (p_Manip->reassmParams.timeOutTblAddr) 2470 FM_MURAM_FreeMem( 2471 p_FmPcd->h_FmMuram, 2472 UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr)); 2473 if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr) 2474 XX_FreeSmart( 2475 UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)); 2476 if (p_Manip->reassmParams.p_ReassCommonTbl) 2477 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2478 p_Manip->reassmParams.p_ReassCommonTbl); 2479 if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr) 2480 FM_MURAM_FreeMem( 2481 p_FmPcd->h_FmMuram, 2482 UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)); 2483 if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr) 2484 FM_MURAM_FreeMem( 2485 p_FmPcd->h_FmMuram, 2486 UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)); 2487 if (p_Manip->reassmParams.internalBufferPoolAddr) 2488 FM_MURAM_FreeMem( 2489 p_FmPcd->h_FmMuram, 2490 UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)); 2491 if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP) 2492 { 2493 2494 } 2495 else 2496 { 2497 if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr) 2498 XX_FreeSmart( 2499 UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)); 2500 if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr) 2501 XX_FreeSmart( 2502 UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)); 2503 if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr) 2504 XX_FreeSmart( 2505 UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)); 2506 if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr) 2507 XX_FreeSmart( 2508 UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)); 2509 if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl) 2510 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2511 p_Manip->reassmParams.ip.p_Ipv4ReassTbl); 2512 if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl) 2513 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, 2514 p_Manip->reassmParams.ip.p_Ipv6ReassTbl); 2515 if (p_Manip->reassmParams.ip.h_Ipv6Ad) 2516 XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad); 2517 if (p_Manip->reassmParams.ip.h_Ipv4Ad) 2518 XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad); 2519 } 2520 } 2521 2522 if (p_Manip->p_StatsTbl) 2523 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl); 2524 } 2525 2526 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 2527 static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams) 2528 { 2529 if (p_ManipParams->u.hdr.rmv) 2530 { 2531 switch (p_ManipParams->u.hdr.rmvParams.type) 2532 { 2533 case (e_FM_PCD_MANIP_RMV_BY_HDR): 2534 switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type) 2535 { 2536 case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) : 2537 if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include) 2538 { 2539 switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr) 2540 { 2541 case (HEADER_TYPE_CAPWAP_DTLS) : 2542 p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; 2543 p_Manip->muramAllocate = TRUE; 2544 if (p_ManipParams->u.hdr.insrt) 2545 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after")); 2546 if (p_ManipParams->fragOrReasm) 2547 { 2548 if (!p_ManipParams->fragOrReasmParams.frag) 2549 { 2550 switch (p_ManipParams->fragOrReasmParams.hdr) 2551 { 2552 case (HEADER_TYPE_CAPWAP): 2553 p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY; 2554 break; 2555 default: 2556 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly")); 2557 } 2558 } 2559 else 2560 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE")); 2561 } 2562 break; 2563 default: 2564 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location")); 2565 } 2566 } 2567 else 2568 { 2569 switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr) 2570 { 2571 case (HEADER_TYPE_CAPWAP_DTLS) : 2572 case (HEADER_TYPE_CAPWAP) : 2573 if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt) 2574 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_CAPWAP can not be insert or fragOrReasm TRUE")); 2575 p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; 2576 p_Manip->muramAllocate = TRUE; 2577 p_ManipParams->u.hdr.insrt = TRUE; //internal frame header 2578 break; 2579 default : 2580 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); 2581 } 2582 } 2583 break; 2584 default : 2585 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); 2586 } 2587 break; 2588 default: 2589 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); 2590 } 2591 } 2592 else if (p_ManipParams->u.hdr.insrt) 2593 { 2594 switch (p_ManipParams->u.hdr.insrtParams.type) 2595 { 2596 case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) : 2597 2598 p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; 2599 p_Manip->muramAllocate = FALSE; 2600 if (p_ManipParams->fragOrReasm) 2601 { 2602 if (p_ManipParams->fragOrReasmParams.frag) 2603 { 2604 switch (p_ManipParams->fragOrReasmParams.hdr) 2605 { 2606 case (HEADER_TYPE_CAPWAP): 2607 p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; 2608 break; 2609 default: 2610 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation")); 2611 } 2612 } 2613 else 2614 RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point")); 2615 } 2616 break; 2617 2618 default: 2619 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type")); 2620 } 2621 } 2622 else if (p_ManipParams->fragOrReasm) 2623 { 2624 if (p_ManipParams->fragOrReasmParams.frag) 2625 { 2626 switch (p_ManipParams->fragOrReasmParams.hdr) 2627 { 2628 case (HEADER_TYPE_CAPWAP): 2629 p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; 2630 p_Manip->muramAllocate = FALSE; 2631 break; 2632 default: 2633 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation")); 2634 } 2635 } 2636 else 2637 { 2638 switch (p_ManipParams->fragOrReasmParams.hdr) 2639 { 2640 case (HEADER_TYPE_CAPWAP): 2641 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS")); 2642 default: 2643 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly")); 2644 } 2645 } 2646 2647 } 2648 else 2649 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation")); 2650 2651 p_Manip->insrt = p_ManipParams->u.hdr.insrt; 2652 p_Manip->rmv = p_ManipParams->u.hdr.rmv; 2653 2654 return E_OK; 2655 } 2656 2657 #else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 2658 static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, 2659 t_FmPcdManipParams *p_ManipParams) 2660 { 2661 switch (p_ManipParams->type) 2662 { 2663 case e_FM_PCD_MANIP_HDR: 2664 /* Check that next-manip is not already used */ 2665 if (p_ManipParams->h_NextManip) 2666 { 2667 if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip)) 2668 RETURN_ERROR( 2669 MAJOR, E_INVALID_STATE, 2670 ("h_NextManip is already a part of another chain")); 2671 if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip) 2672 != e_FM_PCD_MANIP_HDR) && 2673 (MANIP_GET_TYPE(p_ManipParams->h_NextManip) 2674 != e_FM_PCD_MANIP_FRAG)) 2675 RETURN_ERROR( 2676 MAJOR, 2677 E_NOT_SUPPORTED, 2678 ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation.")); 2679 } 2680 2681 if (p_ManipParams->u.hdr.rmv) 2682 { 2683 switch (p_ManipParams->u.hdr.rmvParams.type) 2684 { 2685 case (e_FM_PCD_MANIP_RMV_BY_HDR): 2686 switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type) 2687 { 2688 case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): 2689 break; 2690 #if (DPAA_VERSION >= 11) 2691 case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): 2692 break; 2693 case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): 2694 { 2695 t_Error err; 2696 uint8_t prsArrayOffset; 2697 2698 err = 2699 GetPrOffsetByHeaderOrField( 2700 &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo, 2701 &prsArrayOffset); 2702 if (err) 2703 RETURN_ERROR(MAJOR, err, NO_MSG); 2704 break; 2705 } 2706 #endif /* (DPAA_VERSION >= 11) */ 2707 default: 2708 RETURN_ERROR( 2709 MAJOR, 2710 E_INVALID_STATE, 2711 ("invalid type of remove manipulation")); 2712 } 2713 break; 2714 case (e_FM_PCD_MANIP_RMV_GENERIC): 2715 break; 2716 default: 2717 RETURN_ERROR(MAJOR, E_INVALID_STATE, 2718 ("invalid type of remove manipulation")); 2719 } 2720 p_Manip->opcode = HMAN_OC; 2721 p_Manip->muramAllocate = TRUE; 2722 p_Manip->rmv = TRUE; 2723 } 2724 else 2725 if (p_ManipParams->u.hdr.insrt) 2726 { 2727 switch (p_ManipParams->u.hdr.insrtParams.type) 2728 { 2729 case (e_FM_PCD_MANIP_INSRT_BY_HDR): 2730 { 2731 switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type) 2732 { 2733 case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): 2734 /* nothing to check */ 2735 break; 2736 #if (DPAA_VERSION >= 11) 2737 case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): 2738 if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size 2739 % 4) 2740 RETURN_ERROR( 2741 MAJOR, 2742 E_INVALID_VALUE, 2743 ("IP inserted header must be of size which is a multiple of four bytes")); 2744 break; 2745 case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): 2746 if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size 2747 % 4) 2748 RETURN_ERROR( 2749 MAJOR, 2750 E_INVALID_VALUE, 2751 ("CAPWAP inserted header must be of size which is a multiple of four bytes")); 2752 break; 2753 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): 2754 case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): 2755 if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size 2756 != 8) 2757 RETURN_ERROR( 2758 MAJOR, 2759 E_INVALID_VALUE, 2760 ("Inserted header must be of size 8")); 2761 break; 2762 #endif /* (DPAA_VERSION >= 11) */ 2763 default: 2764 RETURN_ERROR( 2765 MAJOR, 2766 E_INVALID_STATE, 2767 ("unsupported insert by header type")); 2768 } 2769 } 2770 case (e_FM_PCD_MANIP_INSRT_GENERIC): 2771 break; 2772 default: 2773 RETURN_ERROR( 2774 MAJOR, 2775 E_INVALID_STATE, 2776 ("for only insert manipulation unsupported type")); 2777 } 2778 p_Manip->opcode = HMAN_OC; 2779 p_Manip->muramAllocate = TRUE; 2780 p_Manip->insrt = TRUE; 2781 } 2782 else 2783 if (p_ManipParams->u.hdr.fieldUpdate) 2784 { 2785 /* Check parameters */ 2786 if (p_ManipParams->u.hdr.fieldUpdateParams.type 2787 == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN) 2788 { 2789 if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType 2790 == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI) 2791 && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri 2792 > 7)) 2793 RETURN_ERROR( 2794 MAJOR, E_INVALID_VALUE, 2795 ("vpri should get values of 0-7 ")); 2796 if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType 2797 == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) 2798 { 2799 int i; 2800 2801 if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal 2802 > 7) 2803 RETURN_ERROR( 2804 MAJOR, 2805 E_INVALID_VALUE, 2806 ("vpriDefVal should get values of 0-7 ")); 2807 for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS; 2808 i++) 2809 if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i] 2810 & 0xf0) 2811 RETURN_ERROR( 2812 MAJOR, 2813 E_INVALID_VALUE, 2814 ("dscpToVpriTabl value out of range (0-15)")); 2815 } 2816 2817 } 2818 2819 p_Manip->opcode = HMAN_OC; 2820 p_Manip->muramAllocate = TRUE; 2821 p_Manip->fieldUpdate = TRUE; 2822 } 2823 else 2824 if (p_ManipParams->u.hdr.custom) 2825 { 2826 if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE) 2827 { 2828 2829 if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) || 2830 (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8)) 2831 RETURN_ERROR( 2832 MAJOR, E_INVALID_VALUE, 2833 ("size should get values of 1-8 ")); 2834 2835 if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7) 2836 RETURN_ERROR( 2837 MAJOR, E_INVALID_VALUE, 2838 ("srcOffset should be <= 7")); 2839 2840 if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset + 2841 p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8) 2842 RETURN_ERROR( 2843 MAJOR, E_INVALID_VALUE, 2844 ("(srcOffset + size) should be <= 8")); 2845 2846 if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset + 2847 p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256) 2848 RETURN_ERROR( 2849 MAJOR, E_INVALID_VALUE, 2850 ("(dstOffset + size) should be <= 256")); 2851 2852 } 2853 2854 p_Manip->opcode = HMAN_OC; 2855 p_Manip->muramAllocate = TRUE; 2856 p_Manip->custom = TRUE; 2857 } 2858 break; 2859 case e_FM_PCD_MANIP_REASSEM: 2860 if (p_ManipParams->h_NextManip) 2861 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 2862 ("next manip with reassembly")); 2863 switch (p_ManipParams->u.reassem.hdr) 2864 { 2865 case (HEADER_TYPE_IPv4): 2866 p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4; 2867 p_Manip->opcode = HMAN_OC_IP_REASSEMBLY; 2868 break; 2869 case (HEADER_TYPE_IPv6): 2870 p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6; 2871 p_Manip->opcode = HMAN_OC_IP_REASSEMBLY; 2872 break; 2873 #if (DPAA_VERSION >= 11) 2874 case (HEADER_TYPE_CAPWAP): 2875 p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP; 2876 p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY; 2877 break; 2878 #endif /* (DPAA_VERSION >= 11) */ 2879 default: 2880 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 2881 ("header for reassembly")); 2882 } 2883 break; 2884 case e_FM_PCD_MANIP_FRAG: 2885 if (p_ManipParams->h_NextManip) 2886 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 2887 ("next manip with fragmentation")); 2888 switch (p_ManipParams->u.frag.hdr) 2889 { 2890 case (HEADER_TYPE_IPv4): 2891 case (HEADER_TYPE_IPv6): 2892 p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION; 2893 break; 2894 #if (DPAA_VERSION >= 11) 2895 case (HEADER_TYPE_CAPWAP): 2896 p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; 2897 break; 2898 #endif /* (DPAA_VERSION >= 11) */ 2899 default: 2900 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 2901 ("header for fragmentation")); 2902 } 2903 p_Manip->muramAllocate = TRUE; 2904 break; 2905 case e_FM_PCD_MANIP_SPECIAL_OFFLOAD: 2906 switch (p_ManipParams->u.specialOffload.type) 2907 { 2908 case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC): 2909 p_Manip->opcode = HMAN_OC_IPSEC_MANIP; 2910 p_Manip->muramAllocate = TRUE; 2911 break; 2912 #if (DPAA_VERSION >= 11) 2913 case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP): 2914 p_Manip->opcode = HMAN_OC_CAPWAP_MANIP; 2915 p_Manip->muramAllocate = TRUE; 2916 break; 2917 #endif /* (DPAA_VERSION >= 11) */ 2918 default: 2919 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 2920 ("special offload type")); 2921 } 2922 break; 2923 default: 2924 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type")); 2925 } 2926 2927 return E_OK; 2928 } 2929 #endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 2930 2931 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 2932 2933 static t_Error UpdateIndxStats(t_Handle h_FmPcd, 2934 t_Handle h_FmPort, 2935 t_FmPcdManip *p_Manip) 2936 { 2937 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2938 uint32_t tmpReg32 = 0; 2939 t_AdOfTypeContLookup *p_Ad; 2940 t_FmPortGetSetCcParams fmPortGetSetCcParams; 2941 t_Error err; 2942 2943 SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); 2944 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); 2945 2946 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 2947 if (p_Manip->h_FmPcd != h_FmPcd) 2948 RETURN_ERROR(MAJOR, E_INVALID_STATE, 2949 ("handler of PCD previously was initiated by different value")); 2950 2951 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); 2952 2953 if (!p_Manip->p_StatsTbl) 2954 { 2955 2956 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; 2957 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC; 2958 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 2959 if (err) 2960 RETURN_ERROR(MAJOR, err, NO_MSG); 2961 2962 tmpReg32 = GET_UINT32(p_Ad->ccAdBase); 2963 2964 p_Manip->p_StatsTbl = 2965 (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2966 (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE, 2967 4); 2968 if (!p_Manip->p_StatsTbl) 2969 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table")); 2970 2971 MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4)); 2972 2973 tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase); 2974 2975 if (p_Manip->cnia) 2976 tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA; 2977 2978 tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD; 2979 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 2980 } 2981 else 2982 { 2983 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; 2984 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC; 2985 err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); 2986 if (err) 2987 RETURN_ERROR(MAJOR, err, NO_MSG); 2988 } 2989 2990 return E_OK; 2991 } 2992 2993 static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip) 2994 { 2995 t_AdOfTypeContLookup *p_Ad; 2996 uint32_t tmpReg32 = 0; 2997 uint8_t prsArrayOffset = 0; 2998 t_Error err; 2999 3000 SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER); 3001 SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER); 3002 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); 3003 3004 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 3005 if (p_Manip->rmv) 3006 { 3007 err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset); 3008 if (err) 3009 RETURN_ERROR(MAJOR, err, NO_MSG); 3010 3011 tmpReg32 |= (uint32_t)prsArrayOffset << 24; 3012 tmpReg32 |= HMAN_RMV_HDR; 3013 } 3014 3015 if (p_Manip->insrt) 3016 tmpReg32 |= HMAN_INSRT_INT_FRM_HDR; 3017 3018 tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; 3019 3020 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 3021 3022 tmpReg32 = 0; 3023 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3024 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 3025 3026 return E_OK; 3027 } 3028 3029 static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip, 3030 bool caamUsed) 3031 { 3032 t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 3033 uint32_t tmpReg32 = 0; 3034 3035 SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE); 3036 3037 p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET; 3038 3039 tmpReg32 = 0; 3040 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3041 *(uint32_t *)&p_Ad->ccAdBase = tmpReg32; 3042 3043 tmpReg32 = 0; 3044 tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX; 3045 tmpReg32 |= (uint32_t)0x16 << 16; 3046 *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32; 3047 3048 if (caamUsed) 3049 *(uint32_t *)&p_Ad->gmask = 0xf0000000; 3050 3051 return E_OK; 3052 } 3053 3054 static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip) 3055 { 3056 t_AdOfTypeContLookup *p_Ad; 3057 uint32_t tmpReg32 = 0; 3058 t_Error err = E_OK; 3059 3060 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); 3061 3062 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 3063 3064 tmpReg32 = 0; 3065 tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; 3066 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 3067 3068 tmpReg32 = 0; 3069 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3070 3071 3072 if (p_Manip->h_Frag) 3073 { 3074 p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET; 3075 tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase)); 3076 } 3077 3078 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 3079 3080 return err; 3081 } 3082 3083 static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams, 3084 t_FmPcdManip *p_Manip, 3085 t_FmPcd *p_FmPcd, 3086 uint8_t poolId) 3087 { 3088 t_Handle p_Table; 3089 uint32_t tmpReg32 = 0; 3090 int i = 0; 3091 uint8_t log2Num; 3092 uint8_t numOfSets; 3093 uint32_t j = 0; 3094 uint32_t bitFor1Micro; 3095 3096 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); 3097 SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); 3098 3099 if (!p_FmPcd->h_Hc) 3100 RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode")); 3101 if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime)) 3102 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2")); 3103 if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess)) 3104 RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2")); 3105 if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess) 3106 DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly")); 3107 if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH) 3108 { 3109 if ((p_ManipParams->maxNumFramesInProcess < 4) || 3110 (p_ManipParams->maxNumFramesInProcess > 512)) 3111 RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512")); 3112 } 3113 else 3114 { 3115 if ((p_ManipParams->maxNumFramesInProcess < 8) || 3116 (p_ManipParams->maxNumFramesInProcess > 2048)) 3117 RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048")); 3118 } 3119 3120 bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); 3121 if (bitFor1Micro == 0) 3122 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); 3123 3124 p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID); 3125 3126 p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 3127 FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE, 3128 FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); 3129 if (!p_Manip->h_Frag) 3130 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table")); 3131 3132 MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE); 3133 3134 p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag; 3135 3136 p_Manip->capwapFragParams.p_AutoLearnHashTbl = 3137 (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 3138 (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 3139 FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); 3140 3141 if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl) 3142 RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table")); 3143 3144 MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE)); 3145 3146 tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase); 3147 3148 WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32); 3149 3150 tmpReg32 = 0; 3151 if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) 3152 tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES; 3153 if (p_ManipParams->haltOnDuplicationFrag) 3154 tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG; 3155 if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH) 3156 { 3157 i = 8; 3158 tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS; 3159 } 3160 else 3161 i = 4; 3162 3163 numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i); 3164 LOG2(numOfSets, log2Num); 3165 tmpReg32 |= (uint32_t)(log2Num - 1) << 24; 3166 3167 WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32); 3168 3169 for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++) 3170 if (((j / i) % 2)== 0) 3171 WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000); 3172 3173 tmpReg32 = 0x00008000; 3174 tmpReg32 |= (uint32_t)poolId << 16; 3175 WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32); 3176 WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000); 3177 WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000); 3178 3179 p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess; 3180 3181 p_Manip->capwapFragParams.sgBpid = poolId; 3182 3183 p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames; 3184 p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime; 3185 p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro; 3186 3187 tmpReg32 = 0; 3188 tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess); 3189 WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32); 3190 3191 return E_OK; 3192 } 3193 3194 static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams, 3195 t_FmPcdManip *p_Manip, 3196 t_FmPcd *p_FmPcd, 3197 uint8_t poolId) 3198 { 3199 t_AdOfTypeContLookup *p_Ad; 3200 uint32_t tmpReg32 = 0; 3201 3202 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); 3203 3204 p_Manip->updateParams |= OFFSET_OF_DATA; 3205 3206 p_Manip->frag = TRUE; 3207 3208 p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 3209 FM_PCD_CC_AD_ENTRY_SIZE, 3210 FM_PCD_CC_AD_TABLE_ALIGN); 3211 if (!p_Manip->h_Frag) 3212 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor")); 3213 3214 MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); 3215 3216 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; 3217 3218 tmpReg32 = 0; 3219 tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION; 3220 3221 if (p_ManipParams->headerOptionsCompr) 3222 tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN; 3223 tmpReg32 |= ((uint32_t)poolId << 8); 3224 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 3225 3226 tmpReg32 = 0; 3227 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3228 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 3229 3230 p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; 3231 p_Manip->capwapFragParams.sgBpid = poolId; 3232 3233 return E_OK; 3234 } 3235 3236 static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd) 3237 { 3238 t_AdOfTypeContLookup *p_Ad; 3239 uint32_t tmpReg32 = 0; 3240 3241 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); 3242 3243 UNUSED(p_FmPcd); 3244 3245 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 3246 3247 tmpReg32 = 0; 3248 tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS; 3249 if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID) 3250 tmpReg32 |= (uint32_t)0x16 << 16; 3251 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 3252 3253 tmpReg32 = 0; 3254 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3255 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 3256 3257 return E_OK; 3258 } 3259 3260 static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) 3261 { 3262 t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate; 3263 uint8_t tmpReg8 = 0xff; 3264 t_AdOfTypeContLookup *p_Ad; 3265 bool ipModify = FALSE; 3266 uint32_t tmpReg32 = 0, tmpRegNia = 0; 3267 uint16_t tmpReg16 = 0; 3268 t_Error err = E_OK; 3269 uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0; 3270 uint8_t *p_Template = NULL; 3271 3272 SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER); 3273 SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER); 3274 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); 3275 SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER); 3276 3277 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 3278 if (p_Manip->insrt) 3279 { 3280 if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) || 3281 (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan)) 3282 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)")); 3283 3284 if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset)) 3285 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset")); 3286 3287 if (p_InsrtByTemplate->size > 128) 3288 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128")); 3289 3290 if (p_InsrtByTemplate->size) 3291 { 3292 p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 3293 p_InsrtByTemplate->size, 3294 FM_PCD_CC_AD_TABLE_ALIGN); 3295 if(!p_Manip->p_Template) 3296 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); 3297 3298 tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase)); 3299 tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24; 3300 *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32; 3301 } 3302 3303 tmpReg32 = 0; 3304 3305 p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t)); 3306 3307 if (!p_Template) 3308 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED")); 3309 3310 memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t)); 3311 3312 if (p_InsrtByTemplate->modifyOuterIp) 3313 { 3314 ipModify = TRUE; 3315 3316 tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset]; 3317 3318 if((tmpReg8 & 0xf0) == 0x40) 3319 tmpReg8 = 4; 3320 else if((tmpReg8 & 0xf0) == 0x60) 3321 tmpReg8 = 6; 3322 else 3323 tmpReg8 = 0xff; 3324 3325 if (tmpReg8 != 0xff) 3326 { 3327 if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00) 3328 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte")); 3329 if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength) 3330 { 3331 3332 if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255) 3333 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes")); 3334 extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize); 3335 blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize; 3336 extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize; 3337 /*IP header template - IP totalLength - 3338 (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage , 3339 in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13) 3340 second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/ 3341 } 3342 if (blockSize) 3343 { 3344 if (!POWER_OF_2(blockSize)) 3345 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2")); 3346 } 3347 3348 } 3349 if (tmpReg8 == 4) 3350 { 3351 if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size) 3352 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size")); 3353 3354 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn; 3355 3356 if (blockSize) 3357 blockSize -= 1; 3358 3359 if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255) 3360 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255")); 3361 3362 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND 3363 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);// for IPV6 decrement additional 40 bytes of IPV6 heade size 3364 3365 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00; 3366 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize; 3367 3368 /*IP header template - relevant only for ipv4 CheckSum = 0*/ 3369 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00; 3370 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00; 3371 3372 /*UDP checksum has to be 0*/ 3373 if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent) 3374 { 3375 if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size) 3376 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template")); 3377 3378 p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00; 3379 p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00; 3380 3381 } 3382 3383 if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7) 3384 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field")); 3385 3386 tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24; 3387 } 3388 else if (tmpReg8 == 6) 3389 { 3390 /*TODO - add check for maximum value of blockSize;*/ 3391 if (blockSize) 3392 LOG2(blockSize, log2Num); 3393 tmpRegNia |= (uint32_t)log2Num << 24; 3394 3395 // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength 3396 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40); 3397 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize; 3398 if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent) 3399 { 3400 if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size) 3401 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template")); 3402 if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88) 3403 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite")); 3404 p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00; 3405 p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08; 3406 p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00; 3407 p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00; 3408 } 3409 } 3410 else 3411 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4")); 3412 } 3413 3414 tmpReg32 = tmpReg16 = tmpReg8 = 0; 3415 /*TODO - check it*/ 3416 if (p_InsrtByTemplate->modifyOuterVlan) 3417 { 3418 if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07) 3419 RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits")); 3420 3421 memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t))); 3422 if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100)) 3423 RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN ")); 3424 3425 memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t))); 3426 tmpReg8 &= 0x1f; 3427 tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5); 3428 3429 p_Template[14] = tmpReg8; 3430 } 3431 3432 MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size); 3433 3434 XX_Free(p_Template); 3435 } 3436 3437 tmpReg32 = 0; 3438 if (p_Manip->h_Frag) 3439 { 3440 tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase)); 3441 tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16; 3442 } 3443 else 3444 tmpReg32 = 0xffff0000; 3445 3446 if (ipModify) 3447 tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8; 3448 else 3449 tmpReg32 |= (uint32_t)0x0000ff00; 3450 3451 tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; 3452 *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32; 3453 3454 tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3455 *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia; 3456 3457 return err; 3458 } 3459 3460 static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams) 3461 { 3462 3463 switch (p_StatsParams->type) 3464 { 3465 case (e_FM_PCD_STATS_PER_FLOWID): 3466 p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS; 3467 p_Manip->muramAllocate = TRUE; 3468 break; 3469 default: 3470 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type")); 3471 } 3472 3473 return E_OK; 3474 } 3475 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 3476 3477 static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr) 3478 { 3479 t_AdOfTypeContLookup *p_Ad; 3480 t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; 3481 uint32_t tmpReg32; 3482 t_Error err = E_OK; 3483 3484 /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly 3485 function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then 3486 two separate IP Reassembly Parameter tables are required.*/ 3487 if ((err = CreateReassTable(p_Manip, hdr)) != E_OK) 3488 RETURN_ERROR(MAJOR, err, NO_MSG); 3489 3490 /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/ 3491 tmpReg32 = 0; 3492 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3493 3494 /* Gets the required Action descriptor table pointer */ 3495 switch (hdr) 3496 { 3497 case HEADER_TYPE_IPv4: 3498 p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad; 3499 tmpReg32 |= (uint32_t)(XX_VirtToPhys( 3500 p_Manip->reassmParams.ip.p_Ipv4ReassTbl) 3501 - (p_FmPcd->physicalMuramBase)); 3502 break; 3503 case HEADER_TYPE_IPv6: 3504 p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad; 3505 tmpReg32 |= (uint32_t)(XX_VirtToPhys( 3506 p_Manip->reassmParams.ip.p_Ipv6ReassTbl) 3507 - (p_FmPcd->physicalMuramBase)); 3508 break; 3509 case HEADER_TYPE_CAPWAP: 3510 p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad; 3511 tmpReg32 |= (uint32_t)(XX_VirtToPhys( 3512 p_Manip->reassmParams.capwap.p_ReassTbl) 3513 - (p_FmPcd->physicalMuramBase)); 3514 break; 3515 default: 3516 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type")); 3517 } 3518 3519 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 3520 3521 /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/ 3522 /* mark the Scatter/Gather table offset to be set later on when the port will be known */ 3523 p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK); 3524 3525 if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4)) 3526 { 3527 #if (DPAA_VERSION == 10) 3528 tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8); 3529 WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); 3530 #endif /* (DPAA_VERSION == 10) */ 3531 #if (DPAA_VERSION >= 11) 3532 if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0) 3533 { 3534 tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK 3535 | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid); 3536 WRITE_UINT32(p_Ad->gmask, tmpReg32); 3537 } 3538 #endif /* (DPAA_VERSION >= 11) */ 3539 /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/ 3540 tmpReg32 = 0; 3541 tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY; 3542 } 3543 #if (DPAA_VERSION >= 11) 3544 else 3545 if (hdr == HEADER_TYPE_CAPWAP) 3546 { 3547 tmpReg32 = 0; 3548 tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY; 3549 } 3550 #endif /* (DPAA_VERSION >= 11) */ 3551 3552 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 3553 3554 p_Manip->reassm = TRUE; 3555 3556 return E_OK; 3557 } 3558 3559 static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip) 3560 { 3561 t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; 3562 3563 /* Allocation if IPv4 Action descriptor */ 3564 p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart( 3565 FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, 3566 FM_PCD_CC_AD_TABLE_ALIGN); 3567 if (!p_Manip->reassmParams.ip.h_Ipv4Ad) 3568 { 3569 ReleaseManipHandler(p_Manip, p_FmPcd); 3570 RETURN_ERROR(MAJOR, E_NO_MEMORY, 3571 ("Allocation of IPv4 table descriptor")); 3572 } 3573 3574 memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); 3575 3576 /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ 3577 return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4); 3578 } 3579 3580 static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip) 3581 { 3582 t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; 3583 3584 /* Allocation if IPv6 Action descriptor */ 3585 p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart( 3586 FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, 3587 FM_PCD_CC_AD_TABLE_ALIGN); 3588 if (!p_Manip->reassmParams.ip.h_Ipv6Ad) 3589 { 3590 ReleaseManipHandler(p_Manip, p_FmPcd); 3591 RETURN_ERROR(MAJOR, E_NO_MEMORY, 3592 ("Allocation of IPv6 table descriptor")); 3593 } 3594 3595 memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); 3596 3597 /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ 3598 return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6); 3599 } 3600 3601 static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams, 3602 t_FmPcdManip *p_Manip) 3603 { 3604 uint32_t maxSetNumber = 10000; 3605 t_FmPcdManipReassemIpParams reassmManipParams = 3606 p_ManipReassmParams->u.ipReassem; 3607 t_Error res; 3608 3609 SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE); 3610 SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc, 3611 E_INVALID_HANDLE); 3612 3613 /* Check validation of user's parameter.*/ 3614 if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) 3615 || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000)) 3616 RETURN_ERROR( 3617 MAJOR, E_INVALID_VALUE, 3618 ("timeoutThresholdForReassmProcess should be 1msec - 8sec")); 3619 /* It is recommended that the total number of entries in this table (number of sets * number of ways) 3620 will be twice the number of frames that are expected to be reassembled simultaneously.*/ 3621 if (reassmManipParams.maxNumFramesInProcess 3622 > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2)) 3623 RETURN_ERROR( 3624 MAJOR, 3625 E_INVALID_VALUE, 3626 ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)")); 3627 3628 if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6) 3629 && (reassmManipParams.minFragSize[1] < 256)) 3630 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256")); 3631 3632 /* Saves user's reassembly manipulation parameters */ 3633 p_Manip->reassmParams.ip.relativeSchemeId[0] = 3634 reassmManipParams.relativeSchemeId[0]; 3635 p_Manip->reassmParams.ip.relativeSchemeId[1] = 3636 reassmManipParams.relativeSchemeId[1]; 3637 p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] = 3638 reassmManipParams.numOfFramesPerHashEntry[0]; 3639 p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] = 3640 reassmManipParams.numOfFramesPerHashEntry[1]; 3641 p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0]; 3642 p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1]; 3643 p_Manip->reassmParams.maxNumFramesInProcess = 3644 reassmManipParams.maxNumFramesInProcess; 3645 p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode; 3646 p_Manip->reassmParams.fqidForTimeOutFrames = 3647 reassmManipParams.fqidForTimeOutFrames; 3648 p_Manip->reassmParams.timeoutThresholdForReassmProcess = 3649 reassmManipParams.timeoutThresholdForReassmProcess; 3650 p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId; 3651 p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset; 3652 #if (DPAA_VERSION == 10) 3653 p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid; 3654 #endif /* (DPAA_VERSION == 10) */ 3655 #if (DPAA_VERSION >= 11) 3656 if (reassmManipParams.nonConsistentSpFqid != 0) 3657 { 3658 p_Manip->reassmParams.ip.nonConsistentSpFqid = 3659 reassmManipParams.nonConsistentSpFqid; 3660 } 3661 #endif /* (DPAA_VERSION >= 11) */ 3662 3663 /* Creates and initializes the IP Reassembly common parameter table */ 3664 CreateReassCommonTable(p_Manip); 3665 3666 /* Creation of IPv4 reassembly manipulation */ 3667 if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6) 3668 || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4)) 3669 { 3670 res = SetIpv4ReassmManip(p_Manip); 3671 if (res != E_OK) 3672 return res; 3673 } 3674 3675 /* Creation of IPv6 reassembly manipulation */ 3676 if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6) 3677 { 3678 res = SetIpv6ReassmManip(p_Manip); 3679 if (res != E_OK) 3680 return res; 3681 } 3682 3683 return E_OK; 3684 } 3685 3686 static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd, 3687 t_FmPcdKgSchemeParams *p_Scheme, 3688 t_Handle h_CcTree, bool ipv4, 3689 uint8_t groupId) 3690 { 3691 uint32_t j; 3692 uint8_t res; 3693 3694 /* Configures scheme's network environment parameters */ 3695 p_Scheme->netEnvParams.numOfDistinctionUnits = 2; 3696 if (ipv4) 3697 res = FmPcdNetEnvGetUnitId( 3698 p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), 3699 HEADER_TYPE_IPv4, FALSE, 0); 3700 else 3701 res = FmPcdNetEnvGetUnitId( 3702 p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), 3703 HEADER_TYPE_IPv6, FALSE, 0); 3704 ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); 3705 p_Scheme->netEnvParams.unitIds[0] = res; 3706 3707 res = FmPcdNetEnvGetUnitId( 3708 p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), 3709 HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0); 3710 ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); 3711 p_Scheme->netEnvParams.unitIds[1] = res; 3712 3713 /* Configures scheme's next engine parameters*/ 3714 p_Scheme->nextEngine = e_FM_PCD_CC; 3715 p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree; 3716 p_Scheme->kgNextEngineParams.cc.grpId = groupId; 3717 p_Scheme->useHash = TRUE; 3718 3719 /* Configures scheme's key*/ 3720 if (ipv4 == TRUE) 3721 { 3722 p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4; 3723 p_Scheme->keyExtractAndHashParams.extractArray[0].type = 3724 e_FM_PCD_EXTRACT_BY_HDR; 3725 p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type = 3726 e_FM_PCD_EXTRACT_FULL_FIELD; 3727 p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr = 3728 HEADER_TYPE_IPv4; 3729 p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 = 3730 NET_HEADER_FIELD_IPv4_DST_IP; 3731 p_Scheme->keyExtractAndHashParams.extractArray[1].type = 3732 e_FM_PCD_EXTRACT_BY_HDR; 3733 p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type = 3734 e_FM_PCD_EXTRACT_FULL_FIELD; 3735 p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr = 3736 HEADER_TYPE_IPv4; 3737 p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 = 3738 NET_HEADER_FIELD_IPv4_SRC_IP; 3739 p_Scheme->keyExtractAndHashParams.extractArray[2].type = 3740 e_FM_PCD_EXTRACT_BY_HDR; 3741 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type = 3742 e_FM_PCD_EXTRACT_FULL_FIELD; 3743 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr = 3744 HEADER_TYPE_IPv4; 3745 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 = 3746 NET_HEADER_FIELD_IPv4_PROTO; 3747 p_Scheme->keyExtractAndHashParams.extractArray[3].type = 3748 e_FM_PCD_EXTRACT_BY_HDR; 3749 p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr = 3750 HEADER_TYPE_IPv4; 3751 p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type = 3752 e_FM_PCD_EXTRACT_FROM_HDR; 3753 p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation = 3754 FALSE; 3755 p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size = 3756 2; 3757 p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset = 3758 4; 3759 } 3760 else /* IPv6 */ 3761 { 3762 p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3; 3763 p_Scheme->keyExtractAndHashParams.extractArray[0].type = 3764 e_FM_PCD_EXTRACT_BY_HDR; 3765 p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type = 3766 e_FM_PCD_EXTRACT_FULL_FIELD; 3767 p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr = 3768 HEADER_TYPE_IPv6; 3769 p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 = 3770 NET_HEADER_FIELD_IPv6_DST_IP; 3771 p_Scheme->keyExtractAndHashParams.extractArray[1].type = 3772 e_FM_PCD_EXTRACT_BY_HDR; 3773 p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type = 3774 e_FM_PCD_EXTRACT_FULL_FIELD; 3775 p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr = 3776 HEADER_TYPE_IPv6; 3777 p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 = 3778 NET_HEADER_FIELD_IPv6_SRC_IP; 3779 p_Scheme->keyExtractAndHashParams.extractArray[2].type = 3780 e_FM_PCD_EXTRACT_BY_HDR; 3781 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr = 3782 HEADER_TYPE_USER_DEFINED_SHIM2; 3783 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type = 3784 e_FM_PCD_EXTRACT_FROM_HDR; 3785 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size = 3786 4; 3787 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset = 3788 4; 3789 p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation = 3790 TRUE; 3791 } 3792 3793 p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304; 3794 p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314; 3795 p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 3796 FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; 3797 for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++) 3798 { 3799 p_Scheme->keyExtractAndHashParams.dflts[j].type = 3800 (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */ 3801 p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect = 3802 e_FM_PCD_KG_DFLT_GBL_0; 3803 } 3804 } 3805 3806 static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip, 3807 t_FmPcdManipReassemIpStats *p_Stats) 3808 { 3809 ASSERT_COND(p_Manip); 3810 ASSERT_COND(p_Stats); 3811 ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl); 3812 3813 p_Stats->timeout = 3814 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter); 3815 p_Stats->rfdPoolBusy = 3816 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter); 3817 p_Stats->internalBufferBusy = 3818 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy); 3819 p_Stats->externalBufferBusy = 3820 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy); 3821 p_Stats->sgFragments = 3822 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter); 3823 p_Stats->dmaSemaphoreDepletion = 3824 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter); 3825 #if (DPAA_VERSION >= 11) 3826 p_Stats->nonConsistentSp = 3827 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter); 3828 #endif /* (DPAA_VERSION >= 11) */ 3829 3830 if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl) 3831 { 3832 p_Stats->specificHdrStatistics[0].successfullyReassembled = 3833 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter); 3834 p_Stats->specificHdrStatistics[0].validFragments = 3835 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter); 3836 p_Stats->specificHdrStatistics[0].processedFragments = 3837 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter); 3838 p_Stats->specificHdrStatistics[0].malformedFragments = 3839 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter); 3840 p_Stats->specificHdrStatistics[0].autoLearnBusy = 3841 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter); 3842 p_Stats->specificHdrStatistics[0].discardedFragments = 3843 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter); 3844 p_Stats->specificHdrStatistics[0].moreThan16Fragments = 3845 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter); 3846 } 3847 if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl) 3848 { 3849 p_Stats->specificHdrStatistics[1].successfullyReassembled = 3850 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter); 3851 p_Stats->specificHdrStatistics[1].validFragments = 3852 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter); 3853 p_Stats->specificHdrStatistics[1].processedFragments = 3854 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter); 3855 p_Stats->specificHdrStatistics[1].malformedFragments = 3856 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter); 3857 p_Stats->specificHdrStatistics[1].autoLearnBusy = 3858 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter); 3859 p_Stats->specificHdrStatistics[1].discardedFragments = 3860 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter); 3861 p_Stats->specificHdrStatistics[1].moreThan16Fragments = 3862 GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter); 3863 } 3864 return E_OK; 3865 } 3866 3867 static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip, 3868 t_FmPcdManipFragIpStats *p_Stats) 3869 { 3870 t_AdOfTypeContLookup *p_Ad; 3871 3872 ASSERT_COND(p_Manip); 3873 ASSERT_COND(p_Stats); 3874 ASSERT_COND(p_Manip->h_Ad); 3875 ASSERT_COND(p_Manip->fragParams.p_Frag); 3876 3877 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 3878 3879 p_Stats->totalFrames = GET_UINT32(p_Ad->gmask); 3880 p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase) 3881 & 0x00ffffff; 3882 p_Stats->generatedFragments = 3883 GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr); 3884 3885 return E_OK; 3886 } 3887 3888 static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams, 3889 t_FmPcdManip *p_Manip) 3890 { 3891 uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0; 3892 t_FmPcd *p_FmPcd; 3893 #if (DPAA_VERSION == 10) 3894 t_Error err = E_OK; 3895 #endif /* (DPAA_VERSION == 10) */ 3896 3897 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); 3898 SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF, 3899 E_INVALID_VALUE); 3900 3901 p_FmPcd = p_Manip->h_FmPcd; 3902 /* Allocation of fragmentation Action Descriptor */ 3903 p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem( 3904 p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, 3905 FM_PCD_CC_AD_TABLE_ALIGN); 3906 if (!p_Manip->fragParams.p_Frag) 3907 RETURN_ERROR(MAJOR, E_NO_MEMORY, 3908 ("MURAM alloc for Fragmentation table descriptor")); 3909 MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); 3910 3911 /* Prepare the third Ad register (pcAndOffsets)- OperationCode */ 3912 pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION; 3913 3914 /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/ 3915 ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE; 3916 ccAdBaseReg |= (p_ManipParams->dontFragAction 3917 << FM_PCD_MANIP_IP_FRAG_DF_SHIFT); 3918 3919 3920 /* Set Scatter/Gather BPid */ 3921 if (p_ManipParams->sgBpidEn) 3922 { 3923 ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN; 3924 pcAndOffsetsReg |= ((p_ManipParams->sgBpid 3925 << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT) 3926 & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK); 3927 } 3928 3929 /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */ 3930 gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr)) 3931 - p_FmPcd->physicalMuramBase); 3932 #if (DPAA_VERSION == 10) 3933 gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; 3934 #else 3935 gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; 3936 #endif /* (DPAA_VERSION == 10) */ 3937 3938 /* Set all Ad registers */ 3939 WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg); 3940 WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg); 3941 WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg); 3942 3943 /* Saves user's fragmentation manipulation parameters */ 3944 p_Manip->frag = TRUE; 3945 p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; 3946 3947 #if (DPAA_VERSION == 10) 3948 p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid; 3949 3950 /* scratch buffer pool initialization */ 3951 if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK) 3952 { 3953 FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag); 3954 p_Manip->fragParams.p_Frag = NULL; 3955 RETURN_ERROR(MAJOR, err, NO_MSG); 3956 } 3957 #endif /* (DPAA_VERSION == 10) */ 3958 3959 return E_OK; 3960 } 3961 3962 static t_Error IPManip(t_FmPcdManip *p_Manip) 3963 { 3964 t_Error err = E_OK; 3965 t_FmPcd *p_FmPcd; 3966 t_AdOfTypeContLookup *p_Ad; 3967 uint32_t tmpReg32 = 0, tmpRegNia = 0; 3968 3969 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 3970 p_FmPcd = p_Manip->h_FmPcd; 3971 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 3972 3973 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 3974 3975 tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION; 3976 if (p_Manip->frag == TRUE) 3977 { 3978 tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag) 3979 - (p_FmPcd->physicalMuramBase)); 3980 tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation 3981 << FM_PCD_MANIP_IP_MTU_SHIFT; 3982 } 3983 3984 tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; 3985 tmpReg32 |= HMAN_OC_IP_MANIP; 3986 3987 #if (DPAA_VERSION >= 11) 3988 tmpRegNia |= FM_PCD_MANIP_IP_CNIA; 3989 #endif /* (DPAA_VERSION >= 11) */ 3990 3991 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 3992 WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia); 3993 WRITE_UINT32(p_Ad->gmask, 0); 3994 /* Total frame counter - MUST be initialized to zero.*/ 3995 3996 return err; 3997 } 3998 3999 static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams, 4000 t_Handle h_FmPort, t_FmPcdManip *p_Manip, 4001 t_Handle h_Ad, bool validate) 4002 { 4003 t_FmPortGetSetCcParams fmPortGetSetCcParams; 4004 t_Error err; 4005 4006 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 4007 SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION), 4008 E_INVALID_STATE); 4009 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 4010 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4011 4012 UNUSED(h_FmPcd); 4013 UNUSED(h_Ad); 4014 UNUSED(h_PcdParams); 4015 UNUSED(validate); 4016 UNUSED(p_Manip); 4017 4018 fmPortGetSetCcParams.setCcParams.type = 0; 4019 fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE; 4020 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) 4021 RETURN_ERROR(MAJOR, err, NO_MSG); 4022 4023 if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset) 4024 DBG(WARNING, ("manipExtraSpace must be larger than '0'")); 4025 4026 return E_OK; 4027 } 4028 4029 static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams, 4030 t_FmPcdManip *p_Manip) 4031 { 4032 t_AdOfTypeContLookup *p_Ad; 4033 t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams; 4034 t_Error err = E_OK; 4035 uint32_t tmpReg32 = 0; 4036 uint32_t power; 4037 4038 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 4039 SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); 4040 4041 p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec; 4042 4043 SANITY_CHECK_RETURN_ERROR( 4044 !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption, 4045 E_INVALID_VALUE); 4046 SANITY_CHECK_RETURN_ERROR( 4047 !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption, 4048 E_INVALID_VALUE); 4049 SANITY_CHECK_RETURN_ERROR( 4050 !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen, 4051 E_INVALID_VALUE); 4052 SANITY_CHECK_RETURN_ERROR( 4053 !p_IPSecParams->arwSize || p_IPSecParams->arwAddr, 4054 E_INVALID_VALUE); 4055 SANITY_CHECK_RETURN_ERROR( 4056 !p_IPSecParams->arwSize || p_IPSecParams->decryption, 4057 E_INVALID_VALUE); 4058 SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE); 4059 4060 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 4061 4062 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 4063 tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0; 4064 tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0; 4065 tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0; 4066 tmpReg32 |= 4067 (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0; 4068 tmpReg32 |= 4069 (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0; 4070 if (p_IPSecParams->arwSize) 4071 tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM) 4072 & (FM_MURAM_SIZE-1)); 4073 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 4074 4075 tmpReg32 = 0; 4076 if (p_IPSecParams->arwSize) { 4077 NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power); 4078 LOG2(power, power); 4079 tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT; 4080 } 4081 4082 if (p_ManipParams->h_NextManip) 4083 tmpReg32 |= 4084 (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- 4085 (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4; 4086 WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); 4087 4088 tmpReg32 = HMAN_OC_IPSEC_MANIP; 4089 tmpReg32 |= p_IPSecParams->outerIPHdrLen 4090 << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT; 4091 if (p_ManipParams->h_NextManip) 4092 tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN; 4093 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 4094 4095 return err; 4096 } 4097 4098 static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip) 4099 { 4100 t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; 4101 4102 /* Allocation if CAPWAP Action descriptor */ 4103 p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart( 4104 FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, 4105 FM_PCD_CC_AD_TABLE_ALIGN); 4106 if (!p_Manip->reassmParams.capwap.h_Ad) 4107 { 4108 ReleaseManipHandler(p_Manip, p_FmPcd); 4109 RETURN_ERROR(MAJOR, E_NO_MEMORY, 4110 ("Allocation of CAPWAP table descriptor")); 4111 } 4112 4113 memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); 4114 4115 /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */ 4116 return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP); 4117 } 4118 4119 static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd, 4120 t_FmPcdKgSchemeParams *p_Scheme, 4121 t_Handle h_CcTree, uint8_t groupId) 4122 { 4123 uint8_t res; 4124 4125 /* Configures scheme's network environment parameters */ 4126 p_Scheme->netEnvParams.numOfDistinctionUnits = 1; 4127 res = FmPcdNetEnvGetUnitId( 4128 p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), 4129 HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0); 4130 ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); 4131 p_Scheme->netEnvParams.unitIds[0] = res; 4132 4133 /* Configures scheme's next engine parameters*/ 4134 p_Scheme->nextEngine = e_FM_PCD_CC; 4135 p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree; 4136 p_Scheme->kgNextEngineParams.cc.grpId = groupId; 4137 p_Scheme->useHash = TRUE; 4138 4139 /* Configures scheme's key*/ 4140 p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2; 4141 p_Scheme->keyExtractAndHashParams.extractArray[0].type = 4142 e_FM_PCD_EXTRACT_NON_HDR; 4143 p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src = 4144 e_FM_PCD_EXTRACT_FROM_PARSE_RESULT; 4145 p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action = 4146 e_FM_PCD_ACTION_NONE; 4147 p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20; 4148 p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4; 4149 p_Scheme->keyExtractAndHashParams.extractArray[1].type = 4150 e_FM_PCD_EXTRACT_NON_HDR; 4151 p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src = 4152 e_FM_PCD_EXTRACT_FROM_DFLT_VALUE; 4153 p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action = 4154 e_FM_PCD_ACTION_NONE; 4155 p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0; 4156 p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1; 4157 4158 p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0; 4159 p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0; 4160 p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1; 4161 p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA; 4162 p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0; 4163 } 4164 4165 #if (DPAA_VERSION >= 11) 4166 static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip, 4167 t_FmPcdManipReassemCapwapStats *p_Stats) 4168 { 4169 ASSERT_COND(p_Manip); 4170 ASSERT_COND(p_Stats); 4171 ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl); 4172 4173 p_Stats->timeout = 4174 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter); 4175 p_Stats->rfdPoolBusy = 4176 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter); 4177 p_Stats->internalBufferBusy = 4178 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy); 4179 p_Stats->externalBufferBusy = 4180 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy); 4181 p_Stats->sgFragments = 4182 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter); 4183 p_Stats->dmaSemaphoreDepletion = 4184 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter); 4185 p_Stats->exceedMaxReassemblyFrameLen = 4186 GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter); 4187 4188 p_Stats->successfullyReassembled = 4189 GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter); 4190 p_Stats->validFragments = 4191 GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter); 4192 p_Stats->processedFragments = 4193 GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter); 4194 p_Stats->malformedFragments = 4195 GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter); 4196 p_Stats->autoLearnBusy = 4197 GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter); 4198 p_Stats->discardedFragments = 4199 GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter); 4200 p_Stats->moreThan16Fragments = 4201 GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter); 4202 4203 return E_OK; 4204 } 4205 4206 static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip, 4207 t_FmPcdManipFragCapwapStats *p_Stats) 4208 { 4209 t_AdOfTypeContLookup *p_Ad; 4210 4211 ASSERT_COND(p_Manip); 4212 ASSERT_COND(p_Stats); 4213 ASSERT_COND(p_Manip->h_Ad); 4214 ASSERT_COND(p_Manip->fragParams.p_Frag); 4215 4216 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 4217 4218 p_Stats->totalFrames = GET_UINT32(p_Ad->gmask); 4219 4220 return E_OK; 4221 } 4222 4223 static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams, 4224 t_FmPcdManip *p_Manip) 4225 { 4226 uint32_t maxSetNumber = 10000; 4227 t_FmPcdManipReassemCapwapParams reassmManipParams = 4228 p_ManipReassmParams->u.capwapReassem; 4229 t_Error res; 4230 4231 SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE); 4232 SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc, 4233 E_INVALID_HANDLE); 4234 4235 /* Check validation of user's parameter.*/ 4236 if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) 4237 || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000)) 4238 RETURN_ERROR( 4239 MAJOR, E_INVALID_VALUE, 4240 ("timeoutThresholdForReassmProcess should be 1msec - 8sec")); 4241 /* It is recommended that the total number of entries in this table (number of sets * number of ways) 4242 will be twice the number of frames that are expected to be reassembled simultaneously.*/ 4243 if (reassmManipParams.maxNumFramesInProcess 4244 > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2)) 4245 RETURN_ERROR( 4246 MAJOR, 4247 E_INVALID_VALUE, 4248 ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)")); 4249 4250 /* Saves user's reassembly manipulation parameters */ 4251 p_Manip->reassmParams.capwap.relativeSchemeId = 4252 reassmManipParams.relativeSchemeId; 4253 p_Manip->reassmParams.capwap.numOfFramesPerHashEntry = 4254 reassmManipParams.numOfFramesPerHashEntry; 4255 p_Manip->reassmParams.capwap.maxRessembledsSize = 4256 reassmManipParams.maxReassembledFrameLength; 4257 p_Manip->reassmParams.maxNumFramesInProcess = 4258 reassmManipParams.maxNumFramesInProcess; 4259 p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode; 4260 p_Manip->reassmParams.fqidForTimeOutFrames = 4261 reassmManipParams.fqidForTimeOutFrames; 4262 p_Manip->reassmParams.timeoutThresholdForReassmProcess = 4263 reassmManipParams.timeoutThresholdForReassmProcess; 4264 p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId; 4265 p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset; 4266 4267 /* Creates and initializes the Reassembly common parameter table */ 4268 CreateReassCommonTable(p_Manip); 4269 4270 res = SetCapwapReassmManip(p_Manip); 4271 if (res != E_OK) 4272 return res; 4273 4274 return E_OK; 4275 } 4276 4277 static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams, 4278 t_FmPcdManip *p_Manip) 4279 { 4280 t_FmPcd *p_FmPcd; 4281 t_AdOfTypeContLookup *p_Ad; 4282 uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0; 4283 uint32_t tmpReg32 = 0, tmpRegNia = 0; 4284 4285 SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); 4286 SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF, 4287 E_INVALID_VALUE); 4288 p_FmPcd = p_Manip->h_FmPcd; 4289 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 4290 4291 /* Allocation of fragmentation Action Descriptor */ 4292 p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem( 4293 p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, 4294 FM_PCD_CC_AD_TABLE_ALIGN); 4295 if (!p_Manip->fragParams.p_Frag) 4296 RETURN_ERROR(MAJOR, E_NO_MEMORY, 4297 ("MURAM alloc for Fragmentation table descriptor")); 4298 MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); 4299 4300 /* Prepare the third Ad register (pcAndOffsets)- OperationCode */ 4301 pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION; 4302 4303 /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/ 4304 ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE; 4305 ccAdBaseReg |= 4306 (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN : 4307 0; 4308 4309 /* Set Scatter/Gather BPid */ 4310 if (p_ManipParams->sgBpidEn) 4311 { 4312 ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN; 4313 pcAndOffsetsReg |= ((p_ManipParams->sgBpid 4314 << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT) 4315 & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK); 4316 } 4317 4318 /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */ 4319 gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr)) 4320 - p_FmPcd->physicalMuramBase); 4321 gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; 4322 4323 /* Set all Ad registers */ 4324 WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg); 4325 WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg); 4326 WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg); 4327 4328 /* Saves user's fragmentation manipulation parameters */ 4329 p_Manip->frag = TRUE; 4330 p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; 4331 4332 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 4333 4334 tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag) 4335 - (p_FmPcd->physicalMuramBase)); 4336 tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation 4337 << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT; 4338 4339 tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; 4340 tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK; 4341 4342 tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA; 4343 4344 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 4345 WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia); 4346 WRITE_UINT32(p_Ad->gmask, 0); 4347 /* Total frame counter - MUST be initialized to zero.*/ 4348 4349 return E_OK; 4350 } 4351 4352 static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams, 4353 t_Handle h_FmPort, t_FmPcdManip *p_Manip, 4354 t_Handle h_Ad, bool validate) 4355 { 4356 t_FmPortGetSetCcParams fmPortGetSetCcParams; 4357 t_Error err; 4358 4359 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 4360 SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION), 4361 E_INVALID_STATE); 4362 SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); 4363 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); 4364 4365 UNUSED(h_FmPcd); 4366 UNUSED(h_Ad); 4367 UNUSED(h_PcdParams); 4368 UNUSED(validate); 4369 UNUSED(p_Manip); 4370 4371 fmPortGetSetCcParams.setCcParams.type = 0; 4372 fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE; 4373 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) 4374 RETURN_ERROR(MAJOR, err, NO_MSG); 4375 4376 if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset) 4377 DBG(WARNING, ("manipExtraSpace must be larger than '0'")); 4378 4379 return E_OK; 4380 } 4381 4382 static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams, 4383 t_FmPcdManip *p_Manip) 4384 { 4385 t_AdOfTypeContLookup *p_Ad; 4386 t_FmPcdManipSpecialOffloadCapwapParams *p_Params; 4387 t_Error err = E_OK; 4388 uint32_t tmpReg32 = 0; 4389 4390 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 4391 SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); 4392 4393 p_Params = &p_ManipParams->u.specialOffload.u.capwap; 4394 4395 p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; 4396 tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; 4397 tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0; 4398 /* TODO - add 'qosSrc' */ 4399 WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); 4400 4401 tmpReg32 = HMAN_OC_CAPWAP_MANIP; 4402 if (p_ManipParams->h_NextManip) 4403 { 4404 WRITE_UINT32( 4405 p_Ad->matchTblPtr, 4406 (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4); 4407 4408 tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN; 4409 } 4410 4411 WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); 4412 4413 return err; 4414 } 4415 #endif /* (DPAA_VERSION >= 11) */ 4416 4417 static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params, 4418 bool stats) 4419 { 4420 t_FmPcdManip *p_Manip; 4421 t_Error err; 4422 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 4423 4424 p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip)); 4425 if (!p_Manip) 4426 { 4427 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); 4428 return NULL; 4429 } 4430 memset(p_Manip, 0, sizeof(t_FmPcdManip)); 4431 4432 p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type; 4433 memcpy((uint8_t*)&p_Manip->manipParams, p_Params, 4434 sizeof(p_Manip->manipParams)); 4435 4436 if (!stats) 4437 err = CheckManipParamsAndSetType(p_Manip, 4438 (t_FmPcdManipParams *)p_Params); 4439 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4440 else 4441 err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params); 4442 #else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4443 else 4444 { 4445 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!")); 4446 XX_Free(p_Manip); 4447 return NULL; 4448 } 4449 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4450 if (err) 4451 { 4452 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type")); 4453 XX_Free(p_Manip); 4454 return NULL; 4455 } 4456 4457 if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY)) 4458 { 4459 /* In Case of reassembly manipulation the reassembly action descriptor will 4460 be defines later on */ 4461 if (p_Manip->muramAllocate) 4462 { 4463 p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem( 4464 p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, 4465 FM_PCD_CC_AD_TABLE_ALIGN); 4466 if (!p_Manip->h_Ad) 4467 { 4468 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor")); 4469 ReleaseManipHandler(p_Manip, p_FmPcd); 4470 XX_Free(p_Manip); 4471 return NULL; 4472 } 4473 4474 MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); 4475 } 4476 else 4477 { 4478 p_Manip->h_Ad = (t_Handle)XX_Malloc( 4479 FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); 4480 if (!p_Manip->h_Ad) 4481 { 4482 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor")); 4483 ReleaseManipHandler(p_Manip, p_FmPcd); 4484 XX_Free(p_Manip); 4485 return NULL; 4486 } 4487 4488 memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); 4489 } 4490 } 4491 4492 p_Manip->h_FmPcd = h_FmPcd; 4493 4494 return p_Manip; 4495 } 4496 4497 static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip( 4498 t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst) 4499 { 4500 t_CcNodeInformation *p_CcNodeInformation; 4501 t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL; 4502 t_List *p_Pos; 4503 int i = 0; 4504 t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/; 4505 t_CcNodeInformation ccNodeInfo; 4506 4507 NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst) 4508 { 4509 p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); 4510 p_NodePtrOnCurrentMdfManip = 4511 (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode; 4512 4513 ASSERT_COND(p_NodePtrOnCurrentMdfManip); 4514 4515 /* Search in the previous node which exact index points on this current modified node for getting AD */ 4516 for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++) 4517 { 4518 if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine 4519 == e_FM_PCD_CC) 4520 { 4521 if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip 4522 == (t_Handle)p_CrntMdfManip) 4523 { 4524 if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj) 4525 p_AdTablePtOnCrntCurrentMdfNode = 4526 p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd; 4527 else 4528 p_AdTablePtOnCrntCurrentMdfNode = 4529 PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); 4530 4531 memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); 4532 ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode; 4533 EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL); 4534 } 4535 } 4536 } 4537 4538 ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys); 4539 } 4540 } 4541 4542 static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd, 4543 t_FmPcd *p_FmPcd) 4544 { 4545 t_Error err; 4546 4547 /* Copy the HMTD */ 4548 MemCpy8(p_Dest, (uint8_t*)p_Src, 16); 4549 /* Replace the HMCT table pointer */ 4550 WRITE_UINT32( 4551 ((t_Hmtd *)p_Dest)->hmcdBasePtr, 4552 (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase)); 4553 /* Call Host Command to replace HMTD by a new HMTD */ 4554 err = FmHcPcdCcDoDynamicChange( 4555 p_FmPcd->h_Hc, 4556 (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase), 4557 (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase)); 4558 if (err) 4559 REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners.")); 4560 } 4561 4562 static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, 4563 t_Handle h_FmPort, t_Handle h_Manip, 4564 t_Handle h_Ad, bool validate, int level, 4565 t_Handle h_FmTree) 4566 { 4567 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 4568 t_Error err = E_OK; 4569 4570 SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); 4571 4572 UNUSED(level); 4573 UNUSED(h_FmTree); 4574 4575 switch (p_Manip->opcode) 4576 { 4577 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4578 case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): 4579 err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort, 4580 p_Manip, 4581 h_Ad, 4582 validate); 4583 break; 4584 case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): 4585 if (!p_Manip->h_Frag) 4586 break; 4587 case (HMAN_OC_CAPWAP_FRAGMENTATION): 4588 err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree); 4589 break; 4590 case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): 4591 if (p_Manip->h_Frag) 4592 err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate); 4593 break; 4594 case (HMAN_OC_CAPWAP_INDEXED_STATS): 4595 err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip); 4596 break; 4597 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4598 case (HMAN_OC_IP_REASSEMBLY): 4599 err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad, 4600 validate); 4601 break; 4602 case (HMAN_OC_IP_FRAGMENTATION): 4603 err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, 4604 h_Ad, validate); 4605 break; 4606 #if (DPAA_VERSION >= 11) 4607 case (HMAN_OC_CAPWAP_FRAGMENTATION): 4608 err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, 4609 h_Ad, validate); 4610 break; 4611 case (HMAN_OC_CAPWAP_REASSEMBLY): 4612 err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad, 4613 validate); 4614 break; 4615 #endif /* (DPAA_VERSION >= 11) */ 4616 default: 4617 return E_OK; 4618 } 4619 4620 return err; 4621 } 4622 4623 static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad, 4624 bool validate, int level, 4625 t_Handle h_FmTree) 4626 { 4627 4628 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 4629 t_Error err = E_OK; 4630 4631 UNUSED(level); 4632 4633 switch (p_Manip->opcode) 4634 { 4635 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4636 case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): 4637 RETURN_ERROR( 4638 MAJOR, 4639 E_INVALID_STATE, 4640 ("modify node with this type of manipulation is not suppported")); 4641 case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): 4642 4643 if (p_Manip->h_Frag) 4644 { 4645 if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) 4646 && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) 4647 && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) 4648 RETURN_ERROR( 4649 MAJOR, 4650 E_INVALID_STATE, 4651 ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function")); 4652 } 4653 break; 4654 case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): 4655 if (p_Manip->h_Frag) 4656 err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree); 4657 break; 4658 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4659 default: 4660 return E_OK; 4661 } 4662 4663 return err; 4664 } 4665 4666 /*****************************************************************************/ 4667 /* Inter-module API routines */ 4668 /*****************************************************************************/ 4669 4670 t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, 4671 t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, 4672 bool validate, int level, t_Handle h_FmTree, 4673 bool modify) 4674 { 4675 t_Error err; 4676 4677 if (!modify) 4678 err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip, 4679 h_Ad, validate, level, h_FmTree); 4680 else 4681 err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree); 4682 4683 return err; 4684 } 4685 4686 void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add) 4687 { 4688 4689 uint32_t intFlags; 4690 4691 intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock); 4692 if (add) 4693 ((t_FmPcdManip *)h_Manip)->owner++; 4694 else 4695 { 4696 ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner); 4697 ((t_FmPcdManip *)h_Manip)->owner--; 4698 } 4699 XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags); 4700 } 4701 4702 t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip) 4703 { 4704 ASSERT_COND(h_Manip); 4705 return &((t_FmPcdManip *)h_Manip)->nodesLst; 4706 } 4707 4708 t_List *FmPcdManipGetSpinlock(t_Handle h_Manip) 4709 { 4710 ASSERT_COND(h_Manip); 4711 return ((t_FmPcdManip *)h_Manip)->h_Spinlock; 4712 } 4713 4714 t_Error FmPcdManipCheckParamsForCcNextEngine( 4715 t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, 4716 uint32_t *requiredAction) 4717 { 4718 t_FmPcdManip *p_Manip; 4719 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4720 t_Error err = E_OK; 4721 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/ 4722 bool pointFromCc = TRUE; 4723 4724 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); 4725 SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip, 4726 E_NULL_POINTER); 4727 4728 p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip); 4729 *requiredAction = 0; 4730 4731 while (p_Manip) 4732 { 4733 switch (p_Manip->opcode) 4734 { 4735 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4736 case (HMAN_OC_CAPWAP_INDEXED_STATS): 4737 if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) 4738 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); 4739 if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) 4740 p_Manip->cnia = TRUE; 4741 case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): 4742 *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; 4743 case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): 4744 p_Manip->ownerTmp++; 4745 break; 4746 case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): 4747 if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) 4748 && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) 4749 RETURN_ERROR( 4750 MAJOR, 4751 E_INVALID_STATE, 4752 ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE")); 4753 p_Manip->ownerTmp++; 4754 break; 4755 case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): 4756 if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC) 4757 && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) 4758 != CC_PC_GENERIC_IC_HASH_INDEXED)) 4759 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP")); 4760 err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip, 4761 FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)); 4762 if (err) 4763 RETURN_ERROR(MAJOR, err, NO_MSG); 4764 *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; 4765 break; 4766 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4767 case (HMAN_OC_IP_FRAGMENTATION): 4768 case (HMAN_OC_IP_REASSEMBLY): 4769 #if (DPAA_VERSION >= 11) 4770 case (HMAN_OC_CAPWAP_REASSEMBLY): 4771 case (HMAN_OC_CAPWAP_FRAGMENTATION): 4772 #endif /* (DPAA_VERSION >= 11) */ 4773 if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) 4774 RETURN_ERROR( 4775 MAJOR, 4776 E_INVALID_STATE, 4777 ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); 4778 p_Manip->ownerTmp++; 4779 break; 4780 case (HMAN_OC_IPSEC_MANIP): 4781 #if (DPAA_VERSION >= 11) 4782 case (HMAN_OC_CAPWAP_MANIP): 4783 #endif /* (DPAA_VERSION >= 11) */ 4784 p_Manip->ownerTmp++; 4785 break; 4786 case (HMAN_OC): 4787 if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) 4788 && MANIP_IS_CASCADED(p_Manip)) 4789 RETURN_ERROR( 4790 MINOR, 4791 E_INVALID_STATE, 4792 ("Can't have a cascaded manipulation when and Next Engine is CC")); 4793 if (!MANIP_IS_FIRST(p_Manip) && pointFromCc) 4794 RETURN_ERROR( 4795 MAJOR, 4796 E_INVALID_STATE, 4797 ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)")); 4798 break; 4799 default: 4800 RETURN_ERROR( 4801 MAJOR, E_INVALID_STATE, 4802 ("invalid type of header manipulation for this state")); 4803 } 4804 p_Manip = p_Manip->h_NextManip; 4805 pointFromCc = FALSE; 4806 } 4807 return E_OK; 4808 } 4809 4810 4811 t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, 4812 t_Handle h_FmPcdCcNode) 4813 { 4814 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 4815 t_Error err = E_OK; 4816 4817 SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); 4818 SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE); 4819 4820 switch (p_Manip->opcode) 4821 { 4822 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4823 case (HMAN_OC_CAPWAP_INDEXED_STATS): 4824 if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) 4825 RETURN_ERROR( 4826 MAJOR, 4827 E_INVALID_VALUE, 4828 ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys")); 4829 break; 4830 case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): 4831 if (p_Manip->h_Frag) 4832 { 4833 if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) 4834 RETURN_ERROR( 4835 MAJOR, 4836 E_INVALID_VALUE, 4837 ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys")); 4838 err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode)); 4839 if (err) 4840 RETURN_ERROR(MAJOR, err, NO_MSG); 4841 } 4842 break; 4843 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4844 default: 4845 break; 4846 } 4847 4848 return err; 4849 } 4850 4851 void FmPcdManipUpdateAdResultForCc( 4852 t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams, 4853 t_Handle p_Ad, t_Handle *p_AdNewPtr) 4854 { 4855 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 4856 4857 /* This routine creates a Manip AD and can return in "p_AdNewPtr" 4858 * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */ 4859 4860 ASSERT_COND(p_Manip); 4861 ASSERT_COND(p_CcNextEngineParams); 4862 ASSERT_COND(p_Ad); 4863 ASSERT_COND(p_AdNewPtr); 4864 4865 FmPcdManipUpdateOwner(h_Manip, TRUE); 4866 4867 /* According to "type", either build & initialize a new AD (p_AdNew) or initialize 4868 * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */ 4869 switch (p_Manip->opcode) 4870 { 4871 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4872 case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): 4873 case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): 4874 case (HMAN_OC_CAPWAP_INDEXED_STATS): 4875 *p_AdNewPtr = p_Manip->h_Ad; 4876 break; 4877 case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): 4878 case (HMAN_OC_CAPWAP_FRAGMENTATION): 4879 WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid, 4880 ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid); 4881 WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile, 4882 ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile); 4883 WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia, 4884 ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia); 4885 *p_AdNewPtr = NULL; 4886 break; 4887 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4888 case (HMAN_OC_IPSEC_MANIP): 4889 #if (DPAA_VERSION >= 11) 4890 case (HMAN_OC_CAPWAP_MANIP): 4891 #endif /* (DPAA_VERSION >= 11) */ 4892 *p_AdNewPtr = p_Manip->h_Ad; 4893 break; 4894 case (HMAN_OC_IP_FRAGMENTATION): 4895 #if (DPAA_VERSION >= 11) 4896 case (HMAN_OC_CAPWAP_FRAGMENTATION): 4897 #endif /* (DPAA_VERSION >= 11) */ 4898 if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE) 4899 && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid)) 4900 { 4901 memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad, 4902 sizeof(t_AdOfTypeContLookup)); 4903 #if (DPAA_VERSION >= 11) 4904 WRITE_UINT32( 4905 ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, 4906 GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA); 4907 #endif /* (DPAA_VERSION >= 11) */ 4908 *p_AdNewPtr = NULL; 4909 } 4910 else 4911 *p_AdNewPtr = p_Manip->h_Ad; 4912 break; 4913 case (HMAN_OC_IP_REASSEMBLY): 4914 if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip)) 4915 { 4916 if (!p_Manip->reassmParams.ip.ipv6Assigned) 4917 { 4918 *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad; 4919 p_Manip->reassmParams.ip.ipv6Assigned = TRUE; 4920 FmPcdManipUpdateOwner(h_Manip, FALSE); 4921 } 4922 else 4923 { 4924 *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad; 4925 p_Manip->reassmParams.ip.ipv6Assigned = FALSE; 4926 } 4927 } 4928 else 4929 *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad; 4930 memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr, 4931 sizeof(t_AdOfTypeContLookup)); 4932 *p_AdNewPtr = NULL; 4933 break; 4934 #if (DPAA_VERSION >= 11) 4935 case (HMAN_OC_CAPWAP_REASSEMBLY): 4936 *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad; 4937 memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr, 4938 sizeof(t_AdOfTypeContLookup)); 4939 *p_AdNewPtr = NULL; 4940 break; 4941 #endif /* (DPAA_VERSION >= 11) */ 4942 case (HMAN_OC): 4943 /* Allocate and initialize HMTD */ 4944 *p_AdNewPtr = p_Manip->h_Ad; 4945 break; 4946 default: 4947 break; 4948 } 4949 } 4950 4951 void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, 4952 t_Handle *p_AdNewPtr, 4953 uint32_t adTableOffset) 4954 { 4955 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 4956 4957 /* This routine creates a Manip AD and can return in "p_AdNewPtr" 4958 * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */ 4959 ASSERT_COND(p_Manip); 4960 4961 FmPcdManipUpdateOwner(h_Manip, TRUE); 4962 4963 switch (p_Manip->opcode) 4964 { 4965 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 4966 case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): 4967 WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, 4968 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase); 4969 WRITE_UINT32( 4970 ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr, 4971 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr); 4972 WRITE_UINT32( 4973 ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, 4974 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets); 4975 WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask, 4976 ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask); 4977 WRITE_UINT32( 4978 ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, 4979 (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset)); 4980 *p_AdNewPtr = NULL; 4981 break; 4982 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 4983 case (HMAN_OC): 4984 /* Initialize HMTD within the match table*/ 4985 MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); 4986 /* copy the existing HMTD *//* ask Alla - memcpy??? */ 4987 memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd)); 4988 /* update NADEN to be "1"*/ 4989 WRITE_UINT16( 4990 ((t_Hmtd *)p_Ad)->cfg, 4991 (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN)); 4992 /* update next action descriptor */ 4993 WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx, 4994 (uint16_t)(adTableOffset >> 4)); 4995 /* mark that Manip's HMTD is not used */ 4996 *p_AdNewPtr = NULL; 4997 break; 4998 4999 default: 5000 break; 5001 } 5002 } 5003 5004 t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, 5005 t_Handle h_CcTree, t_Handle h_Manip, 5006 bool isIpv4, uint8_t groupId) 5007 { 5008 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 5009 t_FmPcdKgSchemeParams *p_SchemeParams = NULL; 5010 t_Handle h_Scheme; 5011 5012 ASSERT_COND(p_FmPcd); 5013 ASSERT_COND(h_NetEnv); 5014 ASSERT_COND(p_Manip); 5015 5016 /* scheme was already build, no need to check for IPv6 */ 5017 if (p_Manip->reassmParams.ip.h_Ipv4Scheme) 5018 return E_OK; 5019 5020 if (isIpv4) { 5021 h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]); 5022 if (h_Scheme) { 5023 /* scheme was found */ 5024 p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme; 5025 return E_OK; 5026 } 5027 } else { 5028 h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]); 5029 if (h_Scheme) { 5030 /* scheme was found */ 5031 p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme; 5032 return E_OK; 5033 } 5034 } 5035 5036 p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams)); 5037 if (!p_SchemeParams) 5038 RETURN_ERROR(MAJOR, E_NO_MEMORY, 5039 ("Memory allocation failed for scheme")); 5040 5041 /* Configures the IPv4 or IPv6 scheme*/ 5042 memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams)); 5043 p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv; 5044 p_SchemeParams->id.relativeSchemeId = (uint8_t)( 5045 (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] : 5046 p_Manip->reassmParams.ip.relativeSchemeId[1]); 5047 p_SchemeParams->schemeCounter.update = TRUE; 5048 #if (DPAA_VERSION >= 11) 5049 p_SchemeParams->alwaysDirect = TRUE; 5050 p_SchemeParams->bypassFqidGeneration = TRUE; 5051 #else 5052 p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1; 5053 p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/ 5054 #endif /* (DPAA_VERSION >= 11) */ 5055 5056 setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId); 5057 5058 /* Sets the new scheme */ 5059 if (isIpv4) 5060 p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet( 5061 p_FmPcd, p_SchemeParams); 5062 else 5063 p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet( 5064 p_FmPcd, p_SchemeParams); 5065 5066 XX_Free(p_SchemeParams); 5067 5068 return E_OK; 5069 } 5070 5071 t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip) 5072 { 5073 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 5074 5075 ASSERT_COND(p_Manip); 5076 5077 if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) && 5078 !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme)) 5079 FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme); 5080 5081 if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) && 5082 !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme)) 5083 FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme); 5084 5085 return E_OK; 5086 } 5087 5088 bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip) 5089 { 5090 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 5091 5092 ASSERT_COND(p_Manip); 5093 5094 return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6); 5095 } 5096 5097 t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, 5098 t_Handle h_CcTree, t_Handle h_Manip, 5099 uint8_t groupId) 5100 { 5101 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 5102 t_FmPcdKgSchemeParams *p_SchemeParams = NULL; 5103 5104 ASSERT_COND(p_FmPcd); 5105 ASSERT_COND(h_NetEnv); 5106 ASSERT_COND(p_Manip); 5107 5108 /* scheme was already build, no need to check for IPv6 */ 5109 if (p_Manip->reassmParams.capwap.h_Scheme) 5110 return E_OK; 5111 5112 p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams)); 5113 if (!p_SchemeParams) 5114 RETURN_ERROR(MAJOR, E_NO_MEMORY, 5115 ("Memory allocation failed for scheme")); 5116 5117 memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams)); 5118 p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv; 5119 p_SchemeParams->id.relativeSchemeId = 5120 (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId; 5121 p_SchemeParams->schemeCounter.update = TRUE; 5122 p_SchemeParams->bypassFqidGeneration = TRUE; 5123 5124 setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId); 5125 5126 p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd, 5127 p_SchemeParams); 5128 5129 XX_Free(p_SchemeParams); 5130 5131 return E_OK; 5132 } 5133 5134 t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip) 5135 { 5136 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 5137 5138 ASSERT_COND(p_Manip); 5139 5140 if (p_Manip->reassmParams.capwap.h_Scheme) 5141 FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme); 5142 5143 return E_OK; 5144 } 5145 5146 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 5147 t_Handle FmPcdManipApplSpecificBuild(void) 5148 { 5149 t_FmPcdManip *p_Manip; 5150 5151 p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip)); 5152 if (!p_Manip) 5153 { 5154 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); 5155 return NULL; 5156 } 5157 memset(p_Manip, 0, sizeof(t_FmPcdManip)); 5158 5159 p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX; 5160 p_Manip->muramAllocate = FALSE; 5161 5162 p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); 5163 if (!p_Manip->h_Ad) 5164 { 5165 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor")); 5166 XX_Free(p_Manip); 5167 return NULL; 5168 } 5169 5170 memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); 5171 5172 /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/ 5173 /*Application specific = type of flowId index, move internal frame header from data to IC, 5174 SEC errors check*/ 5175 if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK) 5176 { 5177 XX_Free(p_Manip->h_Ad); 5178 XX_Free(p_Manip); 5179 return NULL; 5180 } 5181 return p_Manip; 5182 } 5183 5184 bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip) 5185 { 5186 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; 5187 ASSERT_COND(h_Manip); 5188 5189 return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE); 5190 } 5191 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 5192 /*********************** End of inter-module routines ************************/ 5193 5194 /****************************************/ 5195 /* API Init unit functions */ 5196 /****************************************/ 5197 5198 t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, 5199 t_FmPcdManipParams *p_ManipParams) 5200 { 5201 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 5202 t_FmPcdManip *p_Manip; 5203 t_Error err; 5204 5205 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); 5206 SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL); 5207 5208 p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE); 5209 if (!p_Manip) 5210 return NULL; 5211 5212 if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) 5213 || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION) 5214 || (p_Manip->opcode == HMAN_OC) 5215 || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP) 5216 #if (DPAA_VERSION >= 11) 5217 || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP) 5218 || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) 5219 || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) 5220 #endif /* (DPAA_VERSION >= 11) */ 5221 ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd))) 5222 { 5223 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled")); 5224 XX_Free(p_Manip); 5225 return NULL; 5226 } 5227 p_Manip->h_Spinlock = XX_InitSpinlock(); 5228 if (!p_Manip->h_Spinlock) 5229 { 5230 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); 5231 ReleaseManipHandler(p_Manip, p_FmPcd); 5232 XX_Free(p_Manip); 5233 return NULL; 5234 }INIT_LIST(&p_Manip->nodesLst); 5235 5236 switch (p_Manip->opcode) 5237 { 5238 case (HMAN_OC_IP_REASSEMBLY): 5239 /* IpReassembly */ 5240 err = IpReassembly(&p_ManipParams->u.reassem, p_Manip); 5241 break; 5242 case (HMAN_OC_IP_FRAGMENTATION): 5243 /* IpFragmentation */ 5244 err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip); 5245 if (err) 5246 break; 5247 err = IPManip(p_Manip); 5248 break; 5249 case (HMAN_OC_IPSEC_MANIP): 5250 err = IPSecManip(p_ManipParams, p_Manip); 5251 break; 5252 #if (DPAA_VERSION >= 11) 5253 case (HMAN_OC_CAPWAP_REASSEMBLY): 5254 /* CapwapReassembly */ 5255 err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip); 5256 break; 5257 case (HMAN_OC_CAPWAP_FRAGMENTATION): 5258 /* CapwapFragmentation */ 5259 err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag, 5260 p_Manip); 5261 break; 5262 case (HMAN_OC_CAPWAP_MANIP): 5263 err = CapwapManip(p_ManipParams, p_Manip); 5264 break; 5265 #endif /* (DPAA_VERSION >= 11) */ 5266 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 5267 case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): 5268 /* HmanType1 */ 5269 err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip); 5270 break; 5271 case (HMAN_OC_CAPWAP_FRAGMENTATION): 5272 err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams, 5273 p_Manip, 5274 p_FmPcd, 5275 p_ManipParams->fragOrReasmParams.sgBpid); 5276 if (err) 5277 { 5278 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); 5279 ReleaseManipHandler(p_Manip, p_FmPcd); 5280 XX_Free(p_Manip); 5281 return NULL; 5282 } 5283 if (p_Manip->insrt) 5284 p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; 5285 case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): 5286 /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */ 5287 err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd); 5288 break; 5289 case (HMAN_OC_CAPWAP_REASSEMBLY): 5290 err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams, 5291 p_Manip, 5292 p_FmPcd, 5293 p_ManipParams->fragOrReasmParams.sgBpid); 5294 if (err) 5295 { 5296 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); 5297 ReleaseManipHandler(p_Manip, p_FmPcd); 5298 XX_Free(p_Manip); 5299 return NULL; 5300 } 5301 if (p_Manip->rmv) 5302 p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; 5303 case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): 5304 /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/ 5305 err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip); 5306 break; 5307 case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): 5308 /*Application Specific type 1*/ 5309 err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE); 5310 break; 5311 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 5312 case (HMAN_OC): 5313 /* New Manip */ 5314 err = CreateManipActionNew(p_Manip, p_ManipParams); 5315 break; 5316 default: 5317 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); 5318 ReleaseManipHandler(p_Manip, p_FmPcd); 5319 XX_Free(p_Manip); 5320 return NULL; 5321 } 5322 5323 if (err) 5324 { 5325 REPORT_ERROR(MAJOR, err, NO_MSG); 5326 ReleaseManipHandler(p_Manip, p_FmPcd); 5327 XX_Free(p_Manip); 5328 return NULL; 5329 } 5330 5331 if (p_ManipParams->h_NextManip) 5332 { 5333 /* in the check routine we've verified that h_NextManip has no owners 5334 * and that only supported types are allowed. */ 5335 p_Manip->h_NextManip = p_ManipParams->h_NextManip; 5336 /* save a "prev" pointer in h_NextManip */ 5337 MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip); 5338 FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE); 5339 } 5340 5341 return p_Manip; 5342 } 5343 5344 t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip, 5345 t_FmPcdManipParams *p_ManipParams) 5346 { 5347 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip; 5348 t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd); 5349 t_Error err; 5350 uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL; 5351 t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos; 5352 t_CcNodeInformation *p_CcNodeInfo; 5353 SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); 5354 SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); 5355 5356 INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip); 5357 5358 if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR) 5359 || (p_Manip->type != e_FM_PCD_MANIP_HDR)) 5360 RETURN_ERROR( 5361 MINOR, 5362 E_NOT_SUPPORTED, 5363 ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation.")); 5364 5365 ASSERT_COND(p_Manip->opcode == HMAN_OC); 5366 ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip); 5367 memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams, 5368 sizeof(p_Manip->manipParams)); 5369 p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip; 5370 5371 /* The replacement of the HdrManip depends on the node type.*/ 5372 /* 5373 * (1) If this is an independent node, all its owners should be updated. 5374 * 5375 * (2) If it is the head of a cascaded chain (it does not have a "prev" but 5376 * it has a "next" and it has a "cascaded" indication), the next 5377 * node remains unchanged, and the behavior is as in (1). 5378 * 5379 * (3) If it is not the head, but a part of a cascaded chain, in can be 5380 * also replaced as a regular node with just one owner. 5381 * 5382 * (4) If it is a part of a chain implemented as a unified table, the 5383 * whole table is replaced and the owners of the head node must be updated. 5384 * 5385 */ 5386 /* lock shadow */ 5387 if (!p_FmPcd->p_CcShadow) 5388 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); 5389 5390 if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) 5391 return ERROR_CODE(E_BUSY); 5392 5393 /* this routine creates a new manip action in the CC Shadow. */ 5394 err = CreateManipActionShadow(p_Manip, p_ManipParams); 5395 if (err) 5396 RETURN_ERROR(MINOR, err, NO_MSG); 5397 5398 /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC) 5399 * replace only HMTD and no lcok is required. Otherwise 5400 * lock the whole PCD 5401 * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */ 5402 if (!FmPcdLockTryLockAll(p_FmPcd)) 5403 { 5404 DBG(TRACE, ("FmPcdLockTryLockAll failed")); 5405 return ERROR_CODE(E_BUSY); 5406 } 5407 5408 p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16); 5409 5410 p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip, 5411 e_MANIP_HANDLER_TABLE_OWNER); 5412 ASSERT_COND(p_FirstManip); 5413 5414 if (!NCSW_LIST_IsEmpty(&p_FirstManip->nodesLst)) 5415 UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip( 5416 p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip); 5417 5418 p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD); 5419 ASSERT_COND(p_Hmtd); 5420 BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct, 5421 ((t_FmPcd*)(p_Manip->h_FmPcd))); 5422 5423 NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip) 5424 { 5425 p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); 5426 BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode, 5427 p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd))); 5428 } 5429 5430 p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); 5431 ASSERT_COND(p_WholeHmct); 5432 5433 /* re-build the HMCT n the original location */ 5434 err = CreateManipActionBackToOrig(p_Manip, p_ManipParams); 5435 if (err) 5436 { 5437 RELEASE_LOCK(p_FmPcd->shadowLock); 5438 RETURN_ERROR(MINOR, err, NO_MSG); 5439 } 5440 5441 p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD); 5442 ASSERT_COND(p_Hmtd); 5443 BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct, 5444 ((t_FmPcd*)p_Manip->h_FmPcd)); 5445 5446 /* If NCSW_LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list. 5447 * For each p_Hmct (from list+fixed): 5448 * call Host Command to replace HMTD by a new one */NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip) 5449 { 5450 p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); 5451 BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode, 5452 p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd))); 5453 } 5454 5455 5456 ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip); 5457 5458 FmPcdLockUnlockAll(p_FmPcd); 5459 5460 /* unlock shadow */ 5461 RELEASE_LOCK(p_FmPcd->shadowLock); 5462 5463 return E_OK; 5464 } 5465 5466 t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode) 5467 { 5468 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode; 5469 5470 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 5471 5472 if (p_Manip->owner) 5473 RETURN_ERROR( 5474 MAJOR, 5475 E_INVALID_STATE, 5476 ("This manipulation node not be removed because this node is occupied, first - unbind this node ")); 5477 5478 if (p_Manip->h_NextManip) 5479 { 5480 MANIP_SET_PREV(p_Manip->h_NextManip, NULL); 5481 FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE); 5482 } 5483 5484 if (p_Manip->p_Hmct 5485 && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip))) 5486 FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, 5487 p_Manip->p_Hmct); 5488 5489 if (p_Manip->h_Spinlock) 5490 { 5491 XX_FreeSpinlock(p_Manip->h_Spinlock); 5492 p_Manip->h_Spinlock = NULL; 5493 } 5494 5495 ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd); 5496 5497 XX_Free(h_ManipNode); 5498 5499 return E_OK; 5500 } 5501 5502 t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, 5503 t_FmPcdManipStats *p_FmPcdManipStats) 5504 { 5505 t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode; 5506 5507 SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); 5508 SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER); 5509 5510 switch (p_Manip->opcode) 5511 { 5512 case (HMAN_OC_IP_REASSEMBLY): 5513 return IpReassemblyStats(p_Manip, 5514 &p_FmPcdManipStats->u.reassem.u.ipReassem); 5515 case (HMAN_OC_IP_FRAGMENTATION): 5516 return IpFragmentationStats(p_Manip, 5517 &p_FmPcdManipStats->u.frag.u.ipFrag); 5518 #if (DPAA_VERSION >= 11) 5519 case (HMAN_OC_CAPWAP_REASSEMBLY): 5520 return CapwapReassemblyStats( 5521 p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem); 5522 case (HMAN_OC_CAPWAP_FRAGMENTATION): 5523 return CapwapFragmentationStats( 5524 p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag); 5525 #endif /* (DPAA_VERSION >= 11) */ 5526 default: 5527 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, 5528 ("no statistics to this type of manip")); 5529 } 5530 5531 return E_OK; 5532 } 5533 5534 #if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) 5535 t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams) 5536 { 5537 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 5538 t_FmPcdManip *p_Manip; 5539 t_Error err; 5540 5541 SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL); 5542 SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL); 5543 5544 p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE); 5545 if (!p_Manip) 5546 return NULL; 5547 5548 switch (p_Manip->opcode) 5549 { 5550 case (HMAN_OC_CAPWAP_INDEXED_STATS): 5551 /* Indexed statistics */ 5552 err = IndxStats(p_StatsParams, p_Manip, p_FmPcd); 5553 break; 5554 default: 5555 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type")); 5556 ReleaseManipHandler(p_Manip, p_FmPcd); 5557 XX_Free(p_Manip); 5558 return NULL; 5559 } 5560 5561 if (err) 5562 { 5563 REPORT_ERROR(MAJOR, err, NO_MSG); 5564 ReleaseManipHandler(p_Manip, p_FmPcd); 5565 XX_Free(p_Manip); 5566 return NULL; 5567 } 5568 5569 return p_Manip; 5570 } 5571 #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ 5572