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_kg.c 36 37 @Description FM PCD ... 38 *//***************************************************************************/ 39 #include "std_ext.h" 40 #include "error_ext.h" 41 #include "string_ext.h" 42 #include "debug_ext.h" 43 #include "net_ext.h" 44 #include "fm_port_ext.h" 45 46 #include "fm_common.h" 47 #include "fm_pcd.h" 48 #include "fm_hc.h" 49 #include "fm_pcd_ipc.h" 50 #include "fm_kg.h" 51 #include "fsl_fman_kg.h" 52 53 54 /****************************************/ 55 /* static functions */ 56 /****************************************/ 57 58 static uint32_t KgHwLock(t_Handle h_FmPcdKg) 59 { 60 ASSERT_COND(h_FmPcdKg); 61 return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock); 62 } 63 64 static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags) 65 { 66 ASSERT_COND(h_FmPcdKg); 67 XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags); 68 } 69 70 static uint32_t KgSchemeLock(t_Handle h_Scheme) 71 { 72 ASSERT_COND(h_Scheme); 73 return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); 74 } 75 76 static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags) 77 { 78 ASSERT_COND(h_Scheme); 79 FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags); 80 } 81 82 static bool KgSchemeFlagTryLock(t_Handle h_Scheme) 83 { 84 ASSERT_COND(h_Scheme); 85 return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); 86 } 87 88 static void KgSchemeFlagUnlock(t_Handle h_Scheme) 89 { 90 ASSERT_COND(h_Scheme); 91 FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); 92 } 93 94 static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar) 95 { 96 97 struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 98 99 if (fman_kg_write_ar_wait(regs, fmkg_ar)) 100 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation")); 101 102 return E_OK; 103 } 104 105 static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code) 106 { 107 int i; 108 109 switch (code) 110 { 111 case (KG_SCH_GEN_PARSE_RESULT_N_FQID): 112 case (KG_SCH_GEN_DEFAULT): 113 case (KG_SCH_GEN_NEXTHDR): 114 for (i=0 ; i<numOfSwDefaults ; i++) 115 if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA) 116 return swDefaults[i].dfltSelect; 117 break; 118 case (KG_SCH_GEN_SHIM1): 119 case (KG_SCH_GEN_SHIM2): 120 case (KG_SCH_GEN_IP_PID_NO_V): 121 case (KG_SCH_GEN_ETH_NO_V): 122 case (KG_SCH_GEN_SNAP_NO_V): 123 case (KG_SCH_GEN_VLAN1_NO_V): 124 case (KG_SCH_GEN_VLAN2_NO_V): 125 case (KG_SCH_GEN_ETH_TYPE_NO_V): 126 case (KG_SCH_GEN_PPP_NO_V): 127 case (KG_SCH_GEN_MPLS1_NO_V): 128 case (KG_SCH_GEN_MPLS_LAST_NO_V): 129 case (KG_SCH_GEN_L3_NO_V): 130 case (KG_SCH_GEN_IP2_NO_V): 131 case (KG_SCH_GEN_GRE_NO_V): 132 case (KG_SCH_GEN_L4_NO_V): 133 for (i=0 ; i<numOfSwDefaults ; i++) 134 if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V) 135 return swDefaults[i].dfltSelect; 136 break; 137 case (KG_SCH_GEN_START_OF_FRM): 138 case (KG_SCH_GEN_ETH): 139 case (KG_SCH_GEN_SNAP): 140 case (KG_SCH_GEN_VLAN1): 141 case (KG_SCH_GEN_VLAN2): 142 case (KG_SCH_GEN_ETH_TYPE): 143 case (KG_SCH_GEN_PPP): 144 case (KG_SCH_GEN_MPLS1): 145 case (KG_SCH_GEN_MPLS2): 146 case (KG_SCH_GEN_MPLS3): 147 case (KG_SCH_GEN_MPLS_LAST): 148 case (KG_SCH_GEN_IPV4): 149 case (KG_SCH_GEN_IPV6): 150 case (KG_SCH_GEN_IPV4_TUNNELED): 151 case (KG_SCH_GEN_IPV6_TUNNELED): 152 case (KG_SCH_GEN_MIN_ENCAP): 153 case (KG_SCH_GEN_GRE): 154 case (KG_SCH_GEN_TCP): 155 case (KG_SCH_GEN_UDP): 156 case (KG_SCH_GEN_IPSEC_AH): 157 case (KG_SCH_GEN_SCTP): 158 case (KG_SCH_GEN_DCCP): 159 case (KG_SCH_GEN_IPSEC_ESP): 160 for (i=0 ; i<numOfSwDefaults ; i++) 161 if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA) 162 return swDefaults[i].dfltSelect; 163 break; 164 default: 165 break; 166 } 167 168 return e_FM_PCD_KG_DFLT_ILLEGAL; 169 } 170 171 static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset) 172 { 173 *p_Offset = 0; 174 175 switch (src) 176 { 177 case (e_FM_PCD_EXTRACT_FROM_FRAME_START): 178 return KG_SCH_GEN_START_OF_FRM; 179 case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE): 180 return KG_SCH_GEN_DEFAULT; 181 case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT): 182 return KG_SCH_GEN_PARSE_RESULT_N_FQID; 183 case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID): 184 *p_Offset = 32; 185 return KG_SCH_GEN_PARSE_RESULT_N_FQID; 186 case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE): 187 return KG_SCH_GEN_NEXTHDR; 188 default: 189 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); 190 return 0; 191 } 192 } 193 194 static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation) 195 { 196 if (!ignoreProtocolValidation) 197 switch (hdr) 198 { 199 case (HEADER_TYPE_NONE): 200 ASSERT_COND(FALSE); 201 case (HEADER_TYPE_ETH): 202 return KG_SCH_GEN_ETH; 203 case (HEADER_TYPE_LLC_SNAP): 204 return KG_SCH_GEN_SNAP; 205 case (HEADER_TYPE_PPPoE): 206 return KG_SCH_GEN_PPP; 207 case (HEADER_TYPE_MPLS): 208 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 209 return KG_SCH_GEN_MPLS1; 210 if (hdrIndex == e_FM_PCD_HDR_INDEX_2) 211 return KG_SCH_GEN_MPLS2; 212 if (hdrIndex == e_FM_PCD_HDR_INDEX_3) 213 return KG_SCH_GEN_MPLS3; 214 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 215 return KG_SCH_GEN_MPLS_LAST; 216 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); 217 return 0; 218 case (HEADER_TYPE_IPv4): 219 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 220 return KG_SCH_GEN_IPV4; 221 if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)) 222 return KG_SCH_GEN_IPV4_TUNNELED; 223 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index")); 224 return 0; 225 case (HEADER_TYPE_IPv6): 226 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 227 return KG_SCH_GEN_IPV6; 228 if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)) 229 return KG_SCH_GEN_IPV6_TUNNELED; 230 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index")); 231 return 0; 232 case (HEADER_TYPE_GRE): 233 return KG_SCH_GEN_GRE; 234 case (HEADER_TYPE_TCP): 235 return KG_SCH_GEN_TCP; 236 case (HEADER_TYPE_UDP): 237 return KG_SCH_GEN_UDP; 238 case (HEADER_TYPE_IPSEC_AH): 239 return KG_SCH_GEN_IPSEC_AH; 240 case (HEADER_TYPE_IPSEC_ESP): 241 return KG_SCH_GEN_IPSEC_ESP; 242 case (HEADER_TYPE_SCTP): 243 return KG_SCH_GEN_SCTP; 244 case (HEADER_TYPE_DCCP): 245 return KG_SCH_GEN_DCCP; 246 default: 247 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 248 return 0; 249 } 250 else 251 switch (hdr) 252 { 253 case (HEADER_TYPE_NONE): 254 ASSERT_COND(FALSE); 255 case (HEADER_TYPE_ETH): 256 return KG_SCH_GEN_ETH_NO_V; 257 case (HEADER_TYPE_LLC_SNAP): 258 return KG_SCH_GEN_SNAP_NO_V; 259 case (HEADER_TYPE_PPPoE): 260 return KG_SCH_GEN_PPP_NO_V; 261 case (HEADER_TYPE_MPLS): 262 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 263 return KG_SCH_GEN_MPLS1_NO_V; 264 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 265 return KG_SCH_GEN_MPLS_LAST_NO_V; 266 if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) ) 267 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported")); 268 else 269 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); 270 return 0; 271 case (HEADER_TYPE_IPv4): 272 case (HEADER_TYPE_IPv6): 273 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 274 return KG_SCH_GEN_L3_NO_V; 275 if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)) 276 return KG_SCH_GEN_IP2_NO_V; 277 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index")); 278 case (HEADER_TYPE_MINENCAP): 279 return KG_SCH_GEN_IP2_NO_V; 280 case (HEADER_TYPE_USER_DEFINED_L3): 281 return KG_SCH_GEN_L3_NO_V; 282 case (HEADER_TYPE_GRE): 283 return KG_SCH_GEN_GRE_NO_V; 284 case (HEADER_TYPE_TCP): 285 case (HEADER_TYPE_UDP): 286 case (HEADER_TYPE_IPSEC_AH): 287 case (HEADER_TYPE_IPSEC_ESP): 288 case (HEADER_TYPE_SCTP): 289 case (HEADER_TYPE_DCCP): 290 return KG_SCH_GEN_L4_NO_V; 291 case (HEADER_TYPE_USER_DEFINED_SHIM1): 292 return KG_SCH_GEN_SHIM1; 293 case (HEADER_TYPE_USER_DEFINED_SHIM2): 294 return KG_SCH_GEN_SHIM2; 295 default: 296 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 297 return 0; 298 } 299 } 300 static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex) 301 { 302 if (!ignoreProtocolValidation) 303 switch (hdr) 304 { 305 case (HEADER_TYPE_NONE): 306 ASSERT_COND(FALSE); 307 break; 308 case (HEADER_TYPE_ETH): 309 switch (field.eth) 310 { 311 case (NET_HEADER_FIELD_ETH_TYPE): 312 return KG_SCH_GEN_ETH_TYPE; 313 default: 314 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 315 return 0; 316 } 317 break; 318 case (HEADER_TYPE_VLAN): 319 switch (field.vlan) 320 { 321 case (NET_HEADER_FIELD_VLAN_TCI): 322 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 323 return KG_SCH_GEN_VLAN1; 324 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 325 return KG_SCH_GEN_VLAN2; 326 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index")); 327 return 0; 328 } 329 break; 330 case (HEADER_TYPE_MPLS): 331 case (HEADER_TYPE_IPSEC_AH): 332 case (HEADER_TYPE_IPSEC_ESP): 333 case (HEADER_TYPE_LLC_SNAP): 334 case (HEADER_TYPE_PPPoE): 335 case (HEADER_TYPE_IPv4): 336 case (HEADER_TYPE_IPv6): 337 case (HEADER_TYPE_GRE): 338 case (HEADER_TYPE_MINENCAP): 339 case (HEADER_TYPE_USER_DEFINED_L3): 340 case (HEADER_TYPE_TCP): 341 case (HEADER_TYPE_UDP): 342 case (HEADER_TYPE_SCTP): 343 case (HEADER_TYPE_DCCP): 344 case (HEADER_TYPE_USER_DEFINED_L4): 345 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 346 return 0; 347 default: 348 break; 349 350 } 351 else 352 switch (hdr) 353 { 354 case (HEADER_TYPE_NONE): 355 ASSERT_COND(FALSE); 356 break; 357 case (HEADER_TYPE_ETH): 358 switch (field.eth) 359 { 360 case (NET_HEADER_FIELD_ETH_TYPE): 361 return KG_SCH_GEN_ETH_TYPE_NO_V; 362 default: 363 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 364 return 0; 365 } 366 break; 367 case (HEADER_TYPE_VLAN): 368 switch (field.vlan) 369 { 370 case (NET_HEADER_FIELD_VLAN_TCI) : 371 if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 372 return KG_SCH_GEN_VLAN1_NO_V; 373 if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 374 return KG_SCH_GEN_VLAN2_NO_V; 375 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index")); 376 return 0; 377 } 378 break; 379 case (HEADER_TYPE_IPv4): 380 switch (field.ipv4) 381 { 382 case (NET_HEADER_FIELD_IPv4_PROTO): 383 return KG_SCH_GEN_IP_PID_NO_V; 384 default: 385 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 386 return 0; 387 } 388 break; 389 case (HEADER_TYPE_IPv6): 390 switch (field.ipv6) 391 { 392 case (NET_HEADER_FIELD_IPv6_NEXT_HDR): 393 return KG_SCH_GEN_IP_PID_NO_V; 394 default: 395 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 396 return 0; 397 } 398 break; 399 case (HEADER_TYPE_MPLS): 400 case (HEADER_TYPE_LLC_SNAP): 401 case (HEADER_TYPE_PPPoE): 402 case (HEADER_TYPE_GRE): 403 case (HEADER_TYPE_MINENCAP): 404 case (HEADER_TYPE_USER_DEFINED_L3): 405 case (HEADER_TYPE_TCP): 406 case (HEADER_TYPE_UDP): 407 case (HEADER_TYPE_IPSEC_AH): 408 case (HEADER_TYPE_IPSEC_ESP): 409 case (HEADER_TYPE_SCTP): 410 case (HEADER_TYPE_DCCP): 411 case (HEADER_TYPE_USER_DEFINED_L4): 412 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 413 return 0; 414 default: 415 break; 416 } 417 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported")); 418 return 0; 419 } 420 421 static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field) 422 { 423 UNUSED(p_FmPcd); 424 425 switch (hdr) 426 { 427 case (HEADER_TYPE_NONE): 428 ASSERT_COND(FALSE); 429 break; 430 case (HEADER_TYPE_ETH): 431 switch (field.eth) 432 { 433 case (NET_HEADER_FIELD_ETH_DA): 434 return KG_SCH_KN_MACDST; 435 case (NET_HEADER_FIELD_ETH_SA): 436 return KG_SCH_KN_MACSRC; 437 case (NET_HEADER_FIELD_ETH_TYPE): 438 return KG_SCH_KN_ETYPE; 439 default: 440 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 441 return 0; 442 } 443 case (HEADER_TYPE_LLC_SNAP): 444 switch (field.llcSnap) 445 { 446 case (NET_HEADER_FIELD_LLC_SNAP_TYPE): 447 return KG_SCH_KN_ETYPE; 448 default: 449 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 450 return 0; 451 } 452 case (HEADER_TYPE_VLAN): 453 switch (field.vlan) 454 { 455 case (NET_HEADER_FIELD_VLAN_TCI): 456 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 457 return KG_SCH_KN_TCI1; 458 if (index == e_FM_PCD_HDR_INDEX_LAST) 459 return KG_SCH_KN_TCI2; 460 else 461 { 462 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 463 return 0; 464 } 465 default: 466 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 467 return 0; 468 } 469 case (HEADER_TYPE_MPLS): 470 switch (field.mpls) 471 { 472 case (NET_HEADER_FIELD_MPLS_LABEL_STACK): 473 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 474 return KG_SCH_KN_MPLS1; 475 if (index == e_FM_PCD_HDR_INDEX_2) 476 return KG_SCH_KN_MPLS2; 477 if (index == e_FM_PCD_HDR_INDEX_LAST) 478 return KG_SCH_KN_MPLS_LAST; 479 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index")); 480 return 0; 481 default: 482 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 483 return 0; 484 } 485 case (HEADER_TYPE_IPv4): 486 switch (field.ipv4) 487 { 488 case (NET_HEADER_FIELD_IPv4_SRC_IP): 489 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 490 return KG_SCH_KN_IPSRC1; 491 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 492 return KG_SCH_KN_IPSRC2; 493 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 494 return 0; 495 case (NET_HEADER_FIELD_IPv4_DST_IP): 496 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 497 return KG_SCH_KN_IPDST1; 498 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 499 return KG_SCH_KN_IPDST2; 500 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 501 return 0; 502 case (NET_HEADER_FIELD_IPv4_PROTO): 503 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 504 return KG_SCH_KN_PTYPE1; 505 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 506 return KG_SCH_KN_PTYPE2; 507 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 508 return 0; 509 case (NET_HEADER_FIELD_IPv4_TOS): 510 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 511 return KG_SCH_KN_IPTOS_TC1; 512 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 513 return KG_SCH_KN_IPTOS_TC2; 514 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 515 return 0; 516 default: 517 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 518 return 0; 519 } 520 case (HEADER_TYPE_IPv6): 521 switch (field.ipv6) 522 { 523 case (NET_HEADER_FIELD_IPv6_SRC_IP): 524 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 525 return KG_SCH_KN_IPSRC1; 526 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 527 return KG_SCH_KN_IPSRC2; 528 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 529 return 0; 530 case (NET_HEADER_FIELD_IPv6_DST_IP): 531 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 532 return KG_SCH_KN_IPDST1; 533 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 534 return KG_SCH_KN_IPDST2; 535 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 536 return 0; 537 case (NET_HEADER_FIELD_IPv6_NEXT_HDR): 538 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 539 return KG_SCH_KN_PTYPE1; 540 if (index == e_FM_PCD_HDR_INDEX_2) 541 return KG_SCH_KN_PTYPE2; 542 if (index == e_FM_PCD_HDR_INDEX_LAST) 543 #ifdef FM_KG_NO_IPPID_SUPPORT 544 if (p_FmPcd->fmRevInfo.majorRev < 6) 545 return KG_SCH_KN_PTYPE2; 546 #endif /* FM_KG_NO_IPPID_SUPPORT */ 547 return KG_SCH_KN_IPPID; 548 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 549 return 0; 550 case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC): 551 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 552 return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1); 553 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 554 return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2); 555 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 556 return 0; 557 case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC): 558 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 559 return KG_SCH_KN_IPTOS_TC1; 560 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 561 return KG_SCH_KN_IPTOS_TC2; 562 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 563 return 0; 564 case (NET_HEADER_FIELD_IPv6_FL): 565 if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 566 return KG_SCH_KN_IPV6FL1; 567 if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) 568 return KG_SCH_KN_IPV6FL2; 569 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 570 return 0; 571 default: 572 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 573 return 0; 574 } 575 case (HEADER_TYPE_GRE): 576 switch (field.gre) 577 { 578 case (NET_HEADER_FIELD_GRE_TYPE): 579 return KG_SCH_KN_GREPTYPE; 580 default: 581 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 582 return 0; 583 } 584 case (HEADER_TYPE_MINENCAP): 585 switch (field.minencap) 586 { 587 case (NET_HEADER_FIELD_MINENCAP_SRC_IP): 588 return KG_SCH_KN_IPSRC2; 589 case (NET_HEADER_FIELD_MINENCAP_DST_IP): 590 return KG_SCH_KN_IPDST2; 591 case (NET_HEADER_FIELD_MINENCAP_TYPE): 592 return KG_SCH_KN_PTYPE2; 593 default: 594 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 595 return 0; 596 } 597 case (HEADER_TYPE_TCP): 598 switch (field.tcp) 599 { 600 case (NET_HEADER_FIELD_TCP_PORT_SRC): 601 return KG_SCH_KN_L4PSRC; 602 case (NET_HEADER_FIELD_TCP_PORT_DST): 603 return KG_SCH_KN_L4PDST; 604 case (NET_HEADER_FIELD_TCP_FLAGS): 605 return KG_SCH_KN_TFLG; 606 default: 607 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 608 return 0; 609 } 610 case (HEADER_TYPE_UDP): 611 switch (field.udp) 612 { 613 case (NET_HEADER_FIELD_UDP_PORT_SRC): 614 return KG_SCH_KN_L4PSRC; 615 case (NET_HEADER_FIELD_UDP_PORT_DST): 616 return KG_SCH_KN_L4PDST; 617 default: 618 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 619 return 0; 620 } 621 case (HEADER_TYPE_IPSEC_AH): 622 switch (field.ipsecAh) 623 { 624 case (NET_HEADER_FIELD_IPSEC_AH_SPI): 625 return KG_SCH_KN_IPSEC_SPI; 626 case (NET_HEADER_FIELD_IPSEC_AH_NH): 627 return KG_SCH_KN_IPSEC_NH; 628 default: 629 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 630 return 0; 631 } 632 case (HEADER_TYPE_IPSEC_ESP): 633 switch (field.ipsecEsp) 634 { 635 case (NET_HEADER_FIELD_IPSEC_ESP_SPI): 636 return KG_SCH_KN_IPSEC_SPI; 637 default: 638 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 639 return 0; 640 } 641 case (HEADER_TYPE_SCTP): 642 switch (field.sctp) 643 { 644 case (NET_HEADER_FIELD_SCTP_PORT_SRC): 645 return KG_SCH_KN_L4PSRC; 646 case (NET_HEADER_FIELD_SCTP_PORT_DST): 647 return KG_SCH_KN_L4PDST; 648 default: 649 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 650 return 0; 651 } 652 case (HEADER_TYPE_DCCP): 653 switch (field.dccp) 654 { 655 case (NET_HEADER_FIELD_DCCP_PORT_SRC): 656 return KG_SCH_KN_L4PSRC; 657 case (NET_HEADER_FIELD_DCCP_PORT_DST): 658 return KG_SCH_KN_L4PDST; 659 default: 660 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 661 return 0; 662 } 663 case (HEADER_TYPE_PPPoE): 664 switch (field.pppoe) 665 { 666 case (NET_HEADER_FIELD_PPPoE_PID): 667 return KG_SCH_KN_PPPID; 668 case (NET_HEADER_FIELD_PPPoE_SID): 669 return KG_SCH_KN_PPPSID; 670 default: 671 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 672 return 0; 673 } 674 default: 675 break; 676 677 } 678 679 REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 680 return 0; 681 } 682 683 684 static uint8_t GetKnownFieldId(uint32_t bitMask) 685 { 686 uint8_t cnt = 0; 687 688 while (bitMask) 689 if (bitMask & 0x80000000) 690 break; 691 else 692 { 693 cnt++; 694 bitMask <<= 1; 695 } 696 return cnt; 697 698 } 699 700 static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid) 701 { 702 uint8_t i, mask, numOfOnesToClear, walking1Mask = 1; 703 704 /* bitOffset 1-7 --> mask 0x1-0x7F */ 705 if (bitOffset<8) 706 { 707 mask = 0; 708 for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1) 709 mask |= walking1Mask; 710 } 711 else 712 { 713 mask = 0xFF; 714 numOfOnesToClear = 0; 715 if (fqid && bitOffset>24) 716 /* bitOffset 25-31 --> mask 0xFE-0x80 */ 717 numOfOnesToClear = (uint8_t)(bitOffset-24); 718 else 719 /* bitOffset 9-15 --> mask 0xFE-0x80 */ 720 if (!fqid && bitOffset>8) 721 numOfOnesToClear = (uint8_t)(bitOffset-8); 722 for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1) 723 mask &= ~walking1Mask; 724 /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/ 725 } 726 return mask; 727 } 728 729 static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) 730 { 731 t_FmPcdKg *p_FmPcdKg; 732 t_FmPcdKgScheme *p_Scheme; 733 uint32_t intFlags; 734 uint8_t relativeSchemeId; 735 int i; 736 737 p_FmPcdKg = p_FmPcd->p_FmPcdKg; 738 739 /* for each scheme - update owners counters */ 740 for (i = 0; i < p_BindPort->numOfSchemes; i++) 741 { 742 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); 743 ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES); 744 745 p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId]; 746 747 /* increment owners number */ 748 intFlags = KgSchemeLock(p_Scheme); 749 p_Scheme->owners++; 750 KgSchemeUnlock(p_Scheme, intFlags); 751 } 752 } 753 754 static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) 755 { 756 t_FmPcdKg *p_FmPcdKg; 757 t_FmPcdKgScheme *p_Scheme; 758 uint32_t intFlags; 759 uint8_t relativeSchemeId; 760 int i; 761 762 p_FmPcdKg = p_FmPcd->p_FmPcdKg; 763 764 /* for each scheme - update owners counters */ 765 for (i = 0; i < p_BindPort->numOfSchemes; i++) 766 { 767 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); 768 ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES); 769 770 p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId]; 771 772 /* increment owners number */ 773 ASSERT_COND(p_Scheme->owners); 774 intFlags = KgSchemeLock(p_Scheme); 775 p_Scheme->owners--; 776 KgSchemeUnlock(p_Scheme, intFlags); 777 } 778 } 779 780 static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set) 781 { 782 /* this routine is locked by the calling routine */ 783 ASSERT_COND(p_Scheme); 784 ASSERT_COND(p_Scheme->valid); 785 786 if (set) 787 p_Scheme->requiredActionFlag = TRUE; 788 else 789 { 790 p_Scheme->requiredAction = 0; 791 p_Scheme->requiredActionFlag = FALSE; 792 } 793 } 794 795 static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add) 796 { 797 struct fman_kg_regs *p_KgRegs; 798 799 uint32_t tmpKgarReg = 0, intFlags; 800 t_Error err = E_OK; 801 802 /* The calling routine had locked the port, so for each port only one core can access 803 * (so we don't need a lock here) */ 804 805 if (p_FmPcd->h_Hc) 806 return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add); 807 808 p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 809 810 tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId); 811 /* lock a common KG reg */ 812 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 813 err = WriteKgarWait(p_FmPcd, tmpKgarReg); 814 if (err) 815 { 816 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 817 RETURN_ERROR(MINOR, err, NO_MSG); 818 } 819 820 fman_kg_write_sp(p_KgRegs, spReg, add); 821 822 tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId); 823 824 err = WriteKgarWait(p_FmPcd, tmpKgarReg); 825 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 826 return err; 827 } 828 829 static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg) 830 { 831 struct fman_kg_regs *p_KgRegs; 832 uint32_t tmpKgarReg, intFlags; 833 t_Error err; 834 835 p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 836 837 if (p_FmPcd->h_Hc) 838 { 839 err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg); 840 return err; 841 } 842 843 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 844 fman_kg_write_cpp(p_KgRegs, cppReg); 845 tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId); 846 err = WriteKgarWait(p_FmPcd, tmpKgarReg); 847 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 848 849 return err; 850 } 851 852 static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId) 853 { 854 uint32_t tmpKgpeCpp; 855 856 tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8); 857 tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT); 858 859 return tmpKgpeCpp; 860 } 861 862 static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) 863 { 864 uint32_t tmpKgpeCpp = 0; 865 866 tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId); 867 return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp); 868 } 869 870 static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId) 871 { 872 KgWriteCpp(p_FmPcd, hardwarePortId, 0); 873 } 874 875 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) 876 static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId) 877 { 878 return (uint32_t)(FM_KG_KGAR_GO | 879 FM_KG_KGAR_READ | 880 FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | 881 DUMMY_PORT_ID | 882 ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | 883 FM_PCD_KG_KGAR_WSEL_MASK); 884 885 /* if we ever want to write 1 by 1, use: 886 sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP))); 887 */ 888 } 889 #endif /* (defined(DEBUG_ERRORS) && ... */ 890 891 static void PcdKgErrorException(t_Handle h_FmPcd) 892 { 893 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 894 uint32_t event,schemeIndexes = 0, index = 0; 895 struct fman_kg_regs *p_KgRegs; 896 897 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 898 p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 899 fman_kg_get_event(p_KgRegs, &event, &schemeIndexes); 900 901 if (event & FM_EX_KG_DOUBLE_ECC) 902 p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC); 903 if (event & FM_EX_KG_KEYSIZE_OVERFLOW) 904 { 905 if (schemeIndexes) 906 { 907 while (schemeIndexes) 908 { 909 if (schemeIndexes & 0x1) 910 p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index)); 911 schemeIndexes >>= 1; 912 index+=1; 913 } 914 } 915 else /* this should happen only when interrupt is forced. */ 916 p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW); 917 } 918 } 919 920 static t_Error KgInitGuest(t_FmPcd *p_FmPcd) 921 { 922 t_Error err = E_OK; 923 t_FmPcdIpcKgSchemesParams kgAlloc; 924 uint32_t replyLength; 925 t_FmPcdIpcReply reply; 926 t_FmPcdIpcMsg msg; 927 928 ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID); 929 930 /* in GUEST_PARTITION, we use the IPC */ 931 memset(&reply, 0, sizeof(reply)); 932 memset(&msg, 0, sizeof(msg)); 933 memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams)); 934 kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; 935 kgAlloc.guestId = p_FmPcd->guestId; 936 msg.msgId = FM_PCD_ALLOC_KG_SCHEMES; 937 memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 938 replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t); 939 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 940 (uint8_t*)&msg, 941 sizeof(msg.msgId) + sizeof(kgAlloc), 942 (uint8_t*)&reply, 943 &replyLength, 944 NULL, 945 NULL)) != E_OK) 946 RETURN_ERROR(MAJOR, err, NO_MSG); 947 if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t))) 948 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 949 memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)); 950 951 return (t_Error)reply.error; 952 } 953 954 static t_Error KgInitMaster(t_FmPcd *p_FmPcd) 955 { 956 t_Error err = E_OK; 957 struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 958 959 ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); 960 961 if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC) 962 FmEnableRamsEcc(p_FmPcd->h_Fm); 963 964 fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd)); 965 966 /* register even if no interrupts enabled, to allow future enablement */ 967 FmRegisterIntr(p_FmPcd->h_Fm, 968 e_FM_MOD_KG, 969 0, 970 e_FM_INTR_TYPE_ERR, 971 PcdKgErrorException, 972 p_FmPcd); 973 974 fman_kg_enable_scheme_interrupts(p_Regs); 975 976 if (p_FmPcd->p_FmPcdKg->numOfSchemes) 977 { 978 err = FmPcdKgAllocSchemes(p_FmPcd, 979 p_FmPcd->p_FmPcdKg->numOfSchemes, 980 p_FmPcd->guestId, 981 p_FmPcd->p_FmPcdKg->schemesIds); 982 if (err) 983 RETURN_ERROR(MINOR, err, NO_MSG); 984 } 985 986 return E_OK; 987 } 988 989 static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme) 990 { 991 ASSERT_COND(!p_Scheme->valid); 992 if (p_Scheme->netEnvId != ILLEGAL_NETENV) 993 FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId); 994 p_Scheme->valid = TRUE; 995 } 996 997 static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme) 998 { 999 if (p_Scheme->owners) 1000 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to")); 1001 1002 if (p_Scheme->netEnvId != ILLEGAL_NETENV) 1003 FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId); 1004 p_Scheme->valid = FALSE; 1005 1006 return E_OK; 1007 } 1008 1009 static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme, 1010 t_FmPcdKgSchemeParams *p_SchemeParams, 1011 struct fman_kg_scheme_regs *p_SchemeRegs) 1012 { 1013 t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd); 1014 uint32_t grpBits = 0; 1015 uint8_t grpBase; 1016 bool direct=TRUE, absolute=FALSE; 1017 uint16_t profileId=0, numOfProfiles=0, relativeProfileId; 1018 t_Error err = E_OK; 1019 int i = 0; 1020 t_NetEnvParams netEnvParams; 1021 uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp; 1022 t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL; 1023 uint8_t j, curr, idx; 1024 uint8_t id, shift=0, code=0, offset=0, size=0; 1025 t_FmPcdExtractEntry *p_Extract = NULL; 1026 t_FmPcdKgExtractedOrParams *p_ExtractOr; 1027 bool generic = FALSE; 1028 t_KnownFieldsMasks bitMask; 1029 e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0; 1030 t_FmPcdKgSchemesExtracts *p_LocalExtractsArray; 1031 uint8_t numOfSwDefaults = 0; 1032 t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS]; 1033 uint8_t currGenId = 0; 1034 1035 memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt)); 1036 memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs)); 1037 1038 if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1039 RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1040 ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)); 1041 1042 /* by netEnv parameters, get match vector */ 1043 if (!p_SchemeParams->alwaysDirect) 1044 { 1045 p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv); 1046 netEnvParams.netEnvId = p_Scheme->netEnvId; 1047 netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits; 1048 memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits); 1049 err = PcdGetUnitsVector(p_FmPcd, &netEnvParams); 1050 if (err) 1051 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 1052 p_Scheme->matchVector = netEnvParams.vector; 1053 } 1054 else 1055 { 1056 p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT; 1057 p_Scheme->netEnvId = ILLEGAL_NETENV; 1058 } 1059 1060 if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID) 1061 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid")); 1062 1063 if (p_SchemeParams->bypassFqidGeneration) 1064 { 1065 #ifdef FM_KG_NO_BYPASS_FQID_GEN 1066 if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6)) 1067 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration.")); 1068 #endif /* FM_KG_NO_BYPASS_FQID_GEN */ 1069 if (p_SchemeParams->baseFqid) 1070 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID")); 1071 } 1072 else 1073 if (!p_SchemeParams->baseFqid) 1074 DBG(WARNING, ("baseFqid is 0.")); 1075 1076 if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR) 1077 { 1078 direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct; 1079 p_Scheme->directPlcr = direct; 1080 absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE); 1081 if (!direct && absolute) 1082 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared.")); 1083 1084 if (direct) 1085 { 1086 profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId; 1087 numOfProfiles = 1; 1088 } 1089 else 1090 { 1091 profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; 1092 shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; 1093 numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles; 1094 } 1095 } 1096 1097 if (p_SchemeParams->nextEngine == e_FM_PCD_CC) 1098 { 1099 #ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN 1100 if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) 1101 { 1102 if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6)) 1103 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration.")); 1104 } 1105 #endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */ 1106 1107 err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree, 1108 p_SchemeParams->kgNextEngineParams.cc.grpId, 1109 &grpBits, 1110 &grpBase); 1111 if (err) 1112 RETURN_ERROR(MAJOR, err, NO_MSG); 1113 p_Scheme->ccUnits = grpBits; 1114 1115 if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && 1116 (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) 1117 { 1118 if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile) 1119 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification.")); 1120 absolute = FALSE; 1121 direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct; 1122 if (direct) 1123 { 1124 profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId; 1125 numOfProfiles = 1; 1126 } 1127 else 1128 { 1129 profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; 1130 shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; 1131 numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles; 1132 } 1133 } 1134 } 1135 1136 /* if policer is used directly after KG, or after CC */ 1137 if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) || 1138 ((p_SchemeParams->nextEngine == e_FM_PCD_CC) && 1139 (p_SchemeParams->kgNextEngineParams.cc.plcrNext) && 1140 (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))) 1141 { 1142 /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ 1143 if (absolute) 1144 { 1145 /* for absolute direct policy only, */ 1146 relativeProfileId = profileId; 1147 err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId); 1148 if (err) 1149 RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset")); 1150 if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId)) 1151 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid.")); 1152 p_Scheme->relativeProfileId = profileId; 1153 } 1154 else 1155 { 1156 /* save relative profile id's for later check */ 1157 p_Scheme->nextRelativePlcrProfile = TRUE; 1158 p_Scheme->relativeProfileId = profileId; 1159 p_Scheme->numOfProfiles = numOfProfiles; 1160 } 1161 } 1162 else 1163 { 1164 /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration 1165 is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */ 1166 if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs) 1167 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1168 ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID")); 1169 if (p_SchemeParams->bypassFqidGeneration && 1170 p_SchemeParams->useHash && 1171 p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids) 1172 RETURN_ERROR(MAJOR, E_INVALID_STATE, 1173 ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID")); 1174 } 1175 1176 /* configure all 21 scheme registers */ 1177 tmpReg = KG_SCH_MODE_EN; 1178 switch (p_SchemeParams->nextEngine) 1179 { 1180 case (e_FM_PCD_PLCR): 1181 /* add to mode register - NIA */ 1182 tmpReg |= KG_SCH_MODE_NIA_PLCR; 1183 tmpReg |= NIA_ENG_PLCR; 1184 tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0); 1185 /* initialize policer profile command - */ 1186 /* configure kgse_ppc */ 1187 if (direct) 1188 /* use profileId as base, other fields are 0 */ 1189 p_SchemeRegs->kgse_ppc = (uint32_t)profileId; 1190 else 1191 { 1192 if (shift > MAX_PP_SHIFT) 1193 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); 1194 1195 if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) 1196 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); 1197 1198 ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; 1199 ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW; 1200 ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT); 1201 ppcTmp |= (uint32_t)profileId; 1202 1203 p_SchemeRegs->kgse_ppc = ppcTmp; 1204 } 1205 break; 1206 case (e_FM_PCD_CC): 1207 /* mode reg - define NIA */ 1208 tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); 1209 1210 p_SchemeRegs->kgse_ccbs = grpBits; 1211 tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT); 1212 1213 if (p_SchemeParams->kgNextEngineParams.cc.plcrNext) 1214 { 1215 if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration) 1216 { 1217 /* find out if absolute or relative */ 1218 if (absolute) 1219 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("It is illegal to request a shared profile in a scheme that is in a KG->CC->PLCR flow")); 1220 if (direct) 1221 { 1222 /* mask = 0, base = directProfileId */ 1223 p_SchemeRegs->kgse_ppc = (uint32_t)profileId; 1224 } 1225 else 1226 { 1227 if (shift > MAX_PP_SHIFT) 1228 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); 1229 if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) 1230 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); 1231 1232 ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; 1233 ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW; 1234 ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT); 1235 ppcTmp |= (uint32_t)profileId; 1236 1237 p_SchemeRegs->kgse_ppc = ppcTmp; 1238 } 1239 } 1240 } 1241 break; 1242 case (e_FM_PCD_DONE): 1243 if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME) 1244 tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); 1245 else 1246 tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); 1247 break; 1248 default: 1249 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported")); 1250 } 1251 p_SchemeRegs->kgse_mode = tmpReg; 1252 1253 p_SchemeRegs->kgse_mv = p_Scheme->matchVector; 1254 1255 #if (DPAA_VERSION >= 11) 1256 if (p_SchemeParams->overrideStorageProfile) 1257 { 1258 p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE; 1259 1260 if (p_SchemeParams->storageProfile.direct) 1261 { 1262 profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId; 1263 shift = 0; 1264 numOfProfiles = 1; 1265 } 1266 else 1267 { 1268 profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; 1269 shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift; 1270 numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles; 1271 } 1272 if (shift > MAX_SP_SHIFT) 1273 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT)); 1274 1275 if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) 1276 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); 1277 1278 tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT; 1279 tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT); 1280 tmpReg |= (uint32_t)profileId; 1281 1282 1283 p_SchemeRegs->kgse_vsp = tmpReg; 1284 1285 p_Scheme->vspe = TRUE; 1286 1287 } 1288 else 1289 p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN; 1290 #endif /* (DPAA_VERSION >= 11) */ 1291 1292 if (p_SchemeParams->useHash) 1293 { 1294 p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams; 1295 1296 if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY) 1297 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range")); 1298 1299 /* configure kgse_dv0 */ 1300 p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0; 1301 1302 /* configure kgse_dv1 */ 1303 p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1; 1304 1305 if (!p_SchemeParams->bypassFqidGeneration) 1306 { 1307 if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids)) 1308 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2")); 1309 if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid) 1310 DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues.")); 1311 } 1312 1313 /* configure kgse_ekdv */ 1314 tmpReg = 0; 1315 for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++) 1316 { 1317 switch (p_KeyAndHash->dflts[i].type) 1318 { 1319 case (e_FM_PCD_KG_MAC_ADDR): 1320 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT); 1321 break; 1322 case (e_FM_PCD_KG_TCI): 1323 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT); 1324 break; 1325 case (e_FM_PCD_KG_ENET_TYPE): 1326 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT); 1327 break; 1328 case (e_FM_PCD_KG_PPP_SESSION_ID): 1329 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT); 1330 break; 1331 case (e_FM_PCD_KG_PPP_PROTOCOL_ID): 1332 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT); 1333 break; 1334 case (e_FM_PCD_KG_MPLS_LABEL): 1335 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT); 1336 break; 1337 case (e_FM_PCD_KG_IP_ADDR): 1338 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT); 1339 break; 1340 case (e_FM_PCD_KG_PROTOCOL_TYPE): 1341 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT); 1342 break; 1343 case (e_FM_PCD_KG_IP_TOS_TC): 1344 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT); 1345 break; 1346 case (e_FM_PCD_KG_IPV6_FLOW_LABEL): 1347 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); 1348 break; 1349 case (e_FM_PCD_KG_IPSEC_SPI): 1350 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT); 1351 break; 1352 case (e_FM_PCD_KG_L4_PORT): 1353 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); 1354 break; 1355 case (e_FM_PCD_KG_TCP_FLAG): 1356 tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT); 1357 break; 1358 case (e_FM_PCD_KG_GENERIC_FROM_DATA): 1359 swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA; 1360 swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; 1361 numOfSwDefaults ++; 1362 break; 1363 case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V): 1364 swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V; 1365 swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; 1366 numOfSwDefaults ++; 1367 break; 1368 case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA): 1369 swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA; 1370 swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; 1371 numOfSwDefaults ++; 1372 break; 1373 default: 1374 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1375 } 1376 } 1377 p_SchemeRegs->kgse_ekdv = tmpReg; 1378 1379 p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts)); 1380 if (!p_LocalExtractsArray) 1381 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); 1382 1383 /* configure kgse_ekfc and kgse_gec */ 1384 knownTmp = 0; 1385 for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++) 1386 { 1387 p_Extract = &p_KeyAndHash->extractArray[i]; 1388 switch (p_Extract->type) 1389 { 1390 case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): 1391 knownTmp |= KG_SCH_KN_PORT_ID; 1392 /* save in driver structure */ 1393 p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID); 1394 p_LocalExtractsArray->extractsArray[i].known = TRUE; 1395 break; 1396 case (e_FM_PCD_EXTRACT_BY_HDR): 1397 switch (p_Extract->extractByHdr.hdr) 1398 { 1399 #if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) 1400 case (HEADER_TYPE_UDP_LITE): 1401 p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; 1402 break; 1403 #endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ 1404 case (HEADER_TYPE_UDP_ENCAP_ESP): 1405 switch (p_Extract->extractByHdr.type) 1406 { 1407 case (e_FM_PCD_EXTRACT_FROM_HDR): 1408 /* case where extraction from ESP only */ 1409 if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE) 1410 { 1411 p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 1412 p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE; 1413 p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 1414 } 1415 else 1416 { 1417 p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; 1418 p_Extract->extractByHdr.ignoreProtocolValidation = FALSE; 1419 } 1420 break; 1421 case (e_FM_PCD_EXTRACT_FROM_FIELD): 1422 switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp) 1423 { 1424 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): 1425 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): 1426 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): 1427 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): 1428 p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; 1429 break; 1430 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): 1431 p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 1432 p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 1433 /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/ 1434 p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 1435 break; 1436 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): 1437 p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 1438 p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 1439 p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET; 1440 p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 1441 break; 1442 } 1443 break; 1444 case (e_FM_PCD_EXTRACT_FULL_FIELD): 1445 switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp) 1446 { 1447 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): 1448 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): 1449 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): 1450 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): 1451 p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; 1452 break; 1453 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): 1454 p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 1455 p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 1456 p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE; 1457 p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET; 1458 p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 1459 break; 1460 case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): 1461 p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 1462 p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 1463 p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE; 1464 p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET; 1465 p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 1466 break; 1467 } 1468 break; 1469 } 1470 break; 1471 default: 1472 break; 1473 } 1474 switch (p_Extract->extractByHdr.type) 1475 { 1476 case (e_FM_PCD_EXTRACT_FROM_HDR): 1477 generic = TRUE; 1478 /* get the header code for the generic extract */ 1479 code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation); 1480 /* set generic register fields */ 1481 offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset; 1482 size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size; 1483 break; 1484 case (e_FM_PCD_EXTRACT_FROM_FIELD): 1485 generic = TRUE; 1486 /* get the field code for the generic extract */ 1487 code = GetGenFieldCode(p_Extract->extractByHdr.hdr, 1488 p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex); 1489 offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset; 1490 size = p_Extract->extractByHdr.extractByHdrType.fromField.size; 1491 break; 1492 case (e_FM_PCD_EXTRACT_FULL_FIELD): 1493 if (!p_Extract->extractByHdr.ignoreProtocolValidation) 1494 { 1495 /* if we have a known field for it - use it, otherwise use generic */ 1496 bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, 1497 p_Extract->extractByHdr.extractByHdrType.fullField); 1498 if (bitMask) 1499 { 1500 knownTmp |= bitMask; 1501 /* save in driver structure */ 1502 p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask); 1503 p_LocalExtractsArray->extractsArray[i].known = TRUE; 1504 } 1505 else 1506 generic = TRUE; 1507 } 1508 else 1509 generic = TRUE; 1510 if (generic) 1511 { 1512 /* tmp - till we cover more headers under generic */ 1513 XX_Free(p_LocalExtractsArray); 1514 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported")); 1515 } 1516 break; 1517 default: 1518 XX_Free(p_LocalExtractsArray); 1519 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1520 } 1521 break; 1522 case (e_FM_PCD_EXTRACT_NON_HDR): 1523 /* use generic */ 1524 generic = TRUE; 1525 offset = 0; 1526 /* get the field code for the generic extract */ 1527 code = GetGenCode(p_Extract->extractNonHdr.src, &offset); 1528 offset += p_Extract->extractNonHdr.offset; 1529 size = p_Extract->extractNonHdr.size; 1530 break; 1531 default: 1532 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1533 } 1534 1535 if (generic) 1536 { 1537 /* set generic register fields */ 1538 if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS) 1539 { 1540 XX_Free(p_LocalExtractsArray); 1541 RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); 1542 } 1543 if (!code) 1544 { 1545 XX_Free(p_LocalExtractsArray); 1546 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); 1547 } 1548 1549 genTmp = KG_SCH_GEN_VALID; 1550 genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); 1551 genTmp |= offset; 1552 if ((size > MAX_KG_SCH_SIZE) || (size < 1)) 1553 { 1554 XX_Free(p_LocalExtractsArray); 1555 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)")); 1556 } 1557 genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT); 1558 swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code); 1559 if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL) 1560 DBG(WARNING, ("No sw default configured")); 1561 else 1562 genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT; 1563 1564 genTmp |= KG_SCH_GEN_MASK; 1565 p_SchemeRegs->kgse_gec[currGenId] = genTmp; 1566 /* save in driver structure */ 1567 p_LocalExtractsArray->extractsArray[i].id = currGenId++; 1568 p_LocalExtractsArray->extractsArray[i].known = FALSE; 1569 generic = FALSE; 1570 } 1571 } 1572 p_SchemeRegs->kgse_ekfc = knownTmp; 1573 1574 selectTmp = 0; 1575 maskTmp = 0xFFFFFFFF; 1576 /* configure kgse_bmch, kgse_bmcl and kgse_fqb */ 1577 1578 if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS) 1579 { 1580 XX_Free(p_LocalExtractsArray); 1581 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS)); 1582 } 1583 for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++) 1584 { 1585 /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */ 1586 id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id; 1587 /* Get the shift of the select field (depending on i) */ 1588 GET_MASK_SEL_SHIFT(shift,i); 1589 if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known) 1590 selectTmp |= id << shift; 1591 else 1592 selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift; 1593 1594 /* Get the shift of the offset field (depending on i) - may 1595 be in kgse_bmch or in kgse_fqb (depending on i) */ 1596 GET_MASK_OFFSET_SHIFT(shift,i); 1597 if (i<=1) 1598 selectTmp |= p_KeyAndHash->masks[i].offset << shift; 1599 else 1600 fqbTmp |= p_KeyAndHash->masks[i].offset << shift; 1601 1602 /* Get the shift of the mask field (depending on i) */ 1603 GET_MASK_SHIFT(shift,i); 1604 /* pass all bits */ 1605 maskTmp |= KG_SCH_BITMASK_MASK << shift; 1606 /* clear bits that need masking */ 1607 maskTmp &= ~(0xFF << shift) ; 1608 /* set mask bits */ 1609 maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ; 1610 } 1611 p_SchemeRegs->kgse_bmch = selectTmp; 1612 p_SchemeRegs->kgse_bmcl = maskTmp; 1613 /* kgse_fqb will be written t the end of the routine */ 1614 1615 /* configure kgse_hc */ 1616 if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT) 1617 { 1618 XX_Free(p_LocalExtractsArray); 1619 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT)); 1620 } 1621 if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT) 1622 { 1623 XX_Free(p_LocalExtractsArray); 1624 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT)); 1625 } 1626 1627 tmpReg = 0; 1628 1629 tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift); 1630 tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT; 1631 1632 if (p_KeyAndHash->symmetricHash) 1633 { 1634 if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) || 1635 (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) || 1636 (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) || 1637 (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST))) 1638 { 1639 XX_Free(p_LocalExtractsArray); 1640 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing")); 1641 } 1642 tmpReg |= KG_SCH_HASH_CONFIG_SYM; 1643 } 1644 p_SchemeRegs->kgse_hc = tmpReg; 1645 1646 /* build the return array describing the order of the extractions */ 1647 1648 /* the last currGenId places of the array 1649 are for generic extracts that are always last. 1650 We now sort for the calculation of the order of the known 1651 extractions we sort the known extracts between orderedArray[0] and 1652 orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1]. 1653 for the calculation of the order of the generic extractions we use: 1654 num_of_generic - currGenId 1655 num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId 1656 first_generic_index = num_of_known */ 1657 curr = 0; 1658 for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++) 1659 { 1660 if (p_LocalExtractsArray->extractsArray[i].known) 1661 { 1662 ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId)); 1663 j = curr; 1664 /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original 1665 index in the user's extractions array */ 1666 /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1] 1667 location */ 1668 while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id < 1669 p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id)) 1670 { 1671 p_Scheme->orderedArray[j] = 1672 p_Scheme->orderedArray[j-1]; 1673 j--; 1674 } 1675 p_Scheme->orderedArray[j] = (uint8_t)i; 1676 curr++; 1677 } 1678 else 1679 { 1680 /* index is first_generic_index + generic index (id) */ 1681 idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id); 1682 ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY); 1683 p_Scheme->orderedArray[idx]= (uint8_t)i; 1684 } 1685 } 1686 XX_Free(p_LocalExtractsArray); 1687 } 1688 else 1689 { 1690 /* clear all unused registers: */ 1691 p_SchemeRegs->kgse_ekfc = 0; 1692 p_SchemeRegs->kgse_ekdv = 0; 1693 p_SchemeRegs->kgse_bmch = 0; 1694 p_SchemeRegs->kgse_bmcl = 0; 1695 p_SchemeRegs->kgse_hc = 0; 1696 p_SchemeRegs->kgse_dv0 = 0; 1697 p_SchemeRegs->kgse_dv1 = 0; 1698 } 1699 1700 if (p_SchemeParams->bypassFqidGeneration) 1701 p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID; 1702 1703 /* configure kgse_spc */ 1704 if ( p_SchemeParams->schemeCounter.update) 1705 p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value; 1706 1707 1708 /* check that are enough generic registers */ 1709 if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS) 1710 RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); 1711 1712 /* extracted OR mask on Qid */ 1713 for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++) 1714 { 1715 1716 p_Scheme->extractedOrs = TRUE; 1717 /* configure kgse_gec[i] */ 1718 p_ExtractOr = &p_SchemeParams->extractedOrs[i]; 1719 switch (p_ExtractOr->type) 1720 { 1721 case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): 1722 code = KG_SCH_GEN_PARSE_RESULT_N_FQID; 1723 offset = 0; 1724 break; 1725 case (e_FM_PCD_EXTRACT_BY_HDR): 1726 /* get the header code for the generic extract */ 1727 code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation); 1728 /* set generic register fields */ 1729 offset = p_ExtractOr->extractionOffset; 1730 break; 1731 case (e_FM_PCD_EXTRACT_NON_HDR): 1732 /* get the field code for the generic extract */ 1733 offset = 0; 1734 code = GetGenCode(p_ExtractOr->src, &offset); 1735 offset += p_ExtractOr->extractionOffset; 1736 break; 1737 default: 1738 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 1739 } 1740 1741 /* set generic register fields */ 1742 if (!code) 1743 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); 1744 genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID; 1745 genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); 1746 genTmp |= offset; 1747 if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile) 1748 RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile")); 1749 1750 /************************************************************************************ 1751 bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter 1752 in the following way: 1753 1754 Driver API and implementation: 1755 ============================== 1756 FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID. 1757 if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that 1758 are not overlapping FQID. 1759 ------------------------ 1760 | FQID (24) | 1761 ------------------------ 1762 -------- 1763 | | extracted OR byte 1764 -------- 1765 1766 Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the 1767 PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that 1768 are not overlapping PP id. 1769 1770 -------- 1771 | PP (8) | 1772 -------- 1773 -------- 1774 | | extracted OR byte 1775 -------- 1776 1777 HW implementation 1778 ================= 1779 FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located 1780 as the highest byte of that word and may be rotated to effect any part os the FQID or 1781 the PP. 1782 ------------------------ -------- 1783 | FQID (24) || PP (8) | 1784 ------------------------ -------- 1785 -------- 1786 | | extracted OR byte 1787 -------- 1788 1789 ************************************************************************************/ 1790 1791 if (p_ExtractOr->bitOffsetInFqid) 1792 { 1793 if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET ) 1794 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)")); 1795 if (p_ExtractOr->bitOffsetInFqid<8) 1796 genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT); 1797 else 1798 genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT); 1799 p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE); 1800 } 1801 else /* effect policer profile */ 1802 { 1803 if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET ) 1804 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)")); 1805 p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile; 1806 genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT); 1807 p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE); 1808 } 1809 1810 genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT); 1811 /* clear bits that need masking */ 1812 genTmp &= ~KG_SCH_GEN_MASK ; 1813 /* set mask bits */ 1814 genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT); 1815 p_SchemeRegs->kgse_gec[currGenId++] = genTmp; 1816 1817 } 1818 /* clear all unused GEC registers */ 1819 for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++) 1820 p_SchemeRegs->kgse_gec[i] = 0; 1821 1822 /* add base Qid for this scheme */ 1823 /* add configuration for kgse_fqb */ 1824 if (p_SchemeParams->baseFqid & ~0x00FFFFFF) 1825 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1")); 1826 1827 fqbTmp |= p_SchemeParams->baseFqid; 1828 p_SchemeRegs->kgse_fqb = fqbTmp; 1829 1830 p_Scheme->nextEngine = p_SchemeParams->nextEngine; 1831 p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction; 1832 1833 return E_OK; 1834 } 1835 1836 1837 /*****************************************************************************/ 1838 /* Inter-module API routines */ 1839 /*****************************************************************************/ 1840 1841 t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet) 1842 { 1843 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1844 t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; 1845 t_FmPcdIpcKgClsPlanParams kgAlloc; 1846 t_Error err = E_OK; 1847 uint32_t oredVectors = 0; 1848 int i, j; 1849 1850 /* this routine is protected by the calling routine ! */ 1851 if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)) 1852 RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected.")); 1853 1854 /* find a new clsPlan group */ 1855 for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) 1856 if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used) 1857 break; 1858 if (i == FM_MAX_NUM_OF_PORTS) 1859 RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available.")); 1860 1861 p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE; 1862 1863 p_Grp->clsPlanGrpId = (uint8_t)i; 1864 1865 if (p_Grp->numOfOptions == 0) 1866 p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i; 1867 1868 p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i]; 1869 p_ClsPlanGrp->netEnvId = p_Grp->netEnvId; 1870 p_ClsPlanGrp->owners = 0; 1871 FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId); 1872 if (p_Grp->numOfOptions != 0) 1873 FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId); 1874 1875 p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions); 1876 /* a minimal group of 8 is required */ 1877 if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP) 1878 p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP; 1879 if (p_FmPcd->guestId == NCSW_MASTER_ID) 1880 { 1881 err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry); 1882 1883 if (err) 1884 RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 1885 } 1886 else 1887 { 1888 t_FmPcdIpcMsg msg; 1889 uint32_t replyLength; 1890 t_FmPcdIpcReply reply; 1891 1892 /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ 1893 memset(&reply, 0, sizeof(reply)); 1894 memset(&msg, 0, sizeof(msg)); 1895 memset(&kgAlloc, 0, sizeof(kgAlloc)); 1896 kgAlloc.guestId = p_FmPcd->guestId; 1897 kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; 1898 msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN; 1899 memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 1900 replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)); 1901 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1902 (uint8_t*)&msg, 1903 sizeof(msg.msgId) + sizeof(kgAlloc), 1904 (uint8_t*)&reply, 1905 &replyLength, 1906 NULL, 1907 NULL)) != E_OK) 1908 RETURN_ERROR(MAJOR, err, NO_MSG); 1909 1910 if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry))) 1911 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 1912 if ((t_Error)reply.error != E_OK) 1913 RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG); 1914 1915 p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody); 1916 } 1917 1918 /* build classification plan entries parameters */ 1919 p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry; 1920 p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; 1921 1922 oredVectors = 0; 1923 for (i = 0; i<p_Grp->numOfOptions; i++) 1924 { 1925 oredVectors |= p_Grp->optVectors[i]; 1926 /* save an array of used options - the indexes represent the power of 2 index */ 1927 p_ClsPlanGrp->optArray[i] = p_Grp->options[i]; 1928 } 1929 /* set the classification plan relevant entries so that all bits 1930 * relevant to the list of options is cleared 1931 */ 1932 for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++) 1933 p_ClsPlanSet->vectors[j] = ~oredVectors; 1934 1935 for (i = 0; i<p_Grp->numOfOptions; i++) 1936 { 1937 /* option i got the place 2^i in the clsPlan array. all entries that 1938 * have bit i set, should have the vector bit cleared. So each option 1939 * has one location that it is exclusive (1,2,4,8...) and represent the 1940 * presence of that option only, and other locations that represent a 1941 * combination of options. 1942 * e.g: 1943 * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2 1944 * now represents a frame with ethernet-BC header - so the bit 1945 * representing ethernet-BC should be set and all other option bits 1946 * should be cleared. 1947 * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit 1948 * vector[1] set, but they also have other bits set: 1949 * 3=1+2, options 0 and 1 1950 * 6=2+4, options 1 and 2 1951 * 7=1+2+4, options 0,1,and 2 1952 * 10=2+8, options 1 and 3 1953 * etc. 1954 * */ 1955 1956 /* now for each option (i), we set their bits in all entries (j) 1957 * that contain bit 2^i. 1958 */ 1959 for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++) 1960 { 1961 if (j & (1<<i)) 1962 p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i]; 1963 } 1964 } 1965 1966 return E_OK; 1967 } 1968 1969 void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId) 1970 { 1971 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1972 t_FmPcdIpcKgClsPlanParams kgAlloc; 1973 t_Error err; 1974 t_FmPcdIpcMsg msg; 1975 uint32_t replyLength; 1976 t_FmPcdIpcReply reply; 1977 1978 /* check that no port is bound to this clsPlan */ 1979 if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners) 1980 { 1981 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to")); 1982 return; 1983 } 1984 1985 FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN); 1986 1987 if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) 1988 p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; 1989 else 1990 FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId); 1991 1992 /* free blocks */ 1993 if (p_FmPcd->guestId == NCSW_MASTER_ID) 1994 KgFreeClsPlanEntries(h_FmPcd, 1995 p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp, 1996 p_FmPcd->guestId, 1997 p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry); 1998 else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ 1999 { 2000 memset(&reply, 0, sizeof(reply)); 2001 memset(&msg, 0, sizeof(msg)); 2002 kgAlloc.guestId = p_FmPcd->guestId; 2003 kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp; 2004 kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry; 2005 msg.msgId = FM_PCD_FREE_KG_CLSPLAN; 2006 memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 2007 replyLength = sizeof(uint32_t); 2008 err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 2009 (uint8_t*)&msg, 2010 sizeof(msg.msgId) + sizeof(kgAlloc), 2011 (uint8_t*)&reply, 2012 &replyLength, 2013 NULL, 2014 NULL); 2015 if (err != E_OK) 2016 { 2017 REPORT_ERROR(MINOR, err, NO_MSG); 2018 return; 2019 } 2020 if (replyLength != sizeof(uint32_t)) 2021 { 2022 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 2023 return; 2024 } 2025 if ((t_Error)reply.error != E_OK) 2026 { 2027 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed")); 2028 return; 2029 } 2030 } 2031 2032 /* clear clsPlan driver structure */ 2033 memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp)); 2034 } 2035 2036 t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add) 2037 { 2038 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2039 uint32_t j, schemesPerPortVector = 0; 2040 t_FmPcdKgScheme *p_Scheme; 2041 uint8_t i, relativeSchemeId; 2042 uint32_t tmp, walking1Mask; 2043 uint8_t swPortIndex = 0; 2044 2045 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 2046 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 2047 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 2048 2049 /* for each scheme */ 2050 for (i = 0; i<p_BindPort->numOfSchemes; i++) 2051 { 2052 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); 2053 if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 2054 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 2055 2056 if (add) 2057 { 2058 p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; 2059 if (!FmPcdKgIsSchemeValidSw(p_Scheme)) 2060 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); 2061 /* check netEnvId of the port against the scheme netEnvId */ 2062 if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV)) 2063 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId")); 2064 2065 /* if next engine is private port policer profile, we need to check that it is valid */ 2066 HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId); 2067 if (p_Scheme->nextRelativePlcrProfile) 2068 { 2069 for (j = 0;j<p_Scheme->numOfProfiles;j++) 2070 { 2071 ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort); 2072 if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles) 2073 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range")); 2074 if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j))) 2075 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid.")); 2076 } 2077 } 2078 if (!p_BindPort->useClsPlan) 2079 { 2080 /* This check may be redundant as port is a assigned to the whole NetEnv */ 2081 2082 /* if this port does not use clsPlan, it may not be bound to schemes with units that contain 2083 cls plan options. Schemes that are used only directly, should not be checked. 2084 it also may not be bound to schemes that go to CC with units that are options - so we OR 2085 the match vector and the grpBits (= ccUnits) */ 2086 if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits) 2087 { 2088 uint8_t netEnvId; 2089 walking1Mask = 0x80000000; 2090 netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId; 2091 tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector; 2092 tmp |= p_Scheme->ccUnits; 2093 while (tmp) 2094 { 2095 if (tmp & walking1Mask) 2096 { 2097 tmp &= ~walking1Mask; 2098 if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask)) 2099 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options")); 2100 } 2101 walking1Mask >>= 1; 2102 } 2103 } 2104 } 2105 } 2106 /* build vector */ 2107 schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]); 2108 } 2109 2110 *p_SpReg = schemesPerPortVector; 2111 2112 return E_OK; 2113 } 2114 2115 t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) 2116 { 2117 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2118 uint32_t spReg; 2119 t_Error err = E_OK; 2120 2121 err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE); 2122 if (err) 2123 RETURN_ERROR(MAJOR, err, NO_MSG); 2124 2125 err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE); 2126 if (err) 2127 RETURN_ERROR(MAJOR, err, NO_MSG); 2128 2129 IncSchemeOwners(p_FmPcd, p_SchemeBind); 2130 2131 return E_OK; 2132 } 2133 2134 t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) 2135 { 2136 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2137 uint32_t spReg; 2138 t_Error err = E_OK; 2139 2140 err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE); 2141 if (err) 2142 RETURN_ERROR(MAJOR, err, NO_MSG); 2143 2144 err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE); 2145 if (err) 2146 RETURN_ERROR(MAJOR, err, NO_MSG); 2147 2148 DecSchemeOwners(p_FmPcd, p_SchemeBind); 2149 2150 return E_OK; 2151 } 2152 2153 bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme) 2154 { 2155 t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme; 2156 2157 return p_Scheme->valid; 2158 } 2159 2160 bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId) 2161 { 2162 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2163 2164 if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT) 2165 return TRUE; 2166 else 2167 return FALSE; 2168 } 2169 2170 t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) 2171 { 2172 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2173 uint8_t i, j; 2174 2175 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 2176 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 2177 2178 /* This routine is issued only on master core of master partition - 2179 either directly or through IPC, so no need for lock */ 2180 2181 for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++) 2182 { 2183 if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated) 2184 { 2185 p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE; 2186 p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId; 2187 p_SchemesIds[j] = i; 2188 j++; 2189 } 2190 } 2191 2192 if (j != numOfSchemes) 2193 { 2194 /* roll back */ 2195 for (j--; j; j--) 2196 { 2197 p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE; 2198 p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0; 2199 p_SchemesIds[j] = 0; 2200 } 2201 2202 RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found")); 2203 } 2204 2205 return E_OK; 2206 } 2207 2208 t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) 2209 { 2210 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2211 uint8_t i; 2212 2213 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 2214 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 2215 2216 /* This routine is issued only on master core of master partition - 2217 either directly or through IPC */ 2218 2219 for (i = 0; i < numOfSchemes; i++) 2220 { 2221 if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated) 2222 { 2223 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated")); 2224 } 2225 if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId) 2226 { 2227 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. ")); 2228 } 2229 p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE; 2230 p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0; 2231 } 2232 2233 return E_OK; 2234 } 2235 2236 t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First) 2237 { 2238 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2239 uint8_t numOfBlocks, blocksFound=0, first=0; 2240 uint8_t i, j; 2241 2242 /* This routine is issued only on master core of master partition - 2243 either directly or through IPC, so no need for lock */ 2244 2245 if (!numOfClsPlanEntries) 2246 return E_OK; 2247 2248 if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries))) 2249 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8")); 2250 2251 numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); 2252 2253 /* try to find consequent blocks */ 2254 first = 0; 2255 for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;) 2256 { 2257 if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated) 2258 { 2259 blocksFound++; 2260 i++; 2261 if (blocksFound == numOfBlocks) 2262 break; 2263 } 2264 else 2265 { 2266 blocksFound = 0; 2267 /* advance i to the next aligned address */ 2268 first = i = (uint8_t)(first + numOfBlocks); 2269 } 2270 } 2271 2272 if (blocksFound == numOfBlocks) 2273 { 2274 *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP); 2275 for (j = first; j < (first + numOfBlocks); j++) 2276 { 2277 p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE; 2278 p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId; 2279 } 2280 return E_OK; 2281 } 2282 else 2283 RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan")); 2284 } 2285 2286 void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base) 2287 { 2288 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2289 uint8_t numOfBlocks; 2290 uint8_t i, baseBlock; 2291 2292 #ifdef DISABLE_ASSERTIONS 2293 UNUSED(guestId); 2294 #endif /* DISABLE_ASSERTIONS */ 2295 2296 /* This routine is issued only on master core of master partition - 2297 either directly or through IPC, so no need for lock */ 2298 2299 numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); 2300 ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP)); 2301 2302 baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP); 2303 for (i=baseBlock;i<baseBlock+numOfBlocks;i++) 2304 { 2305 ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated); 2306 ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId); 2307 p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE; 2308 p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0; 2309 } 2310 } 2311 2312 void KgEnable(t_FmPcd *p_FmPcd) 2313 { 2314 struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 2315 2316 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 2317 fman_kg_enable(p_Regs); 2318 } 2319 2320 void KgDisable(t_FmPcd *p_FmPcd) 2321 { 2322 struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 2323 2324 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 2325 fman_kg_disable(p_Regs); 2326 } 2327 2328 void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set) 2329 { 2330 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2331 struct fman_kg_cp_regs *p_FmPcdKgPortRegs; 2332 uint32_t tmpKgarReg = 0, intFlags; 2333 uint16_t i, j; 2334 2335 /* This routine is protected by the calling routine ! */ 2336 ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 2337 p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs; 2338 2339 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 2340 for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8) 2341 { 2342 tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); 2343 2344 for (j = i; j < i+8; j++) 2345 { 2346 ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1)); 2347 WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]); 2348 } 2349 2350 if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK) 2351 { 2352 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED")); 2353 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 2354 return; 2355 } 2356 } 2357 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 2358 } 2359 2360 t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) 2361 { 2362 t_FmPcdKg *p_FmPcdKg; 2363 2364 UNUSED(p_FmPcd); 2365 2366 if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES) 2367 { 2368 REPORT_ERROR(MAJOR, E_INVALID_VALUE, 2369 ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES)); 2370 return NULL; 2371 } 2372 2373 p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg)); 2374 if (!p_FmPcdKg) 2375 { 2376 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED")); 2377 return NULL; 2378 } 2379 memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg)); 2380 2381 2382 if (FmIsMaster(p_FmPcd->h_Fm)) 2383 { 2384 p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm)); 2385 p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions; 2386 p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0]; 2387 } 2388 2389 p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes; 2390 if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes) 2391 { 2392 p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES; 2393 DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES")); 2394 } 2395 2396 p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; 2397 2398 return p_FmPcdKg; 2399 } 2400 2401 t_Error KgInit(t_FmPcd *p_FmPcd) 2402 { 2403 t_Error err = E_OK; 2404 2405 p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock(); 2406 if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock) 2407 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock")); 2408 2409 if (p_FmPcd->guestId == NCSW_MASTER_ID) 2410 err = KgInitMaster(p_FmPcd); 2411 else 2412 err = KgInitGuest(p_FmPcd); 2413 2414 if (err != E_OK) 2415 { 2416 if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) 2417 XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); 2418 } 2419 2420 return err; 2421 } 2422 2423 t_Error KgFree(t_FmPcd *p_FmPcd) 2424 { 2425 t_FmPcdIpcKgSchemesParams kgAlloc; 2426 t_Error err = E_OK; 2427 t_FmPcdIpcMsg msg; 2428 uint32_t replyLength; 2429 t_FmPcdIpcReply reply; 2430 2431 FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR); 2432 2433 if (p_FmPcd->guestId == NCSW_MASTER_ID) 2434 { 2435 err = FmPcdKgFreeSchemes(p_FmPcd, 2436 p_FmPcd->p_FmPcdKg->numOfSchemes, 2437 p_FmPcd->guestId, 2438 p_FmPcd->p_FmPcdKg->schemesIds); 2439 if (err) 2440 RETURN_ERROR(MAJOR, err, NO_MSG); 2441 2442 if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) 2443 XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); 2444 2445 return E_OK; 2446 } 2447 2448 /* guest */ 2449 memset(&reply, 0, sizeof(reply)); 2450 memset(&msg, 0, sizeof(msg)); 2451 kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; 2452 kgAlloc.guestId = p_FmPcd->guestId; 2453 ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES); 2454 memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes); 2455 msg.msgId = FM_PCD_FREE_KG_SCHEMES; 2456 memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 2457 replyLength = sizeof(uint32_t); 2458 if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 2459 (uint8_t*)&msg, 2460 sizeof(msg.msgId) + sizeof(kgAlloc), 2461 (uint8_t*)&reply, 2462 &replyLength, 2463 NULL, 2464 NULL)) != E_OK) 2465 RETURN_ERROR(MAJOR, err, NO_MSG); 2466 if (replyLength != sizeof(uint32_t)) 2467 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 2468 2469 if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) 2470 XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); 2471 2472 return (t_Error)reply.error; 2473 } 2474 2475 t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp) 2476 { 2477 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2478 t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams; 2479 t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; 2480 t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; 2481 t_Error err; 2482 2483 /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules, 2484 so no need for lock here */ 2485 2486 memset(&grpParams, 0, sizeof(grpParams)); 2487 grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN; 2488 p_GrpParams = &grpParams; 2489 2490 p_GrpParams->netEnvId = netEnvId; 2491 2492 /* Get from the NetEnv the information of the clsPlan (can be already created, 2493 * or needs to build) */ 2494 err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams); 2495 if (err) 2496 RETURN_ERROR(MINOR,err,NO_MSG); 2497 2498 if (p_GrpParams->grpExists) 2499 { 2500 /* this group was already updated (at least) in SW */ 2501 *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; 2502 } 2503 else 2504 { 2505 p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); 2506 if (!p_ClsPlanSet) 2507 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); 2508 memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); 2509 /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */ 2510 err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet); 2511 if (err) 2512 { 2513 XX_Free(p_ClsPlanSet); 2514 RETURN_ERROR(MINOR, err, NO_MSG); 2515 } 2516 *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; 2517 2518 if (p_FmPcd->h_Hc) 2519 { 2520 /* write clsPlan entries to memory */ 2521 err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet); 2522 if (err) 2523 { 2524 XX_Free(p_ClsPlanSet); 2525 RETURN_ERROR(MAJOR, err, NO_MSG); 2526 } 2527 } 2528 else 2529 /* write clsPlan entries to memory */ 2530 KgSetClsPlan(p_FmPcd, p_ClsPlanSet); 2531 2532 XX_Free(p_ClsPlanSet); 2533 } 2534 2535 /* Set caller parameters */ 2536 2537 /* mark if this is an empty classification group */ 2538 if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) 2539 *p_IsEmptyClsPlanGrp = TRUE; 2540 else 2541 *p_IsEmptyClsPlanGrp = FALSE; 2542 2543 p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId]; 2544 2545 /* increment owners number */ 2546 p_ClsPlanGrp->owners++; 2547 2548 /* copy options array for port */ 2549 memcpy(p_OptArray, &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId].optArray, FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)*sizeof(protocolOpt_t)); 2550 2551 /* bind port to the new or existing group */ 2552 err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId); 2553 if (err) 2554 RETURN_ERROR(MINOR, err, NO_MSG); 2555 2556 return E_OK; 2557 } 2558 2559 t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) 2560 { 2561 t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 2562 t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId]; 2563 t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; 2564 t_Error err; 2565 2566 /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules, 2567 so no need for lock here */ 2568 2569 UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId); 2570 2571 /* decrement owners number */ 2572 ASSERT_COND(p_ClsPlanGrp->owners); 2573 p_ClsPlanGrp->owners--; 2574 2575 if (!p_ClsPlanGrp->owners) 2576 { 2577 if (p_FmPcd->h_Hc) 2578 { 2579 err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId); 2580 return err; 2581 } 2582 else 2583 { 2584 /* clear clsPlan entries in memory */ 2585 p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); 2586 if (!p_ClsPlanSet) 2587 { 2588 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); 2589 } 2590 memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); 2591 2592 p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry; 2593 p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp; 2594 KgSetClsPlan(p_FmPcd, p_ClsPlanSet); 2595 XX_Free(p_ClsPlanSet); 2596 2597 FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId); 2598 } 2599 } 2600 return E_OK; 2601 } 2602 2603 uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId) 2604 { 2605 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2606 ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2607 2608 return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction; 2609 } 2610 2611 uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId) 2612 { 2613 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2614 2615 ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2616 2617 return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag; 2618 } 2619 2620 bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId) 2621 { 2622 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2623 2624 ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2625 2626 return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr; 2627 } 2628 2629 2630 uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId) 2631 { 2632 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2633 2634 ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2635 2636 return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId; 2637 } 2638 2639 bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId) 2640 { 2641 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2642 2643 ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2644 2645 if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs && 2646 p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) || 2647 p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile) 2648 return TRUE; 2649 else 2650 return FALSE; 2651 2652 } 2653 2654 e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId) 2655 { 2656 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2657 2658 ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid); 2659 2660 return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine; 2661 } 2662 2663 e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId) 2664 { 2665 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2666 2667 ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2668 2669 return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction; 2670 } 2671 2672 void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction) 2673 { 2674 t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme; 2675 2676 /* this routine is protected by calling routine */ 2677 2678 ASSERT_COND(p_Scheme->valid); 2679 2680 p_Scheme->requiredAction |= requiredAction; 2681 } 2682 2683 bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg) 2684 { 2685 return (bool)!!(schemeModeReg & KG_SCH_MODE_EN); 2686 } 2687 2688 uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter) 2689 { 2690 return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) | 2691 FM_KG_KGAR_GO | 2692 FM_KG_KGAR_WRITE | 2693 FM_KG_KGAR_SEL_SCHEME_ENTRY | 2694 DUMMY_PORT_ID | 2695 (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0)); 2696 } 2697 2698 uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId) 2699 { 2700 return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) | 2701 FM_KG_KGAR_GO | 2702 FM_KG_KGAR_READ | 2703 FM_KG_KGAR_SEL_SCHEME_ENTRY | 2704 DUMMY_PORT_ID | 2705 FM_KG_KGAR_SCM_WSEL_UPDATE_CNT); 2706 2707 } 2708 2709 uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId) 2710 { 2711 return (uint32_t)(FM_KG_KGAR_GO | 2712 FM_KG_KGAR_WRITE | 2713 FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | 2714 DUMMY_PORT_ID | 2715 ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | 2716 FM_PCD_KG_KGAR_WSEL_MASK); 2717 2718 /* if we ever want to write 1 by 1, use: 2719 sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP))); 2720 */ 2721 } 2722 2723 uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId) 2724 { 2725 2726 return (uint32_t)(FM_KG_KGAR_GO | 2727 FM_KG_KGAR_WRITE | 2728 FM_PCD_KG_KGAR_SEL_PORT_ENTRY | 2729 hardwarePortId | 2730 FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); 2731 } 2732 2733 uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId) 2734 { 2735 2736 return (uint32_t)(FM_KG_KGAR_GO | 2737 FM_KG_KGAR_READ | 2738 FM_PCD_KG_KGAR_SEL_PORT_ENTRY | 2739 hardwarePortId | 2740 FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); 2741 } 2742 2743 uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId) 2744 { 2745 2746 return (uint32_t)(FM_KG_KGAR_GO | 2747 FM_KG_KGAR_WRITE | 2748 FM_PCD_KG_KGAR_SEL_PORT_ENTRY | 2749 hardwarePortId | 2750 FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP); 2751 } 2752 2753 uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp) 2754 { 2755 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2756 2757 return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry; 2758 } 2759 2760 uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp) 2761 { 2762 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2763 2764 return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp; 2765 } 2766 2767 2768 uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme) 2769 { 2770 return ((t_FmPcdKgScheme*)h_Scheme)->schemeId; 2771 2772 } 2773 2774 #if (DPAA_VERSION >= 11) 2775 bool FmPcdKgGetVspe(t_Handle h_Scheme) 2776 { 2777 return ((t_FmPcdKgScheme*)h_Scheme)->vspe; 2778 2779 } 2780 #endif /* (DPAA_VERSION >= 11) */ 2781 2782 uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId) 2783 { 2784 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2785 uint8_t i; 2786 2787 for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++) 2788 if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId) 2789 return i; 2790 2791 if (i == p_FmPcd->p_FmPcdKg->numOfSchemes) 2792 REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range")); 2793 2794 return FM_PCD_KG_NUM_OF_SCHEMES; 2795 } 2796 2797 t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId) 2798 { 2799 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2800 2801 ASSERT_COND(p_FmPcd); 2802 2803 /* check that schemeId is in range */ 2804 if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) 2805 { 2806 REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId)); 2807 return NULL; 2808 } 2809 2810 if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId])) 2811 return NULL; 2812 2813 return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; 2814 } 2815 2816 bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme) 2817 { 2818 return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE; 2819 } 2820 2821 t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value) 2822 { 2823 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2824 uint8_t relativeSchemeId, physicalSchemeId; 2825 uint32_t tmpKgarReg, tmpReg32 = 0, intFlags; 2826 t_Error err; 2827 t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme; 2828 2829 SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); 2830 SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); 2831 SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); 2832 2833 /* Calling function locked all PCD modules, so no need to lock here */ 2834 2835 if (!FmPcdKgIsSchemeValidSw(h_Scheme)) 2836 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); 2837 2838 if (p_FmPcd->h_Hc) 2839 { 2840 err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value); 2841 2842 UpdateRequiredActionFlag(h_Scheme,TRUE); 2843 FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction); 2844 return err; 2845 } 2846 2847 physicalSchemeId = p_Scheme->schemeId; 2848 2849 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); 2850 if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 2851 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 2852 2853 if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag || 2854 !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction)) 2855 { 2856 if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) 2857 { 2858 switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine) 2859 { 2860 case (e_FM_PCD_DONE): 2861 if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME) 2862 { 2863 tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 2864 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 2865 WriteKgarWait(p_FmPcd, tmpKgarReg); 2866 tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); 2867 ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); 2868 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA); 2869 /* call indirect command for scheme write */ 2870 tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); 2871 WriteKgarWait(p_FmPcd, tmpKgarReg); 2872 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 2873 } 2874 break; 2875 case (e_FM_PCD_PLCR): 2876 if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr || 2877 (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs && 2878 p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) || 2879 p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile) 2880 { 2881 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared")); 2882 } 2883 err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction); 2884 if (err) 2885 { 2886 RETURN_ERROR(MAJOR, err, NO_MSG); 2887 } 2888 break; 2889 default: 2890 RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME")); 2891 } 2892 } 2893 if (requiredAction & UPDATE_KG_NIA_CC_WA) 2894 { 2895 if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC) 2896 { 2897 tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 2898 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 2899 WriteKgarWait(p_FmPcd, tmpKgarReg); 2900 tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); 2901 ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); 2902 tmpReg32 &= ~NIA_FM_CTL_AC_CC; 2903 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC); 2904 /* call indirect command for scheme write */ 2905 tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); 2906 WriteKgarWait(p_FmPcd, tmpKgarReg); 2907 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 2908 } 2909 } 2910 if (requiredAction & UPDATE_KG_OPT_MODE) 2911 { 2912 tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 2913 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 2914 WriteKgarWait(p_FmPcd, tmpKgarReg); 2915 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value); 2916 /* call indirect command for scheme write */ 2917 tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); 2918 WriteKgarWait(p_FmPcd, tmpKgarReg); 2919 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 2920 } 2921 if (requiredAction & UPDATE_KG_NIA) 2922 { 2923 tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 2924 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 2925 WriteKgarWait(p_FmPcd, tmpKgarReg); 2926 tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); 2927 tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK); 2928 tmpReg32 |= value; 2929 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32); 2930 /* call indirect command for scheme write */ 2931 tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); 2932 WriteKgarWait(p_FmPcd, tmpKgarReg); 2933 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 2934 } 2935 } 2936 2937 UpdateRequiredActionFlag(h_Scheme, TRUE); 2938 FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction); 2939 2940 return E_OK; 2941 } 2942 /*********************** End of inter-module routines ************************/ 2943 2944 2945 /****************************************/ 2946 /* API routines */ 2947 /****************************************/ 2948 2949 t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams) 2950 { 2951 t_FmPcd *p_FmPcd; 2952 struct fman_kg_scheme_regs schemeRegs; 2953 struct fman_kg_scheme_regs *p_MemRegs; 2954 uint8_t i; 2955 t_Error err = E_OK; 2956 uint32_t tmpKgarReg; 2957 uint32_t intFlags; 2958 uint8_t physicalSchemeId, relativeSchemeId = 0; 2959 t_FmPcdKgScheme *p_Scheme; 2960 2961 if (p_SchemeParams->modify) 2962 { 2963 p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme; 2964 p_FmPcd = p_Scheme->h_FmPcd; 2965 2966 SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); 2967 SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); 2968 2969 if (!FmPcdKgIsSchemeValidSw(p_Scheme)) 2970 { 2971 REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, 2972 ("Scheme is invalid")); 2973 return NULL; 2974 } 2975 2976 if (!KgSchemeFlagTryLock(p_Scheme)) 2977 { 2978 DBG(TRACE, ("Scheme Try Lock - BUSY")); 2979 /* Signal to caller BUSY condition */ 2980 p_SchemeParams->id.h_Scheme = NULL; 2981 return NULL; 2982 } 2983 } 2984 else 2985 { 2986 p_FmPcd = (t_FmPcd*)h_FmPcd; 2987 2988 SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); 2989 SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); 2990 2991 relativeSchemeId = p_SchemeParams->id.relativeSchemeId; 2992 /* check that schemeId is in range */ 2993 if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) 2994 { 2995 REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId)); 2996 return NULL; 2997 } 2998 2999 p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; 3000 if (FmPcdKgIsSchemeValidSw(p_Scheme)) 3001 { 3002 REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, 3003 ("Scheme id (%d)!", relativeSchemeId)); 3004 return NULL; 3005 } 3006 /* Clear all fields, scheme may have beed previously used */ 3007 memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme)); 3008 3009 p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId]; 3010 p_Scheme->h_FmPcd = p_FmPcd; 3011 3012 p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd); 3013 if (!p_Scheme->p_Lock) 3014 REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!")); 3015 } 3016 3017 err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs); 3018 if (err) 3019 { 3020 REPORT_ERROR(MAJOR, err, NO_MSG); 3021 if (p_SchemeParams->modify) 3022 KgSchemeFlagUnlock(p_Scheme); 3023 if (!p_SchemeParams->modify && 3024 p_Scheme->p_Lock) 3025 FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); 3026 return NULL; 3027 } 3028 3029 if (p_FmPcd->h_Hc) 3030 { 3031 err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc, 3032 (t_Handle)p_Scheme, 3033 &schemeRegs, 3034 p_SchemeParams->schemeCounter.update); 3035 if (p_SchemeParams->modify) 3036 KgSchemeFlagUnlock(p_Scheme); 3037 if (err) 3038 { 3039 if (!p_SchemeParams->modify && 3040 p_Scheme->p_Lock) 3041 FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); 3042 return NULL; 3043 } 3044 if (!p_SchemeParams->modify) 3045 ValidateSchemeSw(p_Scheme); 3046 return (t_Handle)p_Scheme; 3047 } 3048 3049 physicalSchemeId = p_Scheme->schemeId; 3050 3051 /* configure all 21 scheme registers */ 3052 p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs; 3053 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 3054 WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc); 3055 WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs); 3056 WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode); 3057 WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv); 3058 WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0); 3059 WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1); 3060 WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv); 3061 WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc); 3062 WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch); 3063 WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl); 3064 WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc); 3065 WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc); 3066 WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb); 3067 WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om); 3068 WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp); 3069 for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++) 3070 WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]); 3071 3072 /* call indirect command for scheme write */ 3073 tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update); 3074 3075 WriteKgarWait(p_FmPcd, tmpKgarReg); 3076 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 3077 3078 if (!p_SchemeParams->modify) 3079 ValidateSchemeSw(p_Scheme); 3080 else 3081 KgSchemeFlagUnlock(p_Scheme); 3082 3083 return (t_Handle)p_Scheme; 3084 } 3085 3086 t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme) 3087 { 3088 t_FmPcd *p_FmPcd; 3089 uint8_t physicalSchemeId; 3090 uint32_t tmpKgarReg, intFlags; 3091 t_Error err = E_OK; 3092 t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme; 3093 3094 SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE); 3095 3096 p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd); 3097 3098 UpdateRequiredActionFlag(h_Scheme, FALSE); 3099 3100 /* check that no port is bound to this scheme */ 3101 err = InvalidateSchemeSw(h_Scheme); 3102 if (err) 3103 RETURN_ERROR(MINOR, err, NO_MSG); 3104 3105 if (p_FmPcd->h_Hc) 3106 { 3107 err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme); 3108 if (p_Scheme->p_Lock) 3109 FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); 3110 return err; 3111 } 3112 3113 physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; 3114 3115 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 3116 /* clear mode register, including enable bit */ 3117 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0); 3118 3119 /* call indirect command for scheme write */ 3120 tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); 3121 3122 WriteKgarWait(p_FmPcd, tmpKgarReg); 3123 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 3124 3125 if (p_Scheme->p_Lock) 3126 FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); 3127 3128 return E_OK; 3129 } 3130 3131 uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme) 3132 { 3133 t_FmPcd *p_FmPcd; 3134 uint32_t tmpKgarReg, spc, intFlags; 3135 uint8_t physicalSchemeId; 3136 3137 SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0); 3138 3139 p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd); 3140 if (p_FmPcd->h_Hc) 3141 return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme); 3142 3143 physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; 3144 3145 if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) 3146 REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 3147 3148 tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 3149 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 3150 WriteKgarWait(p_FmPcd, tmpKgarReg); 3151 if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) 3152 REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); 3153 spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc); 3154 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 3155 3156 return spc; 3157 } 3158 3159 t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value) 3160 { 3161 t_FmPcd *p_FmPcd; 3162 uint32_t tmpKgarReg, intFlags; 3163 uint8_t physicalSchemeId; 3164 3165 SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0); 3166 3167 p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd); 3168 3169 if (!FmPcdKgIsSchemeValidSw(h_Scheme)) 3170 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); 3171 3172 if (p_FmPcd->h_Hc) 3173 return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value); 3174 3175 physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; 3176 /* check that schemeId is in range */ 3177 if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) 3178 REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 3179 3180 /* read specified scheme into scheme registers */ 3181 tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 3182 intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); 3183 WriteKgarWait(p_FmPcd, tmpKgarReg); 3184 if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) 3185 { 3186 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 3187 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); 3188 } 3189 3190 /* change counter value */ 3191 WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value); 3192 3193 /* call indirect command for scheme write */ 3194 tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); 3195 3196 WriteKgarWait(p_FmPcd, tmpKgarReg); 3197 KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); 3198 3199 return E_OK; 3200 } 3201 3202 t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset) 3203 { 3204 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 3205 struct fman_kg_regs *p_Regs; 3206 3207 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 3208 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); 3209 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); 3210 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); 3211 3212 p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 3213 if (!FmIsMaster(p_FmPcd->h_Fm)) 3214 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!")); 3215 3216 WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset); 3217 3218 return E_OK; 3219 } 3220 3221 t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value) 3222 { 3223 t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 3224 struct fman_kg_regs *p_Regs; 3225 3226 SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 3227 SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE); 3228 SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); 3229 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); 3230 SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); 3231 3232 p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 3233 3234 if (!FmIsMaster(p_FmPcd->h_Fm)) 3235 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!")); 3236 3237 if (valueId == 0) 3238 WRITE_UINT32(p_Regs->fmkg_gdv0r,value); 3239 else 3240 WRITE_UINT32(p_Regs->fmkg_gdv1r,value); 3241 return E_OK; 3242 } 3243