Path: blob/main/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c
48524 views
/*1* Copyright 2008-2012 Freescale Semiconductor Inc.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5* * Redistributions of source code must retain the above copyright6* notice, this list of conditions and the following disclaimer.7* * Redistributions in binary form must reproduce the above copyright8* notice, this list of conditions and the following disclaimer in the9* documentation and/or other materials provided with the distribution.10* * Neither the name of Freescale Semiconductor nor the11* names of its contributors may be used to endorse or promote products12* derived from this software without specific prior written permission.13*14*15* ALTERNATIVELY, this software may be distributed under the terms of the16* GNU General Public License ("GPL") as published by the Free Software17* Foundation, either version 2 of that License or (at your option) any18* later version.19*20* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY21* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED22* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE23* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY24* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES25* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;26* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND27* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT28* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS29* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.30*/313233/******************************************************************************34@File fm_kg.c3536@Description FM PCD ...37*//***************************************************************************/38#include "std_ext.h"39#include "error_ext.h"40#include "string_ext.h"41#include "debug_ext.h"42#include "net_ext.h"43#include "fm_port_ext.h"4445#include "fm_common.h"46#include "fm_pcd.h"47#include "fm_hc.h"48#include "fm_pcd_ipc.h"49#include "fm_kg.h"50#include "fsl_fman_kg.h"515253/****************************************/54/* static functions */55/****************************************/5657static uint32_t KgHwLock(t_Handle h_FmPcdKg)58{59ASSERT_COND(h_FmPcdKg);60return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);61}6263static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)64{65ASSERT_COND(h_FmPcdKg);66XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);67}6869static uint32_t KgSchemeLock(t_Handle h_Scheme)70{71ASSERT_COND(h_Scheme);72return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);73}7475static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)76{77ASSERT_COND(h_Scheme);78FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);79}8081static bool KgSchemeFlagTryLock(t_Handle h_Scheme)82{83ASSERT_COND(h_Scheme);84return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);85}8687static void KgSchemeFlagUnlock(t_Handle h_Scheme)88{89ASSERT_COND(h_Scheme);90FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);91}9293static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)94{9596struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;9798if (fman_kg_write_ar_wait(regs, fmkg_ar))99RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));100101return E_OK;102}103104static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)105{106int i;107108switch (code)109{110case (KG_SCH_GEN_PARSE_RESULT_N_FQID):111case (KG_SCH_GEN_DEFAULT):112case (KG_SCH_GEN_NEXTHDR):113for (i=0 ; i<numOfSwDefaults ; i++)114if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)115return swDefaults[i].dfltSelect;116break;117case (KG_SCH_GEN_SHIM1):118case (KG_SCH_GEN_SHIM2):119case (KG_SCH_GEN_IP_PID_NO_V):120case (KG_SCH_GEN_ETH_NO_V):121case (KG_SCH_GEN_SNAP_NO_V):122case (KG_SCH_GEN_VLAN1_NO_V):123case (KG_SCH_GEN_VLAN2_NO_V):124case (KG_SCH_GEN_ETH_TYPE_NO_V):125case (KG_SCH_GEN_PPP_NO_V):126case (KG_SCH_GEN_MPLS1_NO_V):127case (KG_SCH_GEN_MPLS_LAST_NO_V):128case (KG_SCH_GEN_L3_NO_V):129case (KG_SCH_GEN_IP2_NO_V):130case (KG_SCH_GEN_GRE_NO_V):131case (KG_SCH_GEN_L4_NO_V):132for (i=0 ; i<numOfSwDefaults ; i++)133if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)134return swDefaults[i].dfltSelect;135break;136case (KG_SCH_GEN_START_OF_FRM):137case (KG_SCH_GEN_ETH):138case (KG_SCH_GEN_SNAP):139case (KG_SCH_GEN_VLAN1):140case (KG_SCH_GEN_VLAN2):141case (KG_SCH_GEN_ETH_TYPE):142case (KG_SCH_GEN_PPP):143case (KG_SCH_GEN_MPLS1):144case (KG_SCH_GEN_MPLS2):145case (KG_SCH_GEN_MPLS3):146case (KG_SCH_GEN_MPLS_LAST):147case (KG_SCH_GEN_IPV4):148case (KG_SCH_GEN_IPV6):149case (KG_SCH_GEN_IPV4_TUNNELED):150case (KG_SCH_GEN_IPV6_TUNNELED):151case (KG_SCH_GEN_MIN_ENCAP):152case (KG_SCH_GEN_GRE):153case (KG_SCH_GEN_TCP):154case (KG_SCH_GEN_UDP):155case (KG_SCH_GEN_IPSEC_AH):156case (KG_SCH_GEN_SCTP):157case (KG_SCH_GEN_DCCP):158case (KG_SCH_GEN_IPSEC_ESP):159for (i=0 ; i<numOfSwDefaults ; i++)160if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)161return swDefaults[i].dfltSelect;162break;163default:164break;165}166167return e_FM_PCD_KG_DFLT_ILLEGAL;168}169170static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)171{172*p_Offset = 0;173174switch (src)175{176case (e_FM_PCD_EXTRACT_FROM_FRAME_START):177return KG_SCH_GEN_START_OF_FRM;178case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):179return KG_SCH_GEN_DEFAULT;180case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):181return KG_SCH_GEN_PARSE_RESULT_N_FQID;182case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):183*p_Offset = 32;184return KG_SCH_GEN_PARSE_RESULT_N_FQID;185case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):186return KG_SCH_GEN_NEXTHDR;187default:188REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));189return 0;190}191}192193static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)194{195if (!ignoreProtocolValidation)196switch (hdr)197{198case (HEADER_TYPE_NONE):199ASSERT_COND(FALSE);200case (HEADER_TYPE_ETH):201return KG_SCH_GEN_ETH;202case (HEADER_TYPE_LLC_SNAP):203return KG_SCH_GEN_SNAP;204case (HEADER_TYPE_PPPoE):205return KG_SCH_GEN_PPP;206case (HEADER_TYPE_MPLS):207if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))208return KG_SCH_GEN_MPLS1;209if (hdrIndex == e_FM_PCD_HDR_INDEX_2)210return KG_SCH_GEN_MPLS2;211if (hdrIndex == e_FM_PCD_HDR_INDEX_3)212return KG_SCH_GEN_MPLS3;213if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)214return KG_SCH_GEN_MPLS_LAST;215REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));216return 0;217case (HEADER_TYPE_IPv4):218if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))219return KG_SCH_GEN_IPV4;220if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))221return KG_SCH_GEN_IPV4_TUNNELED;222REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));223return 0;224case (HEADER_TYPE_IPv6):225if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))226return KG_SCH_GEN_IPV6;227if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))228return KG_SCH_GEN_IPV6_TUNNELED;229REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));230return 0;231case (HEADER_TYPE_GRE):232return KG_SCH_GEN_GRE;233case (HEADER_TYPE_TCP):234return KG_SCH_GEN_TCP;235case (HEADER_TYPE_UDP):236return KG_SCH_GEN_UDP;237case (HEADER_TYPE_IPSEC_AH):238return KG_SCH_GEN_IPSEC_AH;239case (HEADER_TYPE_IPSEC_ESP):240return KG_SCH_GEN_IPSEC_ESP;241case (HEADER_TYPE_SCTP):242return KG_SCH_GEN_SCTP;243case (HEADER_TYPE_DCCP):244return KG_SCH_GEN_DCCP;245default:246REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));247return 0;248}249else250switch (hdr)251{252case (HEADER_TYPE_NONE):253ASSERT_COND(FALSE);254case (HEADER_TYPE_ETH):255return KG_SCH_GEN_ETH_NO_V;256case (HEADER_TYPE_LLC_SNAP):257return KG_SCH_GEN_SNAP_NO_V;258case (HEADER_TYPE_PPPoE):259return KG_SCH_GEN_PPP_NO_V;260case (HEADER_TYPE_MPLS):261if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))262return KG_SCH_GEN_MPLS1_NO_V;263if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)264return KG_SCH_GEN_MPLS_LAST_NO_V;265if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )266REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));267else268REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));269return 0;270case (HEADER_TYPE_IPv4):271case (HEADER_TYPE_IPv6):272if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))273return KG_SCH_GEN_L3_NO_V;274if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))275return KG_SCH_GEN_IP2_NO_V;276REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));277case (HEADER_TYPE_MINENCAP):278return KG_SCH_GEN_IP2_NO_V;279case (HEADER_TYPE_USER_DEFINED_L3):280return KG_SCH_GEN_L3_NO_V;281case (HEADER_TYPE_GRE):282return KG_SCH_GEN_GRE_NO_V;283case (HEADER_TYPE_TCP):284case (HEADER_TYPE_UDP):285case (HEADER_TYPE_IPSEC_AH):286case (HEADER_TYPE_IPSEC_ESP):287case (HEADER_TYPE_SCTP):288case (HEADER_TYPE_DCCP):289return KG_SCH_GEN_L4_NO_V;290case (HEADER_TYPE_USER_DEFINED_SHIM1):291return KG_SCH_GEN_SHIM1;292case (HEADER_TYPE_USER_DEFINED_SHIM2):293return KG_SCH_GEN_SHIM2;294default:295REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));296return 0;297}298}299static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)300{301if (!ignoreProtocolValidation)302switch (hdr)303{304case (HEADER_TYPE_NONE):305ASSERT_COND(FALSE);306break;307case (HEADER_TYPE_ETH):308switch (field.eth)309{310case (NET_HEADER_FIELD_ETH_TYPE):311return KG_SCH_GEN_ETH_TYPE;312default:313REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));314return 0;315}316break;317case (HEADER_TYPE_VLAN):318switch (field.vlan)319{320case (NET_HEADER_FIELD_VLAN_TCI):321if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))322return KG_SCH_GEN_VLAN1;323if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)324return KG_SCH_GEN_VLAN2;325REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));326return 0;327}328break;329case (HEADER_TYPE_MPLS):330case (HEADER_TYPE_IPSEC_AH):331case (HEADER_TYPE_IPSEC_ESP):332case (HEADER_TYPE_LLC_SNAP):333case (HEADER_TYPE_PPPoE):334case (HEADER_TYPE_IPv4):335case (HEADER_TYPE_IPv6):336case (HEADER_TYPE_GRE):337case (HEADER_TYPE_MINENCAP):338case (HEADER_TYPE_USER_DEFINED_L3):339case (HEADER_TYPE_TCP):340case (HEADER_TYPE_UDP):341case (HEADER_TYPE_SCTP):342case (HEADER_TYPE_DCCP):343case (HEADER_TYPE_USER_DEFINED_L4):344REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));345return 0;346default:347break;348349}350else351switch (hdr)352{353case (HEADER_TYPE_NONE):354ASSERT_COND(FALSE);355break;356case (HEADER_TYPE_ETH):357switch (field.eth)358{359case (NET_HEADER_FIELD_ETH_TYPE):360return KG_SCH_GEN_ETH_TYPE_NO_V;361default:362REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));363return 0;364}365break;366case (HEADER_TYPE_VLAN):367switch (field.vlan)368{369case (NET_HEADER_FIELD_VLAN_TCI) :370if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))371return KG_SCH_GEN_VLAN1_NO_V;372if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)373return KG_SCH_GEN_VLAN2_NO_V;374REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));375return 0;376}377break;378case (HEADER_TYPE_IPv4):379switch (field.ipv4)380{381case (NET_HEADER_FIELD_IPv4_PROTO):382return KG_SCH_GEN_IP_PID_NO_V;383default:384REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));385return 0;386}387break;388case (HEADER_TYPE_IPv6):389switch (field.ipv6)390{391case (NET_HEADER_FIELD_IPv6_NEXT_HDR):392return KG_SCH_GEN_IP_PID_NO_V;393default:394REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));395return 0;396}397break;398case (HEADER_TYPE_MPLS):399case (HEADER_TYPE_LLC_SNAP):400case (HEADER_TYPE_PPPoE):401case (HEADER_TYPE_GRE):402case (HEADER_TYPE_MINENCAP):403case (HEADER_TYPE_USER_DEFINED_L3):404case (HEADER_TYPE_TCP):405case (HEADER_TYPE_UDP):406case (HEADER_TYPE_IPSEC_AH):407case (HEADER_TYPE_IPSEC_ESP):408case (HEADER_TYPE_SCTP):409case (HEADER_TYPE_DCCP):410case (HEADER_TYPE_USER_DEFINED_L4):411REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));412return 0;413default:414break;415}416REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));417return 0;418}419420static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)421{422UNUSED(p_FmPcd);423424switch (hdr)425{426case (HEADER_TYPE_NONE):427ASSERT_COND(FALSE);428break;429case (HEADER_TYPE_ETH):430switch (field.eth)431{432case (NET_HEADER_FIELD_ETH_DA):433return KG_SCH_KN_MACDST;434case (NET_HEADER_FIELD_ETH_SA):435return KG_SCH_KN_MACSRC;436case (NET_HEADER_FIELD_ETH_TYPE):437return KG_SCH_KN_ETYPE;438default:439REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));440return 0;441}442case (HEADER_TYPE_LLC_SNAP):443switch (field.llcSnap)444{445case (NET_HEADER_FIELD_LLC_SNAP_TYPE):446return KG_SCH_KN_ETYPE;447default:448REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));449return 0;450}451case (HEADER_TYPE_VLAN):452switch (field.vlan)453{454case (NET_HEADER_FIELD_VLAN_TCI):455if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))456return KG_SCH_KN_TCI1;457if (index == e_FM_PCD_HDR_INDEX_LAST)458return KG_SCH_KN_TCI2;459else460{461REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));462return 0;463}464default:465REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));466return 0;467}468case (HEADER_TYPE_MPLS):469switch (field.mpls)470{471case (NET_HEADER_FIELD_MPLS_LABEL_STACK):472if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))473return KG_SCH_KN_MPLS1;474if (index == e_FM_PCD_HDR_INDEX_2)475return KG_SCH_KN_MPLS2;476if (index == e_FM_PCD_HDR_INDEX_LAST)477return KG_SCH_KN_MPLS_LAST;478REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));479return 0;480default:481REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));482return 0;483}484case (HEADER_TYPE_IPv4):485switch (field.ipv4)486{487case (NET_HEADER_FIELD_IPv4_SRC_IP):488if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))489return KG_SCH_KN_IPSRC1;490if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))491return KG_SCH_KN_IPSRC2;492REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));493return 0;494case (NET_HEADER_FIELD_IPv4_DST_IP):495if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))496return KG_SCH_KN_IPDST1;497if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))498return KG_SCH_KN_IPDST2;499REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));500return 0;501case (NET_HEADER_FIELD_IPv4_PROTO):502if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))503return KG_SCH_KN_PTYPE1;504if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))505return KG_SCH_KN_PTYPE2;506REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));507return 0;508case (NET_HEADER_FIELD_IPv4_TOS):509if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))510return KG_SCH_KN_IPTOS_TC1;511if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))512return KG_SCH_KN_IPTOS_TC2;513REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));514return 0;515default:516REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));517return 0;518}519case (HEADER_TYPE_IPv6):520switch (field.ipv6)521{522case (NET_HEADER_FIELD_IPv6_SRC_IP):523if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))524return KG_SCH_KN_IPSRC1;525if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))526return KG_SCH_KN_IPSRC2;527REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));528return 0;529case (NET_HEADER_FIELD_IPv6_DST_IP):530if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))531return KG_SCH_KN_IPDST1;532if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))533return KG_SCH_KN_IPDST2;534REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));535return 0;536case (NET_HEADER_FIELD_IPv6_NEXT_HDR):537if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))538return KG_SCH_KN_PTYPE1;539if (index == e_FM_PCD_HDR_INDEX_2)540return KG_SCH_KN_PTYPE2;541if (index == e_FM_PCD_HDR_INDEX_LAST)542#ifdef FM_KG_NO_IPPID_SUPPORT543if (p_FmPcd->fmRevInfo.majorRev < 6)544return KG_SCH_KN_PTYPE2;545#endif /* FM_KG_NO_IPPID_SUPPORT */546return KG_SCH_KN_IPPID;547REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));548return 0;549case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):550if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))551return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);552if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))553return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);554REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));555return 0;556case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):557if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))558return KG_SCH_KN_IPTOS_TC1;559if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))560return KG_SCH_KN_IPTOS_TC2;561REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));562return 0;563case (NET_HEADER_FIELD_IPv6_FL):564if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))565return KG_SCH_KN_IPV6FL1;566if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))567return KG_SCH_KN_IPV6FL2;568REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));569return 0;570default:571REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));572return 0;573}574case (HEADER_TYPE_GRE):575switch (field.gre)576{577case (NET_HEADER_FIELD_GRE_TYPE):578return KG_SCH_KN_GREPTYPE;579default:580REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));581return 0;582}583case (HEADER_TYPE_MINENCAP):584switch (field.minencap)585{586case (NET_HEADER_FIELD_MINENCAP_SRC_IP):587return KG_SCH_KN_IPSRC2;588case (NET_HEADER_FIELD_MINENCAP_DST_IP):589return KG_SCH_KN_IPDST2;590case (NET_HEADER_FIELD_MINENCAP_TYPE):591return KG_SCH_KN_PTYPE2;592default:593REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));594return 0;595}596case (HEADER_TYPE_TCP):597switch (field.tcp)598{599case (NET_HEADER_FIELD_TCP_PORT_SRC):600return KG_SCH_KN_L4PSRC;601case (NET_HEADER_FIELD_TCP_PORT_DST):602return KG_SCH_KN_L4PDST;603case (NET_HEADER_FIELD_TCP_FLAGS):604return KG_SCH_KN_TFLG;605default:606REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));607return 0;608}609case (HEADER_TYPE_UDP):610switch (field.udp)611{612case (NET_HEADER_FIELD_UDP_PORT_SRC):613return KG_SCH_KN_L4PSRC;614case (NET_HEADER_FIELD_UDP_PORT_DST):615return KG_SCH_KN_L4PDST;616default:617REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));618return 0;619}620case (HEADER_TYPE_IPSEC_AH):621switch (field.ipsecAh)622{623case (NET_HEADER_FIELD_IPSEC_AH_SPI):624return KG_SCH_KN_IPSEC_SPI;625case (NET_HEADER_FIELD_IPSEC_AH_NH):626return KG_SCH_KN_IPSEC_NH;627default:628REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));629return 0;630}631case (HEADER_TYPE_IPSEC_ESP):632switch (field.ipsecEsp)633{634case (NET_HEADER_FIELD_IPSEC_ESP_SPI):635return KG_SCH_KN_IPSEC_SPI;636default:637REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));638return 0;639}640case (HEADER_TYPE_SCTP):641switch (field.sctp)642{643case (NET_HEADER_FIELD_SCTP_PORT_SRC):644return KG_SCH_KN_L4PSRC;645case (NET_HEADER_FIELD_SCTP_PORT_DST):646return KG_SCH_KN_L4PDST;647default:648REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));649return 0;650}651case (HEADER_TYPE_DCCP):652switch (field.dccp)653{654case (NET_HEADER_FIELD_DCCP_PORT_SRC):655return KG_SCH_KN_L4PSRC;656case (NET_HEADER_FIELD_DCCP_PORT_DST):657return KG_SCH_KN_L4PDST;658default:659REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));660return 0;661}662case (HEADER_TYPE_PPPoE):663switch (field.pppoe)664{665case (NET_HEADER_FIELD_PPPoE_PID):666return KG_SCH_KN_PPPID;667case (NET_HEADER_FIELD_PPPoE_SID):668return KG_SCH_KN_PPPSID;669default:670REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));671return 0;672}673default:674break;675676}677678REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));679return 0;680}681682683static uint8_t GetKnownFieldId(uint32_t bitMask)684{685uint8_t cnt = 0;686687while (bitMask)688if (bitMask & 0x80000000)689break;690else691{692cnt++;693bitMask <<= 1;694}695return cnt;696697}698699static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)700{701uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;702703/* bitOffset 1-7 --> mask 0x1-0x7F */704if (bitOffset<8)705{706mask = 0;707for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)708mask |= walking1Mask;709}710else711{712mask = 0xFF;713numOfOnesToClear = 0;714if (fqid && bitOffset>24)715/* bitOffset 25-31 --> mask 0xFE-0x80 */716numOfOnesToClear = (uint8_t)(bitOffset-24);717else718/* bitOffset 9-15 --> mask 0xFE-0x80 */719if (!fqid && bitOffset>8)720numOfOnesToClear = (uint8_t)(bitOffset-8);721for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)722mask &= ~walking1Mask;723/* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/724}725return mask;726}727728static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)729{730t_FmPcdKg *p_FmPcdKg;731t_FmPcdKgScheme *p_Scheme;732uint32_t intFlags;733uint8_t relativeSchemeId;734int i;735736p_FmPcdKg = p_FmPcd->p_FmPcdKg;737738/* for each scheme - update owners counters */739for (i = 0; i < p_BindPort->numOfSchemes; i++)740{741relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);742ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);743744p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];745746/* increment owners number */747intFlags = KgSchemeLock(p_Scheme);748p_Scheme->owners++;749KgSchemeUnlock(p_Scheme, intFlags);750}751}752753static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)754{755t_FmPcdKg *p_FmPcdKg;756t_FmPcdKgScheme *p_Scheme;757uint32_t intFlags;758uint8_t relativeSchemeId;759int i;760761p_FmPcdKg = p_FmPcd->p_FmPcdKg;762763/* for each scheme - update owners counters */764for (i = 0; i < p_BindPort->numOfSchemes; i++)765{766relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);767ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);768769p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];770771/* increment owners number */772ASSERT_COND(p_Scheme->owners);773intFlags = KgSchemeLock(p_Scheme);774p_Scheme->owners--;775KgSchemeUnlock(p_Scheme, intFlags);776}777}778779static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)780{781/* this routine is locked by the calling routine */782ASSERT_COND(p_Scheme);783ASSERT_COND(p_Scheme->valid);784785if (set)786p_Scheme->requiredActionFlag = TRUE;787else788{789p_Scheme->requiredAction = 0;790p_Scheme->requiredActionFlag = FALSE;791}792}793794static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)795{796struct fman_kg_regs *p_KgRegs;797798uint32_t tmpKgarReg = 0, intFlags;799t_Error err = E_OK;800801/* The calling routine had locked the port, so for each port only one core can access802* (so we don't need a lock here) */803804if (p_FmPcd->h_Hc)805return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);806807p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;808809tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);810/* lock a common KG reg */811intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);812err = WriteKgarWait(p_FmPcd, tmpKgarReg);813if (err)814{815KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);816RETURN_ERROR(MINOR, err, NO_MSG);817}818819fman_kg_write_sp(p_KgRegs, spReg, add);820821tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);822823err = WriteKgarWait(p_FmPcd, tmpKgarReg);824KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);825return err;826}827828static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)829{830struct fman_kg_regs *p_KgRegs;831uint32_t tmpKgarReg, intFlags;832t_Error err;833834p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;835836if (p_FmPcd->h_Hc)837{838err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);839return err;840}841842intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);843fman_kg_write_cpp(p_KgRegs, cppReg);844tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);845err = WriteKgarWait(p_FmPcd, tmpKgarReg);846KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);847848return err;849}850851static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)852{853uint32_t tmpKgpeCpp;854855tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);856tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);857858return tmpKgpeCpp;859}860861static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)862{863uint32_t tmpKgpeCpp = 0;864865tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);866return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);867}868869static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)870{871KgWriteCpp(p_FmPcd, hardwarePortId, 0);872}873874#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))875static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)876{877return (uint32_t)(FM_KG_KGAR_GO |878FM_KG_KGAR_READ |879FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |880DUMMY_PORT_ID |881((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |882FM_PCD_KG_KGAR_WSEL_MASK);883884/* if we ever want to write 1 by 1, use:885sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));886*/887}888#endif /* (defined(DEBUG_ERRORS) && ... */889890static void PcdKgErrorException(t_Handle h_FmPcd)891{892t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;893uint32_t event,schemeIndexes = 0, index = 0;894struct fman_kg_regs *p_KgRegs;895896ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));897p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;898fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);899900if (event & FM_EX_KG_DOUBLE_ECC)901p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);902if (event & FM_EX_KG_KEYSIZE_OVERFLOW)903{904if (schemeIndexes)905{906while (schemeIndexes)907{908if (schemeIndexes & 0x1)909p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));910schemeIndexes >>= 1;911index+=1;912}913}914else /* this should happen only when interrupt is forced. */915p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);916}917}918919static t_Error KgInitGuest(t_FmPcd *p_FmPcd)920{921t_Error err = E_OK;922t_FmPcdIpcKgSchemesParams kgAlloc;923uint32_t replyLength;924t_FmPcdIpcReply reply;925t_FmPcdIpcMsg msg;926927ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);928929/* in GUEST_PARTITION, we use the IPC */930memset(&reply, 0, sizeof(reply));931memset(&msg, 0, sizeof(msg));932memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));933kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;934kgAlloc.guestId = p_FmPcd->guestId;935msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;936memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));937replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);938if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,939(uint8_t*)&msg,940sizeof(msg.msgId) + sizeof(kgAlloc),941(uint8_t*)&reply,942&replyLength,943NULL,944NULL)) != E_OK)945RETURN_ERROR(MAJOR, err, NO_MSG);946if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))947RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));948memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));949950return (t_Error)reply.error;951}952953static t_Error KgInitMaster(t_FmPcd *p_FmPcd)954{955t_Error err = E_OK;956struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;957958ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);959960if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)961FmEnableRamsEcc(p_FmPcd->h_Fm);962963fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));964965/* register even if no interrupts enabled, to allow future enablement */966FmRegisterIntr(p_FmPcd->h_Fm,967e_FM_MOD_KG,9680,969e_FM_INTR_TYPE_ERR,970PcdKgErrorException,971p_FmPcd);972973fman_kg_enable_scheme_interrupts(p_Regs);974975if (p_FmPcd->p_FmPcdKg->numOfSchemes)976{977err = FmPcdKgAllocSchemes(p_FmPcd,978p_FmPcd->p_FmPcdKg->numOfSchemes,979p_FmPcd->guestId,980p_FmPcd->p_FmPcdKg->schemesIds);981if (err)982RETURN_ERROR(MINOR, err, NO_MSG);983}984985return E_OK;986}987988static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)989{990ASSERT_COND(!p_Scheme->valid);991if (p_Scheme->netEnvId != ILLEGAL_NETENV)992FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);993p_Scheme->valid = TRUE;994}995996static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)997{998if (p_Scheme->owners)999RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));10001001if (p_Scheme->netEnvId != ILLEGAL_NETENV)1002FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);1003p_Scheme->valid = FALSE;10041005return E_OK;1006}10071008static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,1009t_FmPcdKgSchemeParams *p_SchemeParams,1010struct fman_kg_scheme_regs *p_SchemeRegs)1011{1012t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);1013uint32_t grpBits = 0;1014uint8_t grpBase;1015bool direct=TRUE, absolute=FALSE;1016uint16_t profileId=0, numOfProfiles=0, relativeProfileId;1017t_Error err = E_OK;1018int i = 0;1019t_NetEnvParams netEnvParams;1020uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;1021t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;1022uint8_t j, curr, idx;1023uint8_t id, shift=0, code=0, offset=0, size=0;1024t_FmPcdExtractEntry *p_Extract = NULL;1025t_FmPcdKgExtractedOrParams *p_ExtractOr;1026bool generic = FALSE;1027t_KnownFieldsMasks bitMask;1028e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;1029t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;1030uint8_t numOfSwDefaults = 0;1031t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];1032uint8_t currGenId = 0;10331034memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));1035memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));10361037if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)1038RETURN_ERROR(MAJOR, E_INVALID_VALUE,1039("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));10401041/* by netEnv parameters, get match vector */1042if (!p_SchemeParams->alwaysDirect)1043{1044p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);1045netEnvParams.netEnvId = p_Scheme->netEnvId;1046netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;1047memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);1048err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);1049if (err)1050RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);1051p_Scheme->matchVector = netEnvParams.vector;1052}1053else1054{1055p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;1056p_Scheme->netEnvId = ILLEGAL_NETENV;1057}10581059if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)1060RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));10611062if (p_SchemeParams->bypassFqidGeneration)1063{1064#ifdef FM_KG_NO_BYPASS_FQID_GEN1065if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))1066RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));1067#endif /* FM_KG_NO_BYPASS_FQID_GEN */1068if (p_SchemeParams->baseFqid)1069RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));1070}1071else1072if (!p_SchemeParams->baseFqid)1073DBG(WARNING, ("baseFqid is 0."));10741075if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)1076{1077direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;1078p_Scheme->directPlcr = direct;1079absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);1080if (!direct && absolute)1081RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));10821083if (direct)1084{1085profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;1086numOfProfiles = 1;1087}1088else1089{1090profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;1091shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;1092numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;1093}1094}10951096if (p_SchemeParams->nextEngine == e_FM_PCD_CC)1097{1098#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN1099if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))1100{1101if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))1102RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));1103}1104#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */11051106err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,1107p_SchemeParams->kgNextEngineParams.cc.grpId,1108&grpBits,1109&grpBase);1110if (err)1111RETURN_ERROR(MAJOR, err, NO_MSG);1112p_Scheme->ccUnits = grpBits;11131114if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&1115(!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))1116{1117if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)1118RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));1119absolute = FALSE;1120direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;1121if (direct)1122{1123profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;1124numOfProfiles = 1;1125}1126else1127{1128profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;1129shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;1130numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;1131}1132}1133}11341135/* if policer is used directly after KG, or after CC */1136if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||1137((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&1138(p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&1139(!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))1140{1141/* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */1142if (absolute)1143{1144/* for absolute direct policy only, */1145relativeProfileId = profileId;1146err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);1147if (err)1148RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));1149if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))1150RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));1151p_Scheme->relativeProfileId = profileId;1152}1153else1154{1155/* save relative profile id's for later check */1156p_Scheme->nextRelativePlcrProfile = TRUE;1157p_Scheme->relativeProfileId = profileId;1158p_Scheme->numOfProfiles = numOfProfiles;1159}1160}1161else1162{1163/* if policer is NOT going to be used after KG at all than if bypassFqidGeneration1164is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */1165if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)1166RETURN_ERROR(MAJOR, E_INVALID_STATE,1167("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));1168if (p_SchemeParams->bypassFqidGeneration &&1169p_SchemeParams->useHash &&1170p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)1171RETURN_ERROR(MAJOR, E_INVALID_STATE,1172("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));1173}11741175/* configure all 21 scheme registers */1176tmpReg = KG_SCH_MODE_EN;1177switch (p_SchemeParams->nextEngine)1178{1179case (e_FM_PCD_PLCR):1180/* add to mode register - NIA */1181tmpReg |= KG_SCH_MODE_NIA_PLCR;1182tmpReg |= NIA_ENG_PLCR;1183tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);1184/* initialize policer profile command - */1185/* configure kgse_ppc */1186if (direct)1187/* use profileId as base, other fields are 0 */1188p_SchemeRegs->kgse_ppc = (uint32_t)profileId;1189else1190{1191if (shift > MAX_PP_SHIFT)1192RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));11931194if (!numOfProfiles || !POWER_OF_2(numOfProfiles))1195RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));11961197ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;1198ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;1199ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);1200ppcTmp |= (uint32_t)profileId;12011202p_SchemeRegs->kgse_ppc = ppcTmp;1203}1204break;1205case (e_FM_PCD_CC):1206/* mode reg - define NIA */1207tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);12081209p_SchemeRegs->kgse_ccbs = grpBits;1210tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);12111212if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)1213{1214if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)1215{1216/* find out if absolute or relative */1217if (absolute)1218RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("It is illegal to request a shared profile in a scheme that is in a KG->CC->PLCR flow"));1219if (direct)1220{1221/* mask = 0, base = directProfileId */1222p_SchemeRegs->kgse_ppc = (uint32_t)profileId;1223}1224else1225{1226if (shift > MAX_PP_SHIFT)1227RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));1228if (!numOfProfiles || !POWER_OF_2(numOfProfiles))1229RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));12301231ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;1232ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;1233ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);1234ppcTmp |= (uint32_t)profileId;12351236p_SchemeRegs->kgse_ppc = ppcTmp;1237}1238}1239}1240break;1241case (e_FM_PCD_DONE):1242if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)1243tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);1244else1245tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);1246break;1247default:1248RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));1249}1250p_SchemeRegs->kgse_mode = tmpReg;12511252p_SchemeRegs->kgse_mv = p_Scheme->matchVector;12531254#if (DPAA_VERSION >= 11)1255if (p_SchemeParams->overrideStorageProfile)1256{1257p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;12581259if (p_SchemeParams->storageProfile.direct)1260{1261profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;1262shift = 0;1263numOfProfiles = 1;1264}1265else1266{1267profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;1268shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;1269numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;1270}1271if (shift > MAX_SP_SHIFT)1272RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));12731274if (!numOfProfiles || !POWER_OF_2(numOfProfiles))1275RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));12761277tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;1278tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);1279tmpReg |= (uint32_t)profileId;128012811282p_SchemeRegs->kgse_vsp = tmpReg;12831284p_Scheme->vspe = TRUE;12851286}1287else1288p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;1289#endif /* (DPAA_VERSION >= 11) */12901291if (p_SchemeParams->useHash)1292{1293p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;12941295if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)1296RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));12971298/* configure kgse_dv0 */1299p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;13001301/* configure kgse_dv1 */1302p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;13031304if (!p_SchemeParams->bypassFqidGeneration)1305{1306if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))1307RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));1308if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)1309DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));1310}13111312/* configure kgse_ekdv */1313tmpReg = 0;1314for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)1315{1316switch (p_KeyAndHash->dflts[i].type)1317{1318case (e_FM_PCD_KG_MAC_ADDR):1319tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);1320break;1321case (e_FM_PCD_KG_TCI):1322tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);1323break;1324case (e_FM_PCD_KG_ENET_TYPE):1325tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);1326break;1327case (e_FM_PCD_KG_PPP_SESSION_ID):1328tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);1329break;1330case (e_FM_PCD_KG_PPP_PROTOCOL_ID):1331tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);1332break;1333case (e_FM_PCD_KG_MPLS_LABEL):1334tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);1335break;1336case (e_FM_PCD_KG_IP_ADDR):1337tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);1338break;1339case (e_FM_PCD_KG_PROTOCOL_TYPE):1340tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);1341break;1342case (e_FM_PCD_KG_IP_TOS_TC):1343tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);1344break;1345case (e_FM_PCD_KG_IPV6_FLOW_LABEL):1346tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);1347break;1348case (e_FM_PCD_KG_IPSEC_SPI):1349tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);1350break;1351case (e_FM_PCD_KG_L4_PORT):1352tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);1353break;1354case (e_FM_PCD_KG_TCP_FLAG):1355tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);1356break;1357case (e_FM_PCD_KG_GENERIC_FROM_DATA):1358swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;1359swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;1360numOfSwDefaults ++;1361break;1362case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):1363swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;1364swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;1365numOfSwDefaults ++;1366break;1367case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):1368swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;1369swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;1370numOfSwDefaults ++;1371break;1372default:1373RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);1374}1375}1376p_SchemeRegs->kgse_ekdv = tmpReg;13771378p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));1379if (!p_LocalExtractsArray)1380RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));13811382/* configure kgse_ekfc and kgse_gec */1383knownTmp = 0;1384for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)1385{1386p_Extract = &p_KeyAndHash->extractArray[i];1387switch (p_Extract->type)1388{1389case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):1390knownTmp |= KG_SCH_KN_PORT_ID;1391/* save in driver structure */1392p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);1393p_LocalExtractsArray->extractsArray[i].known = TRUE;1394break;1395case (e_FM_PCD_EXTRACT_BY_HDR):1396switch (p_Extract->extractByHdr.hdr)1397{1398#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))1399case (HEADER_TYPE_UDP_LITE):1400p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;1401break;1402#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */1403case (HEADER_TYPE_UDP_ENCAP_ESP):1404switch (p_Extract->extractByHdr.type)1405{1406case (e_FM_PCD_EXTRACT_FROM_HDR):1407/* case where extraction from ESP only */1408if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)1409{1410p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);1411p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;1412p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;1413}1414else1415{1416p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;1417p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;1418}1419break;1420case (e_FM_PCD_EXTRACT_FROM_FIELD):1421switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)1422{1423case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):1424case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):1425case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):1426case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):1427p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;1428break;1429case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):1430p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;1431p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);1432/*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/1433p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;1434break;1435case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):1436p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;1437p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);1438p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;1439p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;1440break;1441}1442break;1443case (e_FM_PCD_EXTRACT_FULL_FIELD):1444switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)1445{1446case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):1447case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):1448case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):1449case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):1450p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;1451break;1452case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):1453p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;1454p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);1455p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;1456p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;1457p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;1458break;1459case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):1460p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;1461p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);1462p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;1463p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;1464p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;1465break;1466}1467break;1468}1469break;1470default:1471break;1472}1473switch (p_Extract->extractByHdr.type)1474{1475case (e_FM_PCD_EXTRACT_FROM_HDR):1476generic = TRUE;1477/* get the header code for the generic extract */1478code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);1479/* set generic register fields */1480offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;1481size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;1482break;1483case (e_FM_PCD_EXTRACT_FROM_FIELD):1484generic = TRUE;1485/* get the field code for the generic extract */1486code = GetGenFieldCode(p_Extract->extractByHdr.hdr,1487p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);1488offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;1489size = p_Extract->extractByHdr.extractByHdrType.fromField.size;1490break;1491case (e_FM_PCD_EXTRACT_FULL_FIELD):1492if (!p_Extract->extractByHdr.ignoreProtocolValidation)1493{1494/* if we have a known field for it - use it, otherwise use generic */1495bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,1496p_Extract->extractByHdr.extractByHdrType.fullField);1497if (bitMask)1498{1499knownTmp |= bitMask;1500/* save in driver structure */1501p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);1502p_LocalExtractsArray->extractsArray[i].known = TRUE;1503}1504else1505generic = TRUE;1506}1507else1508generic = TRUE;1509if (generic)1510{1511/* tmp - till we cover more headers under generic */1512XX_Free(p_LocalExtractsArray);1513RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));1514}1515break;1516default:1517XX_Free(p_LocalExtractsArray);1518RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);1519}1520break;1521case (e_FM_PCD_EXTRACT_NON_HDR):1522/* use generic */1523generic = TRUE;1524offset = 0;1525/* get the field code for the generic extract */1526code = GetGenCode(p_Extract->extractNonHdr.src, &offset);1527offset += p_Extract->extractNonHdr.offset;1528size = p_Extract->extractNonHdr.size;1529break;1530default:1531RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);1532}15331534if (generic)1535{1536/* set generic register fields */1537if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)1538{1539XX_Free(p_LocalExtractsArray);1540RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));1541}1542if (!code)1543{1544XX_Free(p_LocalExtractsArray);1545RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);1546}15471548genTmp = KG_SCH_GEN_VALID;1549genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);1550genTmp |= offset;1551if ((size > MAX_KG_SCH_SIZE) || (size < 1))1552{1553XX_Free(p_LocalExtractsArray);1554RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));1555}1556genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);1557swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);1558if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)1559DBG(WARNING, ("No sw default configured"));1560else1561genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;15621563genTmp |= KG_SCH_GEN_MASK;1564p_SchemeRegs->kgse_gec[currGenId] = genTmp;1565/* save in driver structure */1566p_LocalExtractsArray->extractsArray[i].id = currGenId++;1567p_LocalExtractsArray->extractsArray[i].known = FALSE;1568generic = FALSE;1569}1570}1571p_SchemeRegs->kgse_ekfc = knownTmp;15721573selectTmp = 0;1574maskTmp = 0xFFFFFFFF;1575/* configure kgse_bmch, kgse_bmcl and kgse_fqb */15761577if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)1578{1579XX_Free(p_LocalExtractsArray);1580RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));1581}1582for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)1583{1584/* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */1585id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;1586/* Get the shift of the select field (depending on i) */1587GET_MASK_SEL_SHIFT(shift,i);1588if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)1589selectTmp |= id << shift;1590else1591selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;15921593/* Get the shift of the offset field (depending on i) - may1594be in kgse_bmch or in kgse_fqb (depending on i) */1595GET_MASK_OFFSET_SHIFT(shift,i);1596if (i<=1)1597selectTmp |= p_KeyAndHash->masks[i].offset << shift;1598else1599fqbTmp |= p_KeyAndHash->masks[i].offset << shift;16001601/* Get the shift of the mask field (depending on i) */1602GET_MASK_SHIFT(shift,i);1603/* pass all bits */1604maskTmp |= KG_SCH_BITMASK_MASK << shift;1605/* clear bits that need masking */1606maskTmp &= ~(0xFF << shift) ;1607/* set mask bits */1608maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;1609}1610p_SchemeRegs->kgse_bmch = selectTmp;1611p_SchemeRegs->kgse_bmcl = maskTmp;1612/* kgse_fqb will be written t the end of the routine */16131614/* configure kgse_hc */1615if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)1616{1617XX_Free(p_LocalExtractsArray);1618RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));1619}1620if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)1621{1622XX_Free(p_LocalExtractsArray);1623RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));1624}16251626tmpReg = 0;16271628tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);1629tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;16301631if (p_KeyAndHash->symmetricHash)1632{1633if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||1634(!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||1635(!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||1636(!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))1637{1638XX_Free(p_LocalExtractsArray);1639RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));1640}1641tmpReg |= KG_SCH_HASH_CONFIG_SYM;1642}1643p_SchemeRegs->kgse_hc = tmpReg;16441645/* build the return array describing the order of the extractions */16461647/* the last currGenId places of the array1648are for generic extracts that are always last.1649We now sort for the calculation of the order of the known1650extractions we sort the known extracts between orderedArray[0] and1651orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].1652for the calculation of the order of the generic extractions we use:1653num_of_generic - currGenId1654num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId1655first_generic_index = num_of_known */1656curr = 0;1657for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)1658{1659if (p_LocalExtractsArray->extractsArray[i].known)1660{1661ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));1662j = curr;1663/* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original1664index in the user's extractions array */1665/* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]1666location */1667while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <1668p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))1669{1670p_Scheme->orderedArray[j] =1671p_Scheme->orderedArray[j-1];1672j--;1673}1674p_Scheme->orderedArray[j] = (uint8_t)i;1675curr++;1676}1677else1678{1679/* index is first_generic_index + generic index (id) */1680idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);1681ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);1682p_Scheme->orderedArray[idx]= (uint8_t)i;1683}1684}1685XX_Free(p_LocalExtractsArray);1686}1687else1688{1689/* clear all unused registers: */1690p_SchemeRegs->kgse_ekfc = 0;1691p_SchemeRegs->kgse_ekdv = 0;1692p_SchemeRegs->kgse_bmch = 0;1693p_SchemeRegs->kgse_bmcl = 0;1694p_SchemeRegs->kgse_hc = 0;1695p_SchemeRegs->kgse_dv0 = 0;1696p_SchemeRegs->kgse_dv1 = 0;1697}16981699if (p_SchemeParams->bypassFqidGeneration)1700p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;17011702/* configure kgse_spc */1703if ( p_SchemeParams->schemeCounter.update)1704p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;170517061707/* check that are enough generic registers */1708if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)1709RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));17101711/* extracted OR mask on Qid */1712for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)1713{17141715p_Scheme->extractedOrs = TRUE;1716/* configure kgse_gec[i] */1717p_ExtractOr = &p_SchemeParams->extractedOrs[i];1718switch (p_ExtractOr->type)1719{1720case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):1721code = KG_SCH_GEN_PARSE_RESULT_N_FQID;1722offset = 0;1723break;1724case (e_FM_PCD_EXTRACT_BY_HDR):1725/* get the header code for the generic extract */1726code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);1727/* set generic register fields */1728offset = p_ExtractOr->extractionOffset;1729break;1730case (e_FM_PCD_EXTRACT_NON_HDR):1731/* get the field code for the generic extract */1732offset = 0;1733code = GetGenCode(p_ExtractOr->src, &offset);1734offset += p_ExtractOr->extractionOffset;1735break;1736default:1737RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);1738}17391740/* set generic register fields */1741if (!code)1742RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);1743genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;1744genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);1745genTmp |= offset;1746if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)1747RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));17481749/************************************************************************************1750bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter1751in the following way:17521753Driver API and implementation:1754==============================1755FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.1756if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that1757are not overlapping FQID.1758------------------------1759| FQID (24) |1760------------------------1761--------1762| | extracted OR byte1763--------17641765Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the1766PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that1767are not overlapping PP id.17681769--------1770| PP (8) |1771--------1772--------1773| | extracted OR byte1774--------17751776HW implementation1777=================1778FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located1779as the highest byte of that word and may be rotated to effect any part os the FQID or1780the PP.1781------------------------ --------1782| FQID (24) || PP (8) |1783------------------------ --------1784--------1785| | extracted OR byte1786--------17871788************************************************************************************/17891790if (p_ExtractOr->bitOffsetInFqid)1791{1792if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )1793RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));1794if (p_ExtractOr->bitOffsetInFqid<8)1795genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);1796else1797genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);1798p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);1799}1800else /* effect policer profile */1801{1802if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )1803RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));1804p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;1805genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);1806p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);1807}18081809genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);1810/* clear bits that need masking */1811genTmp &= ~KG_SCH_GEN_MASK ;1812/* set mask bits */1813genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);1814p_SchemeRegs->kgse_gec[currGenId++] = genTmp;18151816}1817/* clear all unused GEC registers */1818for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)1819p_SchemeRegs->kgse_gec[i] = 0;18201821/* add base Qid for this scheme */1822/* add configuration for kgse_fqb */1823if (p_SchemeParams->baseFqid & ~0x00FFFFFF)1824RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));18251826fqbTmp |= p_SchemeParams->baseFqid;1827p_SchemeRegs->kgse_fqb = fqbTmp;18281829p_Scheme->nextEngine = p_SchemeParams->nextEngine;1830p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;18311832return E_OK;1833}183418351836/*****************************************************************************/1837/* Inter-module API routines */1838/*****************************************************************************/18391840t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)1841{1842t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;1843t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;1844t_FmPcdIpcKgClsPlanParams kgAlloc;1845t_Error err = E_OK;1846uint32_t oredVectors = 0;1847int i, j;18481849/* this routine is protected by the calling routine ! */1850if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))1851RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));18521853/* find a new clsPlan group */1854for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)1855if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)1856break;1857if (i == FM_MAX_NUM_OF_PORTS)1858RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));18591860p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;18611862p_Grp->clsPlanGrpId = (uint8_t)i;18631864if (p_Grp->numOfOptions == 0)1865p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;18661867p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];1868p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;1869p_ClsPlanGrp->owners = 0;1870FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);1871if (p_Grp->numOfOptions != 0)1872FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);18731874p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);1875/* a minimal group of 8 is required */1876if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)1877p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;1878if (p_FmPcd->guestId == NCSW_MASTER_ID)1879{1880err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);18811882if (err)1883RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);1884}1885else1886{1887t_FmPcdIpcMsg msg;1888uint32_t replyLength;1889t_FmPcdIpcReply reply;18901891/* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */1892memset(&reply, 0, sizeof(reply));1893memset(&msg, 0, sizeof(msg));1894memset(&kgAlloc, 0, sizeof(kgAlloc));1895kgAlloc.guestId = p_FmPcd->guestId;1896kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;1897msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;1898memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));1899replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));1900if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,1901(uint8_t*)&msg,1902sizeof(msg.msgId) + sizeof(kgAlloc),1903(uint8_t*)&reply,1904&replyLength,1905NULL,1906NULL)) != E_OK)1907RETURN_ERROR(MAJOR, err, NO_MSG);19081909if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))1910RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));1911if ((t_Error)reply.error != E_OK)1912RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);19131914p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);1915}19161917/* build classification plan entries parameters */1918p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;1919p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;19201921oredVectors = 0;1922for (i = 0; i<p_Grp->numOfOptions; i++)1923{1924oredVectors |= p_Grp->optVectors[i];1925/* save an array of used options - the indexes represent the power of 2 index */1926p_ClsPlanGrp->optArray[i] = p_Grp->options[i];1927}1928/* set the classification plan relevant entries so that all bits1929* relevant to the list of options is cleared1930*/1931for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)1932p_ClsPlanSet->vectors[j] = ~oredVectors;19331934for (i = 0; i<p_Grp->numOfOptions; i++)1935{1936/* option i got the place 2^i in the clsPlan array. all entries that1937* have bit i set, should have the vector bit cleared. So each option1938* has one location that it is exclusive (1,2,4,8...) and represent the1939* presence of that option only, and other locations that represent a1940* combination of options.1941* e.g:1942* If ethernet-BC is option 1 it gets entry 2 in the table. Entry 21943* now represents a frame with ethernet-BC header - so the bit1944* representing ethernet-BC should be set and all other option bits1945* should be cleared.1946* Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit1947* vector[1] set, but they also have other bits set:1948* 3=1+2, options 0 and 11949* 6=2+4, options 1 and 21950* 7=1+2+4, options 0,1,and 21951* 10=2+8, options 1 and 31952* etc.1953* */19541955/* now for each option (i), we set their bits in all entries (j)1956* that contain bit 2^i.1957*/1958for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)1959{1960if (j & (1<<i))1961p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];1962}1963}19641965return E_OK;1966}19671968void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)1969{1970t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;1971t_FmPcdIpcKgClsPlanParams kgAlloc;1972t_Error err;1973t_FmPcdIpcMsg msg;1974uint32_t replyLength;1975t_FmPcdIpcReply reply;19761977/* check that no port is bound to this clsPlan */1978if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)1979{1980REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));1981return;1982}19831984FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);19851986if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)1987p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;1988else1989FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);19901991/* free blocks */1992if (p_FmPcd->guestId == NCSW_MASTER_ID)1993KgFreeClsPlanEntries(h_FmPcd,1994p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,1995p_FmPcd->guestId,1996p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);1997else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */1998{1999memset(&reply, 0, sizeof(reply));2000memset(&msg, 0, sizeof(msg));2001kgAlloc.guestId = p_FmPcd->guestId;2002kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;2003kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;2004msg.msgId = FM_PCD_FREE_KG_CLSPLAN;2005memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));2006replyLength = sizeof(uint32_t);2007err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,2008(uint8_t*)&msg,2009sizeof(msg.msgId) + sizeof(kgAlloc),2010(uint8_t*)&reply,2011&replyLength,2012NULL,2013NULL);2014if (err != E_OK)2015{2016REPORT_ERROR(MINOR, err, NO_MSG);2017return;2018}2019if (replyLength != sizeof(uint32_t))2020{2021REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));2022return;2023}2024if ((t_Error)reply.error != E_OK)2025{2026REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));2027return;2028}2029}20302031/* clear clsPlan driver structure */2032memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));2033}20342035t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)2036{2037t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;2038uint32_t j, schemesPerPortVector = 0;2039t_FmPcdKgScheme *p_Scheme;2040uint8_t i, relativeSchemeId;2041uint32_t tmp, walking1Mask;2042uint8_t swPortIndex = 0;20432044SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);2045SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);2046SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);20472048/* for each scheme */2049for (i = 0; i<p_BindPort->numOfSchemes; i++)2050{2051relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);2052if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)2053RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);20542055if (add)2056{2057p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];2058if (!FmPcdKgIsSchemeValidSw(p_Scheme))2059RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));2060/* check netEnvId of the port against the scheme netEnvId */2061if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))2062RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));20632064/* if next engine is private port policer profile, we need to check that it is valid */2065HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);2066if (p_Scheme->nextRelativePlcrProfile)2067{2068for (j = 0;j<p_Scheme->numOfProfiles;j++)2069{2070ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);2071if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)2072RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));2073if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))2074RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));2075}2076}2077if (!p_BindPort->useClsPlan)2078{2079/* This check may be redundant as port is a assigned to the whole NetEnv */20802081/* if this port does not use clsPlan, it may not be bound to schemes with units that contain2082cls plan options. Schemes that are used only directly, should not be checked.2083it also may not be bound to schemes that go to CC with units that are options - so we OR2084the match vector and the grpBits (= ccUnits) */2085if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)2086{2087uint8_t netEnvId;2088walking1Mask = 0x80000000;2089netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;2090tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;2091tmp |= p_Scheme->ccUnits;2092while (tmp)2093{2094if (tmp & walking1Mask)2095{2096tmp &= ~walking1Mask;2097if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))2098RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));2099}2100walking1Mask >>= 1;2101}2102}2103}2104}2105/* build vector */2106schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);2107}21082109*p_SpReg = schemesPerPortVector;21102111return E_OK;2112}21132114t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)2115{2116t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;2117uint32_t spReg;2118t_Error err = E_OK;21192120err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);2121if (err)2122RETURN_ERROR(MAJOR, err, NO_MSG);21232124err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);2125if (err)2126RETURN_ERROR(MAJOR, err, NO_MSG);21272128IncSchemeOwners(p_FmPcd, p_SchemeBind);21292130return E_OK;2131}21322133t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)2134{2135t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;2136uint32_t spReg;2137t_Error err = E_OK;21382139err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);2140if (err)2141RETURN_ERROR(MAJOR, err, NO_MSG);21422143err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);2144if (err)2145RETURN_ERROR(MAJOR, err, NO_MSG);21462147DecSchemeOwners(p_FmPcd, p_SchemeBind);21482149return E_OK;2150}21512152bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)2153{2154t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;21552156return p_Scheme->valid;2157}21582159bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)2160{2161t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;21622163if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)2164return TRUE;2165else2166return FALSE;2167}21682169t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)2170{2171t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;2172uint8_t i, j;21732174SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);2175SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);21762177/* This routine is issued only on master core of master partition -2178either directly or through IPC, so no need for lock */21792180for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)2181{2182if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)2183{2184p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;2185p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;2186p_SchemesIds[j] = i;2187j++;2188}2189}21902191if (j != numOfSchemes)2192{2193/* roll back */2194for (j--; j; j--)2195{2196p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;2197p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;2198p_SchemesIds[j] = 0;2199}22002201RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));2202}22032204return E_OK;2205}22062207t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)2208{2209t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;2210uint8_t i;22112212SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);2213SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);22142215/* This routine is issued only on master core of master partition -2216either directly or through IPC */22172218for (i = 0; i < numOfSchemes; i++)2219{2220if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)2221{2222RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));2223}2224if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)2225{2226RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));2227}2228p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;2229p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;2230}22312232return E_OK;2233}22342235t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)2236{2237t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;2238uint8_t numOfBlocks, blocksFound=0, first=0;2239uint8_t i, j;22402241/* This routine is issued only on master core of master partition -2242either directly or through IPC, so no need for lock */22432244if (!numOfClsPlanEntries)2245return E_OK;22462247if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))2248RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));22492250numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);22512252/* try to find consequent blocks */2253first = 0;2254for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)2255{2256if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)2257{2258blocksFound++;2259i++;2260if (blocksFound == numOfBlocks)2261break;2262}2263else2264{2265blocksFound = 0;2266/* advance i to the next aligned address */2267first = i = (uint8_t)(first + numOfBlocks);2268}2269}22702271if (blocksFound == numOfBlocks)2272{2273*p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);2274for (j = first; j < (first + numOfBlocks); j++)2275{2276p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;2277p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;2278}2279return E_OK;2280}2281else2282RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));2283}22842285void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)2286{2287t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;2288uint8_t numOfBlocks;2289uint8_t i, baseBlock;22902291#ifdef DISABLE_ASSERTIONS2292UNUSED(guestId);2293#endif /* DISABLE_ASSERTIONS */22942295/* This routine is issued only on master core of master partition -2296either directly or through IPC, so no need for lock */22972298numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);2299ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));23002301baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);2302for (i=baseBlock;i<baseBlock+numOfBlocks;i++)2303{2304ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);2305ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);2306p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;2307p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;2308}2309}23102311void KgEnable(t_FmPcd *p_FmPcd)2312{2313struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;23142315ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));2316fman_kg_enable(p_Regs);2317}23182319void KgDisable(t_FmPcd *p_FmPcd)2320{2321struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;23222323ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));2324fman_kg_disable(p_Regs);2325}23262327void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)2328{2329t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;2330struct fman_kg_cp_regs *p_FmPcdKgPortRegs;2331uint32_t tmpKgarReg = 0, intFlags;2332uint16_t i, j;23332334/* This routine is protected by the calling routine ! */2335ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));2336p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;23372338intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);2339for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)2340{2341tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));23422343for (j = i; j < i+8; j++)2344{2345ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));2346WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);2347}23482349if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)2350{2351REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));2352KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);2353return;2354}2355}2356KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);2357}23582359t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)2360{2361t_FmPcdKg *p_FmPcdKg;23622363UNUSED(p_FmPcd);23642365if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)2366{2367REPORT_ERROR(MAJOR, E_INVALID_VALUE,2368("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));2369return NULL;2370}23712372p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));2373if (!p_FmPcdKg)2374{2375REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));2376return NULL;2377}2378memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));237923802381if (FmIsMaster(p_FmPcd->h_Fm))2382{2383p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));2384p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;2385p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];2386}23872388p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;2389if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)2390{2391p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;2392DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));2393}23942395p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;23962397return p_FmPcdKg;2398}23992400t_Error KgInit(t_FmPcd *p_FmPcd)2401{2402t_Error err = E_OK;24032404p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();2405if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)2406RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));24072408if (p_FmPcd->guestId == NCSW_MASTER_ID)2409err = KgInitMaster(p_FmPcd);2410else2411err = KgInitGuest(p_FmPcd);24122413if (err != E_OK)2414{2415if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)2416XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);2417}24182419return err;2420}24212422t_Error KgFree(t_FmPcd *p_FmPcd)2423{2424t_FmPcdIpcKgSchemesParams kgAlloc;2425t_Error err = E_OK;2426t_FmPcdIpcMsg msg;2427uint32_t replyLength;2428t_FmPcdIpcReply reply;24292430FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);24312432if (p_FmPcd->guestId == NCSW_MASTER_ID)2433{2434err = FmPcdKgFreeSchemes(p_FmPcd,2435p_FmPcd->p_FmPcdKg->numOfSchemes,2436p_FmPcd->guestId,2437p_FmPcd->p_FmPcdKg->schemesIds);2438if (err)2439RETURN_ERROR(MAJOR, err, NO_MSG);24402441if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)2442XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);24432444return E_OK;2445}24462447/* guest */2448memset(&reply, 0, sizeof(reply));2449memset(&msg, 0, sizeof(msg));2450kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;2451kgAlloc.guestId = p_FmPcd->guestId;2452ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);2453memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);2454msg.msgId = FM_PCD_FREE_KG_SCHEMES;2455memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));2456replyLength = sizeof(uint32_t);2457if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,2458(uint8_t*)&msg,2459sizeof(msg.msgId) + sizeof(kgAlloc),2460(uint8_t*)&reply,2461&replyLength,2462NULL,2463NULL)) != E_OK)2464RETURN_ERROR(MAJOR, err, NO_MSG);2465if (replyLength != sizeof(uint32_t))2466RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));24672468if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)2469XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);24702471return (t_Error)reply.error;2472}24732474t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)2475{2476t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;2477t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;2478t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;2479t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;2480t_Error err;24812482/* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,2483so no need for lock here */24842485memset(&grpParams, 0, sizeof(grpParams));2486grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;2487p_GrpParams = &grpParams;24882489p_GrpParams->netEnvId = netEnvId;24902491/* Get from the NetEnv the information of the clsPlan (can be already created,2492* or needs to build) */2493err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);2494if (err)2495RETURN_ERROR(MINOR,err,NO_MSG);24962497if (p_GrpParams->grpExists)2498{2499/* this group was already updated (at least) in SW */2500*p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;2501}2502else2503{2504p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));2505if (!p_ClsPlanSet)2506RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));2507memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));2508/* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */2509err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);2510if (err)2511{2512XX_Free(p_ClsPlanSet);2513RETURN_ERROR(MINOR, err, NO_MSG);2514}2515*p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;25162517if (p_FmPcd->h_Hc)2518{2519/* write clsPlan entries to memory */2520err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);2521if (err)2522{2523XX_Free(p_ClsPlanSet);2524RETURN_ERROR(MAJOR, err, NO_MSG);2525}2526}2527else2528/* write clsPlan entries to memory */2529KgSetClsPlan(p_FmPcd, p_ClsPlanSet);25302531XX_Free(p_ClsPlanSet);2532}25332534/* Set caller parameters */25352536/* mark if this is an empty classification group */2537if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)2538*p_IsEmptyClsPlanGrp = TRUE;2539else2540*p_IsEmptyClsPlanGrp = FALSE;25412542p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];25432544/* increment owners number */2545p_ClsPlanGrp->owners++;25462547/* copy options array for port */2548memcpy(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));25492550/* bind port to the new or existing group */2551err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);2552if (err)2553RETURN_ERROR(MINOR, err, NO_MSG);25542555return E_OK;2556}25572558t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)2559{2560t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;2561t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];2562t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;2563t_Error err;25642565/* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,2566so no need for lock here */25672568UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);25692570/* decrement owners number */2571ASSERT_COND(p_ClsPlanGrp->owners);2572p_ClsPlanGrp->owners--;25732574if (!p_ClsPlanGrp->owners)2575{2576if (p_FmPcd->h_Hc)2577{2578err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);2579return err;2580}2581else2582{2583/* clear clsPlan entries in memory */2584p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));2585if (!p_ClsPlanSet)2586{2587RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));2588}2589memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));25902591p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;2592p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;2593KgSetClsPlan(p_FmPcd, p_ClsPlanSet);2594XX_Free(p_ClsPlanSet);25952596FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);2597}2598}2599return E_OK;2600}26012602uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)2603{2604t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;2605ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);26062607return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;2608}26092610uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)2611{2612t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;26132614ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);26152616return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;2617}26182619bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)2620{2621t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;26222623ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);26242625return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;2626}262726282629uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)2630{2631t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;26322633ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);26342635return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;2636}26372638bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)2639{2640t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;26412642ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);26432644if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&2645p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||2646p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)2647return TRUE;2648else2649return FALSE;26502651}26522653e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)2654{2655t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;26562657ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);26582659return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;2660}26612662e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)2663{2664t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;26652666ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);26672668return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;2669}26702671void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)2672{2673t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;26742675/* this routine is protected by calling routine */26762677ASSERT_COND(p_Scheme->valid);26782679p_Scheme->requiredAction |= requiredAction;2680}26812682bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)2683{2684return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);2685}26862687uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)2688{2689return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |2690FM_KG_KGAR_GO |2691FM_KG_KGAR_WRITE |2692FM_KG_KGAR_SEL_SCHEME_ENTRY |2693DUMMY_PORT_ID |2694(updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));2695}26962697uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)2698{2699return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |2700FM_KG_KGAR_GO |2701FM_KG_KGAR_READ |2702FM_KG_KGAR_SEL_SCHEME_ENTRY |2703DUMMY_PORT_ID |2704FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);27052706}27072708uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)2709{2710return (uint32_t)(FM_KG_KGAR_GO |2711FM_KG_KGAR_WRITE |2712FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |2713DUMMY_PORT_ID |2714((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |2715FM_PCD_KG_KGAR_WSEL_MASK);27162717/* if we ever want to write 1 by 1, use:2718sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));2719*/2720}27212722uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)2723{27242725return (uint32_t)(FM_KG_KGAR_GO |2726FM_KG_KGAR_WRITE |2727FM_PCD_KG_KGAR_SEL_PORT_ENTRY |2728hardwarePortId |2729FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);2730}27312732uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)2733{27342735return (uint32_t)(FM_KG_KGAR_GO |2736FM_KG_KGAR_READ |2737FM_PCD_KG_KGAR_SEL_PORT_ENTRY |2738hardwarePortId |2739FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);2740}27412742uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)2743{27442745return (uint32_t)(FM_KG_KGAR_GO |2746FM_KG_KGAR_WRITE |2747FM_PCD_KG_KGAR_SEL_PORT_ENTRY |2748hardwarePortId |2749FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);2750}27512752uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)2753{2754t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;27552756return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;2757}27582759uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)2760{2761t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;27622763return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;2764}276527662767uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)2768{2769return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;27702771}27722773#if (DPAA_VERSION >= 11)2774bool FmPcdKgGetVspe(t_Handle h_Scheme)2775{2776return ((t_FmPcdKgScheme*)h_Scheme)->vspe;27772778}2779#endif /* (DPAA_VERSION >= 11) */27802781uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)2782{2783t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;2784uint8_t i;27852786for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)2787if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)2788return i;27892790if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)2791REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));27922793return FM_PCD_KG_NUM_OF_SCHEMES;2794}27952796t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)2797{2798t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;27992800ASSERT_COND(p_FmPcd);28012802/* check that schemeId is in range */2803if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)2804{2805REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));2806return NULL;2807}28082809if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))2810return NULL;28112812return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];2813}28142815bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)2816{2817return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;2818}28192820t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)2821{2822t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;2823uint8_t relativeSchemeId, physicalSchemeId;2824uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;2825t_Error err;2826t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;28272828SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);2829SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);2830SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);28312832/* Calling function locked all PCD modules, so no need to lock here */28332834if (!FmPcdKgIsSchemeValidSw(h_Scheme))2835RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));28362837if (p_FmPcd->h_Hc)2838{2839err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);28402841UpdateRequiredActionFlag(h_Scheme,TRUE);2842FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);2843return err;2844}28452846physicalSchemeId = p_Scheme->schemeId;28472848relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);2849if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)2850RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);28512852if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||2853!(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))2854{2855if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)2856{2857switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)2858{2859case (e_FM_PCD_DONE):2860if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)2861{2862tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);2863intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);2864WriteKgarWait(p_FmPcd, tmpKgarReg);2865tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);2866ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));2867WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);2868/* call indirect command for scheme write */2869tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);2870WriteKgarWait(p_FmPcd, tmpKgarReg);2871KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);2872}2873break;2874case (e_FM_PCD_PLCR):2875if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||2876(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&2877p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||2878p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)2879{2880RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));2881}2882err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);2883if (err)2884{2885RETURN_ERROR(MAJOR, err, NO_MSG);2886}2887break;2888default:2889RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));2890}2891}2892if (requiredAction & UPDATE_KG_NIA_CC_WA)2893{2894if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)2895{2896tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);2897intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);2898WriteKgarWait(p_FmPcd, tmpKgarReg);2899tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);2900ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));2901tmpReg32 &= ~NIA_FM_CTL_AC_CC;2902WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);2903/* call indirect command for scheme write */2904tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);2905WriteKgarWait(p_FmPcd, tmpKgarReg);2906KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);2907}2908}2909if (requiredAction & UPDATE_KG_OPT_MODE)2910{2911tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);2912intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);2913WriteKgarWait(p_FmPcd, tmpKgarReg);2914WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);2915/* call indirect command for scheme write */2916tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);2917WriteKgarWait(p_FmPcd, tmpKgarReg);2918KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);2919}2920if (requiredAction & UPDATE_KG_NIA)2921{2922tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);2923intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);2924WriteKgarWait(p_FmPcd, tmpKgarReg);2925tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);2926tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);2927tmpReg32 |= value;2928WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);2929/* call indirect command for scheme write */2930tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);2931WriteKgarWait(p_FmPcd, tmpKgarReg);2932KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);2933}2934}29352936UpdateRequiredActionFlag(h_Scheme, TRUE);2937FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);29382939return E_OK;2940}2941/*********************** End of inter-module routines ************************/294229432944/****************************************/2945/* API routines */2946/****************************************/29472948t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)2949{2950t_FmPcd *p_FmPcd;2951struct fman_kg_scheme_regs schemeRegs;2952struct fman_kg_scheme_regs *p_MemRegs;2953uint8_t i;2954t_Error err = E_OK;2955uint32_t tmpKgarReg;2956uint32_t intFlags;2957uint8_t physicalSchemeId, relativeSchemeId = 0;2958t_FmPcdKgScheme *p_Scheme;29592960if (p_SchemeParams->modify)2961{2962p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;2963p_FmPcd = p_Scheme->h_FmPcd;29642965SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);2966SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);29672968if (!FmPcdKgIsSchemeValidSw(p_Scheme))2969{2970REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,2971("Scheme is invalid"));2972return NULL;2973}29742975if (!KgSchemeFlagTryLock(p_Scheme))2976{2977DBG(TRACE, ("Scheme Try Lock - BUSY"));2978/* Signal to caller BUSY condition */2979p_SchemeParams->id.h_Scheme = NULL;2980return NULL;2981}2982}2983else2984{2985p_FmPcd = (t_FmPcd*)h_FmPcd;29862987SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);2988SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);29892990relativeSchemeId = p_SchemeParams->id.relativeSchemeId;2991/* check that schemeId is in range */2992if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)2993{2994REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));2995return NULL;2996}29972998p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];2999if (FmPcdKgIsSchemeValidSw(p_Scheme))3000{3001REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,3002("Scheme id (%d)!", relativeSchemeId));3003return NULL;3004}3005/* Clear all fields, scheme may have beed previously used */3006memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));30073008p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];3009p_Scheme->h_FmPcd = p_FmPcd;30103011p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);3012if (!p_Scheme->p_Lock)3013REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));3014}30153016err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);3017if (err)3018{3019REPORT_ERROR(MAJOR, err, NO_MSG);3020if (p_SchemeParams->modify)3021KgSchemeFlagUnlock(p_Scheme);3022if (!p_SchemeParams->modify &&3023p_Scheme->p_Lock)3024FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);3025return NULL;3026}30273028if (p_FmPcd->h_Hc)3029{3030err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,3031(t_Handle)p_Scheme,3032&schemeRegs,3033p_SchemeParams->schemeCounter.update);3034if (p_SchemeParams->modify)3035KgSchemeFlagUnlock(p_Scheme);3036if (err)3037{3038if (!p_SchemeParams->modify &&3039p_Scheme->p_Lock)3040FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);3041return NULL;3042}3043if (!p_SchemeParams->modify)3044ValidateSchemeSw(p_Scheme);3045return (t_Handle)p_Scheme;3046}30473048physicalSchemeId = p_Scheme->schemeId;30493050/* configure all 21 scheme registers */3051p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;3052intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);3053WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);3054WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);3055WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);3056WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);3057WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);3058WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);3059WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);3060WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);3061WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);3062WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);3063WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);3064WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);3065WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);3066WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);3067WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);3068for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)3069WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);30703071/* call indirect command for scheme write */3072tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);30733074WriteKgarWait(p_FmPcd, tmpKgarReg);3075KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);30763077if (!p_SchemeParams->modify)3078ValidateSchemeSw(p_Scheme);3079else3080KgSchemeFlagUnlock(p_Scheme);30813082return (t_Handle)p_Scheme;3083}30843085t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)3086{3087t_FmPcd *p_FmPcd;3088uint8_t physicalSchemeId;3089uint32_t tmpKgarReg, intFlags;3090t_Error err = E_OK;3091t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;30923093SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);30943095p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);30963097UpdateRequiredActionFlag(h_Scheme, FALSE);30983099/* check that no port is bound to this scheme */3100err = InvalidateSchemeSw(h_Scheme);3101if (err)3102RETURN_ERROR(MINOR, err, NO_MSG);31033104if (p_FmPcd->h_Hc)3105{3106err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);3107if (p_Scheme->p_Lock)3108FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);3109return err;3110}31113112physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;31133114intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);3115/* clear mode register, including enable bit */3116WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);31173118/* call indirect command for scheme write */3119tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);31203121WriteKgarWait(p_FmPcd, tmpKgarReg);3122KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);31233124if (p_Scheme->p_Lock)3125FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);31263127return E_OK;3128}31293130uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)3131{3132t_FmPcd *p_FmPcd;3133uint32_t tmpKgarReg, spc, intFlags;3134uint8_t physicalSchemeId;31353136SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);31373138p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);3139if (p_FmPcd->h_Hc)3140return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);31413142physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;31433144if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)3145REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);31463147tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);3148intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);3149WriteKgarWait(p_FmPcd, tmpKgarReg);3150if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))3151REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));3152spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);3153KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);31543155return spc;3156}31573158t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)3159{3160t_FmPcd *p_FmPcd;3161uint32_t tmpKgarReg, intFlags;3162uint8_t physicalSchemeId;31633164SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);31653166p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);31673168if (!FmPcdKgIsSchemeValidSw(h_Scheme))3169RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));31703171if (p_FmPcd->h_Hc)3172return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);31733174physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;3175/* check that schemeId is in range */3176if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)3177REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);31783179/* read specified scheme into scheme registers */3180tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);3181intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);3182WriteKgarWait(p_FmPcd, tmpKgarReg);3183if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))3184{3185KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);3186RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));3187}31883189/* change counter value */3190WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);31913192/* call indirect command for scheme write */3193tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);31943195WriteKgarWait(p_FmPcd, tmpKgarReg);3196KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);31973198return E_OK;3199}32003201t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)3202{3203t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;3204struct fman_kg_regs *p_Regs;32053206SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);3207SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);3208SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);3209SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);32103211p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;3212if (!FmIsMaster(p_FmPcd->h_Fm))3213RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));32143215WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);32163217return E_OK;3218}32193220t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)3221{3222t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;3223struct fman_kg_regs *p_Regs;32243225SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);3226SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);3227SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);3228SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);3229SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);32303231p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;32323233if (!FmIsMaster(p_FmPcd->h_Fm))3234RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));32353236if (valueId == 0)3237WRITE_UINT32(p_Regs->fmkg_gdv0r,value);3238else3239WRITE_UINT32(p_Regs->fmkg_gdv1r,value);3240return E_OK;3241}324232433244