1296177Sjhibbits/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. 2296177Sjhibbits * All rights reserved. 3296177Sjhibbits * 4296177Sjhibbits * Redistribution and use in source and binary forms, with or without 5296177Sjhibbits * modification, are permitted provided that the following conditions are met: 6296177Sjhibbits * * Redistributions of source code must retain the above copyright 7296177Sjhibbits * notice, this list of conditions and the following disclaimer. 8296177Sjhibbits * * Redistributions in binary form must reproduce the above copyright 9296177Sjhibbits * notice, this list of conditions and the following disclaimer in the 10296177Sjhibbits * documentation and/or other materials provided with the distribution. 11296177Sjhibbits * * Neither the name of Freescale Semiconductor nor the 12296177Sjhibbits * names of its contributors may be used to endorse or promote products 13296177Sjhibbits * derived from this software without specific prior written permission. 14296177Sjhibbits * 15296177Sjhibbits * 16296177Sjhibbits * ALTERNATIVELY, this software may be distributed under the terms of the 17296177Sjhibbits * GNU General Public License ("GPL") as published by the Free Software 18296177Sjhibbits * Foundation, either version 2 of that License or (at your option) any 19296177Sjhibbits * later version. 20296177Sjhibbits * 21296177Sjhibbits * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 22296177Sjhibbits * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23296177Sjhibbits * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24296177Sjhibbits * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 25296177Sjhibbits * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26296177Sjhibbits * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27296177Sjhibbits * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28296177Sjhibbits * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29296177Sjhibbits * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30296177Sjhibbits * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31296177Sjhibbits */ 32296177Sjhibbits 33296177Sjhibbits/****************************************************************************** 34296177Sjhibbits @File fm_kg.c 35296177Sjhibbits 36296177Sjhibbits @Description FM PCD ... 37296177Sjhibbits*//***************************************************************************/ 38296177Sjhibbits#include "std_ext.h" 39296177Sjhibbits#include "error_ext.h" 40296177Sjhibbits#include "string_ext.h" 41296177Sjhibbits#include "debug_ext.h" 42296177Sjhibbits#include "net_ext.h" 43296177Sjhibbits#include "fm_port_ext.h" 44296177Sjhibbits 45296177Sjhibbits#include "fm_common.h" 46296177Sjhibbits#include "fm_pcd.h" 47296177Sjhibbits#include "fm_hc.h" 48296177Sjhibbits 49296177Sjhibbits#include "fm_pcd_ipc.h" 50296177Sjhibbits 51296177Sjhibbits 52296177Sjhibbitsstatic t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t kgar) 53296177Sjhibbits{ 54296177Sjhibbits WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgar, kgar); 55296177Sjhibbits /* Wait for GO to be idle and read error */ 56296177Sjhibbits while ((kgar = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgar)) & FM_PCD_KG_KGAR_GO) ; 57296177Sjhibbits if (kgar & FM_PCD_KG_KGAR_ERR) 58296177Sjhibbits RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation")); 59296177Sjhibbits return E_OK; 60296177Sjhibbits} 61296177Sjhibbits 62296177Sjhibbitsstatic e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code) 63296177Sjhibbits{ 64296177Sjhibbits int i; 65296177Sjhibbits 66296177Sjhibbits switch(code) 67296177Sjhibbits { 68296177Sjhibbits case( KG_SCH_GEN_PARSE_RESULT_N_FQID): 69296177Sjhibbits case( KG_SCH_GEN_DEFAULT): 70296177Sjhibbits case( KG_SCH_GEN_NEXTHDR): 71296177Sjhibbits for(i=0 ; i<numOfSwDefaults ; i++) 72296177Sjhibbits if(swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA) 73296177Sjhibbits return swDefaults[i].dfltSelect; 74296177Sjhibbits ASSERT_COND(FALSE); 75296177Sjhibbits case( KG_SCH_GEN_SHIM1): 76296177Sjhibbits case( KG_SCH_GEN_SHIM2): 77296177Sjhibbits case( KG_SCH_GEN_IP_PID_NO_V): 78296177Sjhibbits case( KG_SCH_GEN_ETH_NO_V): 79296177Sjhibbits case( KG_SCH_GEN_SNAP_NO_V): 80296177Sjhibbits case( KG_SCH_GEN_VLAN1_NO_V): 81296177Sjhibbits case( KG_SCH_GEN_VLAN2_NO_V): 82296177Sjhibbits case( KG_SCH_GEN_ETH_TYPE_NO_V): 83296177Sjhibbits case( KG_SCH_GEN_PPP_NO_V): 84296177Sjhibbits case( KG_SCH_GEN_MPLS1_NO_V): 85296177Sjhibbits case( KG_SCH_GEN_MPLS_LAST_NO_V): 86296177Sjhibbits case( KG_SCH_GEN_L3_NO_V): 87296177Sjhibbits case( KG_SCH_GEN_IP2_NO_V): 88296177Sjhibbits case( KG_SCH_GEN_GRE_NO_V): 89296177Sjhibbits case( KG_SCH_GEN_L4_NO_V): 90296177Sjhibbits for(i=0 ; i<numOfSwDefaults ; i++) 91296177Sjhibbits if(swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V) 92296177Sjhibbits return swDefaults[i].dfltSelect; 93296177Sjhibbits 94296177Sjhibbits case( KG_SCH_GEN_START_OF_FRM): 95296177Sjhibbits case( KG_SCH_GEN_ETH): 96296177Sjhibbits case( KG_SCH_GEN_SNAP): 97296177Sjhibbits case( KG_SCH_GEN_VLAN1): 98296177Sjhibbits case( KG_SCH_GEN_VLAN2): 99296177Sjhibbits case( KG_SCH_GEN_ETH_TYPE): 100296177Sjhibbits case( KG_SCH_GEN_PPP): 101296177Sjhibbits case( KG_SCH_GEN_MPLS1): 102296177Sjhibbits case( KG_SCH_GEN_MPLS2): 103296177Sjhibbits case( KG_SCH_GEN_MPLS3): 104296177Sjhibbits case( KG_SCH_GEN_MPLS_LAST): 105296177Sjhibbits case( KG_SCH_GEN_IPV4): 106296177Sjhibbits case( KG_SCH_GEN_IPV6): 107296177Sjhibbits case( KG_SCH_GEN_IPV4_TUNNELED): 108296177Sjhibbits case( KG_SCH_GEN_IPV6_TUNNELED): 109296177Sjhibbits case( KG_SCH_GEN_MIN_ENCAP): 110296177Sjhibbits case( KG_SCH_GEN_GRE): 111296177Sjhibbits case( KG_SCH_GEN_TCP): 112296177Sjhibbits case( KG_SCH_GEN_UDP): 113296177Sjhibbits case( KG_SCH_GEN_IPSEC_AH): 114296177Sjhibbits case( KG_SCH_GEN_SCTP): 115296177Sjhibbits case( KG_SCH_GEN_DCCP): 116296177Sjhibbits case( KG_SCH_GEN_IPSEC_ESP): 117296177Sjhibbits for(i=0 ; i<numOfSwDefaults ; i++) 118296177Sjhibbits if(swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA) 119296177Sjhibbits return swDefaults[i].dfltSelect; 120296177Sjhibbits default: 121296177Sjhibbits return e_FM_PCD_KG_DFLT_ILLEGAL; 122296177Sjhibbits } 123296177Sjhibbits} 124296177Sjhibbits 125296177Sjhibbitsstatic uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset) 126296177Sjhibbits{ 127296177Sjhibbits *p_Offset = 0; 128296177Sjhibbits 129296177Sjhibbits switch(src) 130296177Sjhibbits { 131296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_FRAME_START): 132296177Sjhibbits return KG_SCH_GEN_START_OF_FRM; 133296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_DFLT_VALUE): 134296177Sjhibbits return KG_SCH_GEN_DEFAULT; 135296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_PARSE_RESULT): 136296177Sjhibbits return KG_SCH_GEN_PARSE_RESULT_N_FQID; 137296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_ENQ_FQID): 138296177Sjhibbits *p_Offset = 32; 139296177Sjhibbits return KG_SCH_GEN_PARSE_RESULT_N_FQID; 140296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE): 141296177Sjhibbits return KG_SCH_GEN_NEXTHDR; 142296177Sjhibbits default: 143296177Sjhibbits REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); 144296177Sjhibbits return 0; 145296177Sjhibbits } 146296177Sjhibbits} 147296177Sjhibbits 148296177Sjhibbitsstatic uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation) 149296177Sjhibbits{ 150296177Sjhibbits if(!ignoreProtocolValidation) 151296177Sjhibbits switch(hdr) 152296177Sjhibbits { 153296177Sjhibbits case(HEADER_TYPE_NONE): 154296177Sjhibbits ASSERT_COND(FALSE); 155296177Sjhibbits case(HEADER_TYPE_ETH): 156296177Sjhibbits return KG_SCH_GEN_ETH; 157296177Sjhibbits case(HEADER_TYPE_LLC_SNAP): 158296177Sjhibbits return KG_SCH_GEN_SNAP; 159296177Sjhibbits case(HEADER_TYPE_PPPoE): 160296177Sjhibbits return KG_SCH_GEN_PPP; 161296177Sjhibbits case(HEADER_TYPE_MPLS): 162296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 163296177Sjhibbits return KG_SCH_GEN_MPLS1; 164296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_2) 165296177Sjhibbits return KG_SCH_GEN_MPLS2; 166296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_3) 167296177Sjhibbits return KG_SCH_GEN_MPLS3; 168296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 169296177Sjhibbits return KG_SCH_GEN_MPLS_LAST; 170296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); 171296177Sjhibbits return 0; 172296177Sjhibbits case(HEADER_TYPE_IPv4): 173296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 174296177Sjhibbits return KG_SCH_GEN_IPV4; 175296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_2) 176296177Sjhibbits return KG_SCH_GEN_IPV4_TUNNELED; 177296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index")); 178296177Sjhibbits return 0; 179296177Sjhibbits case(HEADER_TYPE_IPv6): 180296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 181296177Sjhibbits return KG_SCH_GEN_IPV6; 182296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_2) 183296177Sjhibbits return KG_SCH_GEN_IPV6_TUNNELED; 184296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index")); 185296177Sjhibbits return 0; 186296177Sjhibbits case(HEADER_TYPE_GRE): 187296177Sjhibbits return KG_SCH_GEN_GRE; 188296177Sjhibbits case(HEADER_TYPE_TCP): 189296177Sjhibbits return KG_SCH_GEN_TCP; 190296177Sjhibbits case(HEADER_TYPE_UDP): 191296177Sjhibbits return KG_SCH_GEN_UDP; 192296177Sjhibbits case(HEADER_TYPE_IPSEC_AH): 193296177Sjhibbits return KG_SCH_GEN_IPSEC_AH; 194296177Sjhibbits case(HEADER_TYPE_IPSEC_ESP): 195296177Sjhibbits return KG_SCH_GEN_IPSEC_ESP; 196296177Sjhibbits case(HEADER_TYPE_SCTP): 197296177Sjhibbits return KG_SCH_GEN_SCTP; 198296177Sjhibbits case(HEADER_TYPE_DCCP): 199296177Sjhibbits return KG_SCH_GEN_DCCP; 200296177Sjhibbits default: 201296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 202296177Sjhibbits return 0; 203296177Sjhibbits } 204296177Sjhibbits else 205296177Sjhibbits switch(hdr) 206296177Sjhibbits { 207296177Sjhibbits case(HEADER_TYPE_NONE): 208296177Sjhibbits ASSERT_COND(FALSE); 209296177Sjhibbits case(HEADER_TYPE_ETH): 210296177Sjhibbits return KG_SCH_GEN_ETH_NO_V; 211296177Sjhibbits case(HEADER_TYPE_LLC_SNAP): 212296177Sjhibbits return KG_SCH_GEN_SNAP_NO_V; 213296177Sjhibbits case(HEADER_TYPE_PPPoE): 214296177Sjhibbits return KG_SCH_GEN_PPP_NO_V; 215296177Sjhibbits case(HEADER_TYPE_MPLS): 216296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 217296177Sjhibbits return KG_SCH_GEN_MPLS1_NO_V; 218296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 219296177Sjhibbits return KG_SCH_GEN_MPLS_LAST_NO_V; 220296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) ) 221296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported")); 222296177Sjhibbits else 223296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); 224296177Sjhibbits return 0; 225296177Sjhibbits case(HEADER_TYPE_IPv4): 226296177Sjhibbits case(HEADER_TYPE_IPv6): 227296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 228296177Sjhibbits return KG_SCH_GEN_L3_NO_V; 229296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_2) 230296177Sjhibbits return KG_SCH_GEN_IP2_NO_V; 231296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index")); 232296177Sjhibbits case(HEADER_TYPE_MINENCAP): 233296177Sjhibbits return KG_SCH_GEN_IP2_NO_V; 234296177Sjhibbits case(HEADER_TYPE_USER_DEFINED_L3): 235296177Sjhibbits return KG_SCH_GEN_L3_NO_V; 236296177Sjhibbits case(HEADER_TYPE_GRE): 237296177Sjhibbits return KG_SCH_GEN_GRE_NO_V; 238296177Sjhibbits case(HEADER_TYPE_TCP): 239296177Sjhibbits case(HEADER_TYPE_UDP): 240296177Sjhibbits case(HEADER_TYPE_IPSEC_AH): 241296177Sjhibbits case(HEADER_TYPE_IPSEC_ESP): 242296177Sjhibbits case(HEADER_TYPE_SCTP): 243296177Sjhibbits case(HEADER_TYPE_DCCP): 244296177Sjhibbits return KG_SCH_GEN_L4_NO_V; 245296177Sjhibbits case(HEADER_TYPE_USER_DEFINED_SHIM1): 246296177Sjhibbits return KG_SCH_GEN_SHIM1; 247296177Sjhibbits case(HEADER_TYPE_USER_DEFINED_SHIM2): 248296177Sjhibbits return KG_SCH_GEN_SHIM2; 249296177Sjhibbits default: 250296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 251296177Sjhibbits return 0; 252296177Sjhibbits } 253296177Sjhibbits} 254296177Sjhibbitsstatic t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex) 255296177Sjhibbits{ 256296177Sjhibbits if (!ignoreProtocolValidation) 257296177Sjhibbits switch(hdr) 258296177Sjhibbits { 259296177Sjhibbits case(HEADER_TYPE_NONE): 260296177Sjhibbits ASSERT_COND(FALSE); 261296177Sjhibbits case(HEADER_TYPE_ETH): 262296177Sjhibbits switch(field.eth) 263296177Sjhibbits { 264296177Sjhibbits case(NET_HEADER_FIELD_ETH_TYPE): 265296177Sjhibbits return KG_SCH_GEN_ETH_TYPE; 266296177Sjhibbits default: 267296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 268296177Sjhibbits return 0; 269296177Sjhibbits } 270296177Sjhibbits case(HEADER_TYPE_VLAN): 271296177Sjhibbits switch(field.vlan) 272296177Sjhibbits { 273296177Sjhibbits case(NET_HEADER_FIELD_VLAN_TCI): 274296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 275296177Sjhibbits return KG_SCH_GEN_VLAN1; 276296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 277296177Sjhibbits return KG_SCH_GEN_VLAN2; 278296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index")); 279296177Sjhibbits return 0; 280296177Sjhibbits } 281296177Sjhibbits case(HEADER_TYPE_MPLS): 282296177Sjhibbits case(HEADER_TYPE_IPSEC_AH): 283296177Sjhibbits case(HEADER_TYPE_IPSEC_ESP): 284296177Sjhibbits case(HEADER_TYPE_LLC_SNAP): 285296177Sjhibbits case(HEADER_TYPE_PPPoE): 286296177Sjhibbits case(HEADER_TYPE_IPv4): 287296177Sjhibbits case(HEADER_TYPE_IPv6): 288296177Sjhibbits case(HEADER_TYPE_GRE): 289296177Sjhibbits case(HEADER_TYPE_MINENCAP): 290296177Sjhibbits case(HEADER_TYPE_USER_DEFINED_L3): 291296177Sjhibbits case(HEADER_TYPE_TCP): 292296177Sjhibbits case(HEADER_TYPE_UDP): 293296177Sjhibbits case(HEADER_TYPE_SCTP): 294296177Sjhibbits case(HEADER_TYPE_DCCP): 295296177Sjhibbits case(HEADER_TYPE_USER_DEFINED_L4): 296296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 297296177Sjhibbits default: 298296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported")); 299296177Sjhibbits return 0; 300296177Sjhibbits } 301296177Sjhibbits else 302296177Sjhibbits switch(hdr) 303296177Sjhibbits { 304296177Sjhibbits case(HEADER_TYPE_NONE): 305296177Sjhibbits ASSERT_COND(FALSE); 306296177Sjhibbits case(HEADER_TYPE_ETH): 307296177Sjhibbits switch(field.eth) 308296177Sjhibbits { 309296177Sjhibbits case(NET_HEADER_FIELD_ETH_TYPE): 310296177Sjhibbits return KG_SCH_GEN_ETH_TYPE_NO_V; 311296177Sjhibbits default: 312296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 313296177Sjhibbits return 0; 314296177Sjhibbits } 315296177Sjhibbits case(HEADER_TYPE_VLAN): 316296177Sjhibbits switch(field.vlan) 317296177Sjhibbits { 318296177Sjhibbits case(NET_HEADER_FIELD_VLAN_TCI) : 319296177Sjhibbits if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) 320296177Sjhibbits return KG_SCH_GEN_VLAN1_NO_V; 321296177Sjhibbits if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST) 322296177Sjhibbits return KG_SCH_GEN_VLAN2_NO_V; 323296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index")); 324296177Sjhibbits return 0; 325296177Sjhibbits } 326296177Sjhibbits case(HEADER_TYPE_IPv4): 327296177Sjhibbits switch(field.ipv4) 328296177Sjhibbits { 329296177Sjhibbits case(NET_HEADER_FIELD_IPv4_PROTO): 330296177Sjhibbits return KG_SCH_GEN_IP_PID_NO_V; 331296177Sjhibbits default: 332296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 333296177Sjhibbits return 0; 334296177Sjhibbits } 335296177Sjhibbits case(HEADER_TYPE_IPv6): 336296177Sjhibbits switch(field.ipv6) 337296177Sjhibbits { 338296177Sjhibbits case(NET_HEADER_FIELD_IPv6_NEXT_HDR): 339296177Sjhibbits return KG_SCH_GEN_IP_PID_NO_V; 340296177Sjhibbits default: 341296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 342296177Sjhibbits return 0; 343296177Sjhibbits } 344296177Sjhibbits case(HEADER_TYPE_MPLS): 345296177Sjhibbits case(HEADER_TYPE_LLC_SNAP): 346296177Sjhibbits case(HEADER_TYPE_PPPoE): 347296177Sjhibbits case(HEADER_TYPE_GRE): 348296177Sjhibbits case(HEADER_TYPE_MINENCAP): 349296177Sjhibbits case(HEADER_TYPE_USER_DEFINED_L3): 350296177Sjhibbits case(HEADER_TYPE_TCP): 351296177Sjhibbits case(HEADER_TYPE_UDP): 352296177Sjhibbits case(HEADER_TYPE_IPSEC_AH): 353296177Sjhibbits case(HEADER_TYPE_IPSEC_ESP): 354296177Sjhibbits case(HEADER_TYPE_SCTP): 355296177Sjhibbits case(HEADER_TYPE_DCCP): 356296177Sjhibbits case(HEADER_TYPE_USER_DEFINED_L4): 357296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 358296177Sjhibbits return 0; 359296177Sjhibbits default: 360296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported")); 361296177Sjhibbits return 0; 362296177Sjhibbits } 363296177Sjhibbits} 364296177Sjhibbits 365296177Sjhibbitsstatic t_KnownFieldsMasks GetKnownProtMask(e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field) 366296177Sjhibbits{ 367296177Sjhibbits switch(hdr) 368296177Sjhibbits { 369296177Sjhibbits case(HEADER_TYPE_NONE): 370296177Sjhibbits ASSERT_COND(FALSE); 371296177Sjhibbits case(HEADER_TYPE_ETH): 372296177Sjhibbits switch(field.eth) 373296177Sjhibbits { 374296177Sjhibbits case(NET_HEADER_FIELD_ETH_DA): 375296177Sjhibbits return KG_SCH_KN_MACDST; 376296177Sjhibbits case(NET_HEADER_FIELD_ETH_SA): 377296177Sjhibbits return KG_SCH_KN_MACSRC; 378296177Sjhibbits case(NET_HEADER_FIELD_ETH_TYPE): 379296177Sjhibbits return KG_SCH_KN_ETYPE; 380296177Sjhibbits default: 381296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 382296177Sjhibbits return 0; 383296177Sjhibbits } 384296177Sjhibbits case(HEADER_TYPE_LLC_SNAP): 385296177Sjhibbits switch(field.llcSnap) 386296177Sjhibbits { 387296177Sjhibbits case(NET_HEADER_FIELD_LLC_SNAP_TYPE): 388296177Sjhibbits return KG_SCH_KN_ETYPE; 389296177Sjhibbits default: 390296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 391296177Sjhibbits return 0; 392296177Sjhibbits } 393296177Sjhibbits case(HEADER_TYPE_VLAN): 394296177Sjhibbits switch(field.vlan) 395296177Sjhibbits { 396296177Sjhibbits case(NET_HEADER_FIELD_VLAN_TCI): 397296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 398296177Sjhibbits return KG_SCH_KN_TCI1; 399296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_LAST) 400296177Sjhibbits return KG_SCH_KN_TCI2; 401296177Sjhibbits else 402296177Sjhibbits { 403296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 404296177Sjhibbits return 0; 405296177Sjhibbits } 406296177Sjhibbits default: 407296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 408296177Sjhibbits return 0; 409296177Sjhibbits } 410296177Sjhibbits case(HEADER_TYPE_MPLS): 411296177Sjhibbits switch(field.mpls) 412296177Sjhibbits { 413296177Sjhibbits case(NET_HEADER_FIELD_MPLS_LABEL_STACK): 414296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 415296177Sjhibbits return KG_SCH_KN_MPLS1; 416296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 417296177Sjhibbits return KG_SCH_KN_MPLS2; 418296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_LAST) 419296177Sjhibbits return KG_SCH_KN_MPLS_LAST; 420296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index")); 421296177Sjhibbits return 0; 422296177Sjhibbits default: 423296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 424296177Sjhibbits return 0; 425296177Sjhibbits } 426296177Sjhibbits case(HEADER_TYPE_IPv4): 427296177Sjhibbits switch(field.ipv4) 428296177Sjhibbits { 429296177Sjhibbits case(NET_HEADER_FIELD_IPv4_SRC_IP): 430296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 431296177Sjhibbits return KG_SCH_KN_IPSRC1; 432296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 433296177Sjhibbits return KG_SCH_KN_IPSRC2; 434296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 435296177Sjhibbits return 0; 436296177Sjhibbits case(NET_HEADER_FIELD_IPv4_DST_IP): 437296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 438296177Sjhibbits return KG_SCH_KN_IPDST1; 439296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 440296177Sjhibbits return KG_SCH_KN_IPDST2; 441296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 442296177Sjhibbits return 0; 443296177Sjhibbits case(NET_HEADER_FIELD_IPv4_PROTO): 444296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 445296177Sjhibbits return KG_SCH_KN_PTYPE1; 446296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 447296177Sjhibbits return KG_SCH_KN_PTYPE2; 448296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 449296177Sjhibbits return 0; 450296177Sjhibbits case(NET_HEADER_FIELD_IPv4_TOS): 451296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 452296177Sjhibbits return KG_SCH_KN_IPTOS_TC1; 453296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 454296177Sjhibbits return KG_SCH_KN_IPTOS_TC2; 455296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); 456296177Sjhibbits return 0; 457296177Sjhibbits default: 458296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 459296177Sjhibbits return 0; 460296177Sjhibbits } 461296177Sjhibbits case(HEADER_TYPE_IPv6): 462296177Sjhibbits switch(field.ipv6) 463296177Sjhibbits { 464296177Sjhibbits case(NET_HEADER_FIELD_IPv6_SRC_IP): 465296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 466296177Sjhibbits return KG_SCH_KN_IPSRC1; 467296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 468296177Sjhibbits return KG_SCH_KN_IPSRC2; 469296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 470296177Sjhibbits return 0; 471296177Sjhibbits case(NET_HEADER_FIELD_IPv6_DST_IP): 472296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 473296177Sjhibbits return KG_SCH_KN_IPDST1; 474296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 475296177Sjhibbits return KG_SCH_KN_IPDST2; 476296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 477296177Sjhibbits return 0; 478296177Sjhibbits case(NET_HEADER_FIELD_IPv6_NEXT_HDR): 479296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 480296177Sjhibbits return KG_SCH_KN_PTYPE1; 481296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 482296177Sjhibbits return KG_SCH_KN_PTYPE2; 483296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 484296177Sjhibbits return 0; 485296177Sjhibbits case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC): 486296177Sjhibbits if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) 487296177Sjhibbits return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1); 488296177Sjhibbits if(index == e_FM_PCD_HDR_INDEX_2) 489296177Sjhibbits return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2); 490296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); 491296177Sjhibbits return 0; 492296177Sjhibbits default: 493296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 494296177Sjhibbits return 0; 495296177Sjhibbits } 496296177Sjhibbits case(HEADER_TYPE_GRE): 497296177Sjhibbits switch(field.gre) 498296177Sjhibbits { 499296177Sjhibbits case(NET_HEADER_FIELD_GRE_TYPE): 500296177Sjhibbits return KG_SCH_KN_GREPTYPE; 501296177Sjhibbits default: 502296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 503296177Sjhibbits return 0; 504296177Sjhibbits } 505296177Sjhibbits case(HEADER_TYPE_MINENCAP): 506296177Sjhibbits switch(field.minencap) 507296177Sjhibbits { 508296177Sjhibbits case(NET_HEADER_FIELD_MINENCAP_SRC_IP): 509296177Sjhibbits return KG_SCH_KN_IPSRC2; 510296177Sjhibbits case(NET_HEADER_FIELD_MINENCAP_DST_IP): 511296177Sjhibbits return KG_SCH_KN_IPDST2; 512296177Sjhibbits case(NET_HEADER_FIELD_MINENCAP_TYPE): 513296177Sjhibbits return KG_SCH_KN_PTYPE2; 514296177Sjhibbits default: 515296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 516296177Sjhibbits return 0; 517296177Sjhibbits } 518296177Sjhibbits case(HEADER_TYPE_TCP): 519296177Sjhibbits switch(field.tcp) 520296177Sjhibbits { 521296177Sjhibbits case(NET_HEADER_FIELD_TCP_PORT_SRC): 522296177Sjhibbits return KG_SCH_KN_L4PSRC; 523296177Sjhibbits case(NET_HEADER_FIELD_TCP_PORT_DST): 524296177Sjhibbits return KG_SCH_KN_L4PDST; 525296177Sjhibbits case(NET_HEADER_FIELD_TCP_FLAGS): 526296177Sjhibbits return KG_SCH_KN_TFLG; 527296177Sjhibbits default: 528296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 529296177Sjhibbits return 0; 530296177Sjhibbits } 531296177Sjhibbits case(HEADER_TYPE_UDP): 532296177Sjhibbits switch(field.udp) 533296177Sjhibbits { 534296177Sjhibbits case(NET_HEADER_FIELD_UDP_PORT_SRC): 535296177Sjhibbits return KG_SCH_KN_L4PSRC; 536296177Sjhibbits case(NET_HEADER_FIELD_UDP_PORT_DST): 537296177Sjhibbits return KG_SCH_KN_L4PDST; 538296177Sjhibbits default: 539296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 540296177Sjhibbits return 0; 541296177Sjhibbits } 542296177Sjhibbits case(HEADER_TYPE_IPSEC_AH): 543296177Sjhibbits switch(field.ipsecAh) 544296177Sjhibbits { 545296177Sjhibbits case(NET_HEADER_FIELD_IPSEC_AH_SPI): 546296177Sjhibbits return KG_SCH_KN_IPSEC_SPI; 547296177Sjhibbits case(NET_HEADER_FIELD_IPSEC_AH_NH): 548296177Sjhibbits return KG_SCH_KN_IPSEC_NH; 549296177Sjhibbits default: 550296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 551296177Sjhibbits return 0; 552296177Sjhibbits } 553296177Sjhibbits case(HEADER_TYPE_IPSEC_ESP): 554296177Sjhibbits switch(field.ipsecEsp) 555296177Sjhibbits { 556296177Sjhibbits case(NET_HEADER_FIELD_IPSEC_ESP_SPI): 557296177Sjhibbits return KG_SCH_KN_IPSEC_SPI; 558296177Sjhibbits default: 559296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 560296177Sjhibbits return 0; 561296177Sjhibbits } 562296177Sjhibbits case(HEADER_TYPE_SCTP): 563296177Sjhibbits switch(field.sctp) 564296177Sjhibbits { 565296177Sjhibbits case(NET_HEADER_FIELD_SCTP_PORT_SRC): 566296177Sjhibbits return KG_SCH_KN_L4PSRC; 567296177Sjhibbits case(NET_HEADER_FIELD_SCTP_PORT_DST): 568296177Sjhibbits return KG_SCH_KN_L4PDST; 569296177Sjhibbits default: 570296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 571296177Sjhibbits return 0; 572296177Sjhibbits } 573296177Sjhibbits case(HEADER_TYPE_DCCP): 574296177Sjhibbits switch(field.dccp) 575296177Sjhibbits { 576296177Sjhibbits case(NET_HEADER_FIELD_DCCP_PORT_SRC): 577296177Sjhibbits return KG_SCH_KN_L4PSRC; 578296177Sjhibbits case(NET_HEADER_FIELD_DCCP_PORT_DST): 579296177Sjhibbits return KG_SCH_KN_L4PDST; 580296177Sjhibbits default: 581296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 582296177Sjhibbits return 0; 583296177Sjhibbits } 584296177Sjhibbits case(HEADER_TYPE_PPPoE): 585296177Sjhibbits switch(field.pppoe) 586296177Sjhibbits { 587296177Sjhibbits case(NET_HEADER_FIELD_PPPoE_PID): 588296177Sjhibbits return KG_SCH_KN_PPPID; 589296177Sjhibbits case(NET_HEADER_FIELD_PPPoE_SID): 590296177Sjhibbits return KG_SCH_KN_PPPSID; 591296177Sjhibbits default: 592296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 593296177Sjhibbits return 0; 594296177Sjhibbits } 595296177Sjhibbits default: 596296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); 597296177Sjhibbits return 0; 598296177Sjhibbits } 599296177Sjhibbits} 600296177Sjhibbits 601296177Sjhibbits 602296177Sjhibbitsstatic uint8_t GetKnownFieldId(uint32_t bitMask) 603296177Sjhibbits{ 604296177Sjhibbits uint8_t cnt = 0; 605296177Sjhibbits 606296177Sjhibbits while (bitMask) 607296177Sjhibbits if(bitMask & 0x80000000) 608296177Sjhibbits break; 609296177Sjhibbits else 610296177Sjhibbits { 611296177Sjhibbits cnt++; 612296177Sjhibbits bitMask <<= 1; 613296177Sjhibbits } 614296177Sjhibbits return cnt; 615296177Sjhibbits 616296177Sjhibbits} 617296177Sjhibbits 618296177Sjhibbitsstatic uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid) 619296177Sjhibbits{ 620296177Sjhibbits uint8_t i, mask, numOfOnesToClear, walking1Mask = 1; 621296177Sjhibbits 622296177Sjhibbits /* bitOffset 1-7 --> mask 0x1-0x7F */ 623296177Sjhibbits if(bitOffset<8) 624296177Sjhibbits { 625296177Sjhibbits mask = 0; 626296177Sjhibbits for(i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1) 627296177Sjhibbits mask |= walking1Mask; 628296177Sjhibbits } 629296177Sjhibbits else 630296177Sjhibbits { 631296177Sjhibbits mask = 0xFF; 632296177Sjhibbits numOfOnesToClear = 0; 633296177Sjhibbits if(fqid && bitOffset>24) 634296177Sjhibbits /* bitOffset 25-31 --> mask 0xFE-0x80 */ 635296177Sjhibbits numOfOnesToClear = (uint8_t)(bitOffset-24); 636296177Sjhibbits else 637296177Sjhibbits /* bitOffset 9-15 --> mask 0xFE-0x80 */ 638296177Sjhibbits if(!fqid && bitOffset>8) 639296177Sjhibbits numOfOnesToClear = (uint8_t)(bitOffset-8); 640296177Sjhibbits for(i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1) 641296177Sjhibbits mask &= ~walking1Mask; 642296177Sjhibbits /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/ 643296177Sjhibbits } 644296177Sjhibbits return mask; 645296177Sjhibbits} 646296177Sjhibbits 647296177Sjhibbits 648296177Sjhibbitst_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet) 649296177Sjhibbits{ 650296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 651296177Sjhibbits t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; 652296177Sjhibbits t_FmPcdIpcKgClsPlanParams kgAlloc; 653296177Sjhibbits t_Error err = E_OK; 654296177Sjhibbits uint32_t oredVectors = 0; 655296177Sjhibbits uint32_t intFlags; 656296177Sjhibbits int i, j; 657296177Sjhibbits 658296177Sjhibbits if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)) 659296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected.")); 660296177Sjhibbits 661296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 662296177Sjhibbits 663296177Sjhibbits /* find a new clsPlan group */ 664296177Sjhibbits for(i = 0;i<FM_MAX_NUM_OF_PORTS;i++) 665296177Sjhibbits if(!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used) 666296177Sjhibbits break; 667296177Sjhibbits if(i== FM_MAX_NUM_OF_PORTS) 668296177Sjhibbits { 669296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 670296177Sjhibbits RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available.")); 671296177Sjhibbits } 672296177Sjhibbits p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE; 673296177Sjhibbits p_Grp->clsPlanGrpId = (uint8_t)i; 674296177Sjhibbits 675296177Sjhibbits if(p_Grp->numOfOptions == 0) 676296177Sjhibbits p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i; 677296177Sjhibbits 678296177Sjhibbits if (!TRY_LOCK(NULL, &p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock)) 679296177Sjhibbits { 680296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 681296177Sjhibbits return ERROR_CODE(E_BUSY); 682296177Sjhibbits } 683296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 684296177Sjhibbits 685296177Sjhibbits p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i]; 686296177Sjhibbits p_ClsPlanGrp->netEnvId = p_Grp->netEnvId; 687296177Sjhibbits p_ClsPlanGrp->owners = 0; 688296177Sjhibbits FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId); 689296177Sjhibbits FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId); 690296177Sjhibbits 691296177Sjhibbits p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1<<p_Grp->numOfOptions); 692296177Sjhibbits /* a minimal group of 8 is required */ 693296177Sjhibbits if(p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP) 694296177Sjhibbits p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP; 695296177Sjhibbits if(p_FmPcd->guestId == NCSW_MASTER_ID) 696296177Sjhibbits { 697296177Sjhibbits err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry); 698296177Sjhibbits 699296177Sjhibbits if(err) 700296177Sjhibbits { 701296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); 702296177Sjhibbits RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); 703296177Sjhibbits } 704296177Sjhibbits 705296177Sjhibbits } 706296177Sjhibbits else 707296177Sjhibbits { 708296177Sjhibbits t_FmPcdIpcMsg msg; 709296177Sjhibbits uint32_t replyLength; 710296177Sjhibbits t_FmPcdIpcReply reply; 711296177Sjhibbits 712296177Sjhibbits /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ 713296177Sjhibbits memset(&reply, 0, sizeof(reply)); 714296177Sjhibbits memset(&msg, 0, sizeof(msg)); 715296177Sjhibbits memset(&kgAlloc, 0, sizeof(kgAlloc)); 716296177Sjhibbits kgAlloc.guestId = p_FmPcd->guestId; 717296177Sjhibbits kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; 718296177Sjhibbits msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN; 719296177Sjhibbits memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 720296177Sjhibbits replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)); 721296177Sjhibbits if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 722296177Sjhibbits (uint8_t*)&msg, 723296177Sjhibbits sizeof(msg.msgId) + sizeof(kgAlloc), 724296177Sjhibbits (uint8_t*)&reply, 725296177Sjhibbits &replyLength, 726296177Sjhibbits NULL, 727296177Sjhibbits NULL)) != E_OK) 728296177Sjhibbits { 729296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); 730296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 731296177Sjhibbits } 732296177Sjhibbits 733296177Sjhibbits if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry))) 734296177Sjhibbits { 735296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); 736296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 737296177Sjhibbits } 738296177Sjhibbits if ((t_Error)reply.error != E_OK) 739296177Sjhibbits { 740296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); 741296177Sjhibbits RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG); 742296177Sjhibbits } 743296177Sjhibbits 744296177Sjhibbits p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody); 745296177Sjhibbits } 746296177Sjhibbits 747296177Sjhibbits /* build classification plan entries parameters */ 748296177Sjhibbits p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry; 749296177Sjhibbits p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; 750296177Sjhibbits 751296177Sjhibbits oredVectors = 0; 752296177Sjhibbits for(i = 0; i<p_Grp->numOfOptions; i++) 753296177Sjhibbits { 754296177Sjhibbits oredVectors |= p_Grp->optVectors[i]; 755296177Sjhibbits /* save an array of used options - the indexes represent the power of 2 index */ 756296177Sjhibbits p_ClsPlanGrp->optArray[i] = p_Grp->options[i]; 757296177Sjhibbits } 758296177Sjhibbits /* set the classification plan relevant entries so that all bits 759296177Sjhibbits * relevant to the list of options is cleared 760296177Sjhibbits */ 761296177Sjhibbits for(j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++) 762296177Sjhibbits p_ClsPlanSet->vectors[j] = ~oredVectors; 763296177Sjhibbits 764296177Sjhibbits for(i = 0; i<p_Grp->numOfOptions; i++) 765296177Sjhibbits { 766296177Sjhibbits /* option i got the place 2^i in the clsPlan array. all entries that 767296177Sjhibbits * have bit i set, should have the vector bit cleared. So each option 768296177Sjhibbits * has one location that it is exclusive (1,2,4,8...) and represent the 769296177Sjhibbits * presence of that option only, and other locations that represent a 770296177Sjhibbits * combination of options. 771296177Sjhibbits * e.g: 772296177Sjhibbits * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2 773296177Sjhibbits * now represents a frame with ethernet-BC header - so the bit 774296177Sjhibbits * representing ethernet-BC should be set and all other option bits 775296177Sjhibbits * should be cleared. 776296177Sjhibbits * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit 777296177Sjhibbits * vector[1] set, but they also have other bits set: 778296177Sjhibbits * 3=1+2, options 0 and 1 779296177Sjhibbits * 6=2+4, options 1 and 2 780296177Sjhibbits * 7=1+2+4, options 0,1,and 2 781296177Sjhibbits * 10=2+8, options 1 and 3 782296177Sjhibbits * etc. 783296177Sjhibbits * */ 784296177Sjhibbits 785296177Sjhibbits /* now for each option (i), we set their bits in all entries (j) 786296177Sjhibbits * that contain bit 2^i. 787296177Sjhibbits */ 788296177Sjhibbits for(j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++) 789296177Sjhibbits { 790296177Sjhibbits if(j & (1<<i)) 791296177Sjhibbits p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i]; 792296177Sjhibbits } 793296177Sjhibbits } 794296177Sjhibbits 795296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock); 796296177Sjhibbits 797296177Sjhibbits return E_OK; 798296177Sjhibbits} 799296177Sjhibbits 800296177Sjhibbitsvoid FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId) 801296177Sjhibbits{ 802296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 803296177Sjhibbits t_FmPcdIpcKgClsPlanParams kgAlloc; 804296177Sjhibbits t_Error err; 805296177Sjhibbits t_FmPcdIpcMsg msg; 806296177Sjhibbits uint32_t replyLength; 807296177Sjhibbits t_FmPcdIpcReply reply; 808296177Sjhibbits 809296177Sjhibbits /* check that no port is bound to this clsPlan */ 810296177Sjhibbits if(p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners) 811296177Sjhibbits { 812296177Sjhibbits REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to")); 813296177Sjhibbits return; 814296177Sjhibbits } 815296177Sjhibbits 816296177Sjhibbits FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId); 817296177Sjhibbits 818296177Sjhibbits /* free blocks */ 819296177Sjhibbits if(p_FmPcd->guestId == NCSW_MASTER_ID) 820296177Sjhibbits { 821296177Sjhibbits KgFreeClsPlanEntries(h_FmPcd, 822296177Sjhibbits p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp, 823296177Sjhibbits p_FmPcd->guestId, 824296177Sjhibbits p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry); 825296177Sjhibbits } 826296177Sjhibbits else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ 827296177Sjhibbits { 828296177Sjhibbits memset(&reply, 0, sizeof(reply)); 829296177Sjhibbits memset(&msg, 0, sizeof(msg)); 830296177Sjhibbits kgAlloc.guestId = p_FmPcd->guestId; 831296177Sjhibbits kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp; 832296177Sjhibbits kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry; 833296177Sjhibbits msg.msgId = FM_PCD_FREE_KG_CLSPLAN; 834296177Sjhibbits memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 835296177Sjhibbits replyLength = sizeof(uint32_t); 836296177Sjhibbits if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 837296177Sjhibbits (uint8_t*)&msg, 838296177Sjhibbits sizeof(msg.msgId) + sizeof(kgAlloc), 839296177Sjhibbits (uint8_t*)&reply, 840296177Sjhibbits &replyLength, 841296177Sjhibbits NULL, 842296177Sjhibbits NULL)) != E_OK) 843296177Sjhibbits { 844296177Sjhibbits REPORT_ERROR(MINOR, err, NO_MSG); 845296177Sjhibbits return; 846296177Sjhibbits } 847296177Sjhibbits if (replyLength != sizeof(uint32_t)) 848296177Sjhibbits { 849296177Sjhibbits REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 850296177Sjhibbits return; 851296177Sjhibbits } 852296177Sjhibbits if((t_Error)reply.error != E_OK) 853296177Sjhibbits { 854296177Sjhibbits REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed")); 855296177Sjhibbits return; 856296177Sjhibbits } 857296177Sjhibbits } 858296177Sjhibbits 859296177Sjhibbits if(grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) 860296177Sjhibbits p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; 861296177Sjhibbits /* clear clsPlan driver structure */ 862296177Sjhibbits memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp)); 863296177Sjhibbits} 864296177Sjhibbits 865296177Sjhibbitst_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add) 866296177Sjhibbits{ 867296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 868296177Sjhibbits uint32_t j, schemesPerPortVector = 0; 869296177Sjhibbits t_FmPcdKgScheme *p_Scheme; 870296177Sjhibbits uint8_t i, relativeSchemeId; 871296177Sjhibbits uint32_t tmp, walking1Mask; 872296177Sjhibbits uint8_t swPortIndex = 0; 873296177Sjhibbits 874296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 875296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 876296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 877296177Sjhibbits 878296177Sjhibbits /* for each scheme */ 879296177Sjhibbits for(i = 0; i<p_BindPort->numOfSchemes; i++) 880296177Sjhibbits { 881296177Sjhibbits relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); 882296177Sjhibbits if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 883296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 884296177Sjhibbits 885296177Sjhibbits if(add) 886296177Sjhibbits { 887296177Sjhibbits if (!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId)) 888296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); 889296177Sjhibbits 890296177Sjhibbits p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; 891296177Sjhibbits /* check netEnvId of the port against the scheme netEnvId */ 892296177Sjhibbits if((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV)) 893296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId")); 894296177Sjhibbits 895296177Sjhibbits /* if next engine is private port policer profile, we need to check that it is valid */ 896296177Sjhibbits HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId); 897296177Sjhibbits if(p_Scheme->nextRelativePlcrProfile) 898296177Sjhibbits { 899296177Sjhibbits for(j = 0;j<p_Scheme->numOfProfiles;j++) 900296177Sjhibbits { 901296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort); 902296177Sjhibbits if(p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles) 903296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range")); 904296177Sjhibbits if(!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j))) 905296177Sjhibbits RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid.")); 906296177Sjhibbits } 907296177Sjhibbits } 908296177Sjhibbits if(!p_BindPort->useClsPlan) 909296177Sjhibbits { 910296177Sjhibbits /* if this port does not use clsPlan, it may not be bound to schemes with units that contain 911296177Sjhibbits cls plan options. Schemes that are used only directly, should not be checked. 912296177Sjhibbits it also may not be bound to schemes that go to CC with units that are options - so we OR 913296177Sjhibbits the match vector and the grpBits (= ccUnits) */ 914296177Sjhibbits if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits) 915296177Sjhibbits { 916296177Sjhibbits walking1Mask = 0x80000000; 917296177Sjhibbits tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector; 918296177Sjhibbits tmp |= p_Scheme->ccUnits; 919296177Sjhibbits while (tmp) 920296177Sjhibbits { 921296177Sjhibbits if(tmp & walking1Mask) 922296177Sjhibbits { 923296177Sjhibbits tmp &= ~walking1Mask; 924296177Sjhibbits if(!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, p_Scheme->netEnvId, walking1Mask)) 925296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options")); 926296177Sjhibbits } 927296177Sjhibbits walking1Mask >>= 1; 928296177Sjhibbits } 929296177Sjhibbits } 930296177Sjhibbits } 931296177Sjhibbits } 932296177Sjhibbits /* build vector */ 933296177Sjhibbits schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]); 934296177Sjhibbits } 935296177Sjhibbits 936296177Sjhibbits *p_SpReg = schemesPerPortVector; 937296177Sjhibbits 938296177Sjhibbits return E_OK; 939296177Sjhibbits} 940296177Sjhibbits 941296177Sjhibbitsvoid FmPcdKgIncSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) 942296177Sjhibbits{ 943296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 944296177Sjhibbits int i; 945296177Sjhibbits t_FmPcdKgScheme *p_Scheme; 946296177Sjhibbits 947296177Sjhibbits /* for each scheme - update owners counters */ 948296177Sjhibbits for(i = 0; i<p_BindPort->numOfSchemes; i++) 949296177Sjhibbits { 950296177Sjhibbits p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[p_BindPort->schemesIds[i]]; 951296177Sjhibbits 952296177Sjhibbits /* increment owners number */ 953296177Sjhibbits p_Scheme->owners++; 954296177Sjhibbits } 955296177Sjhibbits} 956296177Sjhibbits 957296177Sjhibbitsvoid FmPcdKgDecSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) 958296177Sjhibbits{ 959296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 960296177Sjhibbits int i; 961296177Sjhibbits t_FmPcdKgScheme *p_Scheme; 962296177Sjhibbits 963296177Sjhibbits /* for each scheme - update owners counters */ 964296177Sjhibbits for(i = 0; i<p_BindPort->numOfSchemes; i++) 965296177Sjhibbits { 966296177Sjhibbits p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[p_BindPort->schemesIds[i]]; 967296177Sjhibbits 968296177Sjhibbits /* increment owners number */ 969296177Sjhibbits ASSERT_COND(p_Scheme->owners); 970296177Sjhibbits p_Scheme->owners--; 971296177Sjhibbits } 972296177Sjhibbits} 973296177Sjhibbits 974296177Sjhibbitsstatic t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add) 975296177Sjhibbits{ 976296177Sjhibbits t_FmPcdKgPortConfigRegs *p_FmPcdKgPortRegs; 977296177Sjhibbits uint32_t tmpKgarReg = 0, tmpKgpeSp, intFlags; 978296177Sjhibbits t_Error err = E_OK; 979296177Sjhibbits 980296177Sjhibbits if (p_FmPcd->h_Hc) 981296177Sjhibbits return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add); 982296177Sjhibbits 983296177Sjhibbits p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs; 984296177Sjhibbits 985296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId); 986296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 987296177Sjhibbits err = WriteKgarWait(p_FmPcd, tmpKgarReg); 988296177Sjhibbits if(err) 989296177Sjhibbits { 990296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 991296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 992296177Sjhibbits } 993296177Sjhibbits 994296177Sjhibbits tmpKgpeSp = GET_UINT32(p_FmPcdKgPortRegs->kgoe_sp); 995296177Sjhibbits 996296177Sjhibbits if(add) 997296177Sjhibbits tmpKgpeSp |= spReg; 998296177Sjhibbits else /* clear */ 999296177Sjhibbits tmpKgpeSp &= ~spReg; 1000296177Sjhibbits 1001296177Sjhibbits WRITE_UINT32(p_FmPcdKgPortRegs->kgoe_sp, tmpKgpeSp); 1002296177Sjhibbits 1003296177Sjhibbits tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId); 1004296177Sjhibbits 1005296177Sjhibbits err = WriteKgarWait(p_FmPcd, tmpKgarReg); 1006296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1007296177Sjhibbits return err; 1008296177Sjhibbits} 1009296177Sjhibbits 1010296177Sjhibbitsstatic t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg) 1011296177Sjhibbits{ 1012296177Sjhibbits t_FmPcdKgPortConfigRegs *p_FmPcdKgPortRegs; 1013296177Sjhibbits uint32_t tmpKgarReg, intFlags; 1014296177Sjhibbits t_Error err; 1015296177Sjhibbits 1016296177Sjhibbits if (p_FmPcd->h_Hc) 1017296177Sjhibbits return FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg); 1018296177Sjhibbits 1019296177Sjhibbits p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs; 1020296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 1021296177Sjhibbits WRITE_UINT32(p_FmPcdKgPortRegs->kgoe_cpp, cppReg); 1022296177Sjhibbits 1023296177Sjhibbits tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId); 1024296177Sjhibbits err = WriteKgarWait(p_FmPcd, tmpKgarReg); 1025296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1026296177Sjhibbits 1027296177Sjhibbits return err; 1028296177Sjhibbits} 1029296177Sjhibbits 1030296177Sjhibbitsstatic void FmPcdKgUnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId) 1031296177Sjhibbits{ 1032296177Sjhibbits KgWriteCpp(p_FmPcd, hardwarePortId, 0); 1033296177Sjhibbits} 1034296177Sjhibbits 1035296177Sjhibbitsstatic t_Error KgBindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) 1036296177Sjhibbits{ 1037296177Sjhibbits uint32_t tmpKgpeCpp = 0; 1038296177Sjhibbits 1039296177Sjhibbits tmpKgpeCpp = FmPcdKgBuildCppReg(p_FmPcd, clsPlanGrpId); 1040296177Sjhibbits return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp); 1041296177Sjhibbits} 1042296177Sjhibbits 1043296177Sjhibbitst_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) 1044296177Sjhibbits{ 1045296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1046296177Sjhibbits uint32_t spReg; 1047296177Sjhibbits t_Error err = E_OK; 1048296177Sjhibbits 1049296177Sjhibbits err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE); 1050296177Sjhibbits if(err) 1051296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1052296177Sjhibbits 1053296177Sjhibbits err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE); 1054296177Sjhibbits if(err) 1055296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1056296177Sjhibbits 1057296177Sjhibbits FmPcdKgIncSchemeOwners(h_FmPcd, p_SchemeBind); 1058296177Sjhibbits 1059296177Sjhibbits return E_OK; 1060296177Sjhibbits} 1061296177Sjhibbits 1062296177Sjhibbitst_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) 1063296177Sjhibbits{ 1064296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1065296177Sjhibbits uint32_t spReg; 1066296177Sjhibbits t_Error err = E_OK; 1067296177Sjhibbits 1068296177Sjhibbits err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, FALSE); 1069296177Sjhibbits if(err) 1070296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1071296177Sjhibbits 1072296177Sjhibbits err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE); 1073296177Sjhibbits if(err) 1074296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1075296177Sjhibbits 1076296177Sjhibbits FmPcdKgDecSchemeOwners(h_FmPcd, p_SchemeBind); 1077296177Sjhibbits 1078296177Sjhibbits return E_OK; 1079296177Sjhibbits} 1080296177Sjhibbits 1081296177Sjhibbitsbool FmPcdKgIsSchemeValidSw(t_Handle h_FmPcd, uint8_t schemeId) 1082296177Sjhibbits{ 1083296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1084296177Sjhibbits 1085296177Sjhibbits return p_FmPcd->p_FmPcdKg->schemes[schemeId].valid; 1086296177Sjhibbits} 1087296177Sjhibbits 1088296177Sjhibbitsbool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId) 1089296177Sjhibbits{ 1090296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1091296177Sjhibbits 1092296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT) 1093296177Sjhibbits return TRUE; 1094296177Sjhibbits else 1095296177Sjhibbits return FALSE; 1096296177Sjhibbits} 1097296177Sjhibbits 1098296177Sjhibbitst_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) 1099296177Sjhibbits{ 1100296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1101296177Sjhibbits uint32_t intFlags; 1102296177Sjhibbits uint8_t i,j; 1103296177Sjhibbits 1104296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1105296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 1106296177Sjhibbits 1107296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 1108296177Sjhibbits for(j=0,i=0;i<FM_PCD_KG_NUM_OF_SCHEMES && j<numOfSchemes;i++) 1109296177Sjhibbits { 1110296177Sjhibbits if(!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated) 1111296177Sjhibbits { 1112296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE; 1113296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId; 1114296177Sjhibbits p_SchemesIds[j] = i; 1115296177Sjhibbits j++; 1116296177Sjhibbits } 1117296177Sjhibbits } 1118296177Sjhibbits 1119296177Sjhibbits if (j != numOfSchemes) 1120296177Sjhibbits { 1121296177Sjhibbits /* roll back */ 1122296177Sjhibbits for(j--; j; j--) 1123296177Sjhibbits { 1124296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE; 1125296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0; 1126296177Sjhibbits p_SchemesIds[j] = 0; 1127296177Sjhibbits } 1128296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1129296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found")); 1130296177Sjhibbits } 1131296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1132296177Sjhibbits 1133296177Sjhibbits return E_OK; 1134296177Sjhibbits} 1135296177Sjhibbits 1136296177Sjhibbitst_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) 1137296177Sjhibbits{ 1138296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1139296177Sjhibbits uint32_t intFlags; 1140296177Sjhibbits uint8_t i; 1141296177Sjhibbits 1142296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1143296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 1144296177Sjhibbits 1145296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 1146296177Sjhibbits 1147296177Sjhibbits for(i=0;i<numOfSchemes;i++) 1148296177Sjhibbits { 1149296177Sjhibbits if(!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated) 1150296177Sjhibbits { 1151296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1152296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated")); 1153296177Sjhibbits } 1154296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId) 1155296177Sjhibbits { 1156296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1157296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. ")); 1158296177Sjhibbits } 1159296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE; 1160296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0; 1161296177Sjhibbits } 1162296177Sjhibbits 1163296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1164296177Sjhibbits return E_OK; 1165296177Sjhibbits} 1166296177Sjhibbits 1167296177Sjhibbitst_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First) 1168296177Sjhibbits{ 1169296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1170296177Sjhibbits uint32_t intFlags; 1171296177Sjhibbits uint8_t numOfBlocks, blocksFound=0, first=0; 1172296177Sjhibbits uint8_t i, j; 1173296177Sjhibbits 1174296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 1175296177Sjhibbits 1176296177Sjhibbits if(!numOfClsPlanEntries) 1177296177Sjhibbits { 1178296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1179296177Sjhibbits return E_OK; 1180296177Sjhibbits } 1181296177Sjhibbits 1182296177Sjhibbits if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries))) 1183296177Sjhibbits { 1184296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1185296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8")); 1186296177Sjhibbits } 1187296177Sjhibbits 1188296177Sjhibbits numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); 1189296177Sjhibbits 1190296177Sjhibbits /* try to find consequent blocks */ 1191296177Sjhibbits first = 0; 1192296177Sjhibbits for(i=0;i<FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;) 1193296177Sjhibbits { 1194296177Sjhibbits if(!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated) 1195296177Sjhibbits { 1196296177Sjhibbits blocksFound++; 1197296177Sjhibbits i++; 1198296177Sjhibbits if(blocksFound == numOfBlocks) 1199296177Sjhibbits break; 1200296177Sjhibbits } 1201296177Sjhibbits else 1202296177Sjhibbits { 1203296177Sjhibbits blocksFound = 0; 1204296177Sjhibbits /* advance i to the next aligned address */ 1205296177Sjhibbits first = i = (uint8_t)(first + numOfBlocks); 1206296177Sjhibbits } 1207296177Sjhibbits } 1208296177Sjhibbits 1209296177Sjhibbits if(blocksFound == numOfBlocks) 1210296177Sjhibbits { 1211296177Sjhibbits *p_First = (uint8_t)(first*CLS_PLAN_NUM_PER_GRP); 1212296177Sjhibbits for(j = first; j<first + numOfBlocks; j++) 1213296177Sjhibbits { 1214296177Sjhibbits p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE; 1215296177Sjhibbits p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId; 1216296177Sjhibbits } 1217296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1218296177Sjhibbits 1219296177Sjhibbits return E_OK; 1220296177Sjhibbits } 1221296177Sjhibbits else 1222296177Sjhibbits { 1223296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1224296177Sjhibbits RETURN_ERROR(MINOR, E_FULL, ("No recources for clsPlan")); 1225296177Sjhibbits } 1226296177Sjhibbits} 1227296177Sjhibbits 1228296177Sjhibbitsvoid KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base) 1229296177Sjhibbits{ 1230296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1231296177Sjhibbits uint32_t intFlags; 1232296177Sjhibbits uint8_t numOfBlocks; 1233296177Sjhibbits uint8_t i, baseBlock; 1234296177Sjhibbits 1235296177Sjhibbits UNUSED( guestId); 1236296177Sjhibbits 1237296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 1238296177Sjhibbits 1239296177Sjhibbits numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); 1240296177Sjhibbits ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP)); 1241296177Sjhibbits 1242296177Sjhibbits baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP); 1243296177Sjhibbits for(i=baseBlock;i<baseBlock+numOfBlocks;i++) 1244296177Sjhibbits { 1245296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated); 1246296177Sjhibbits ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId); 1247296177Sjhibbits p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE; 1248296177Sjhibbits p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0; 1249296177Sjhibbits } 1250296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1251296177Sjhibbits} 1252296177Sjhibbits 1253296177Sjhibbitsvoid KgEnable(t_FmPcd *p_FmPcd) 1254296177Sjhibbits{ 1255296177Sjhibbits t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 1256296177Sjhibbits 1257296177Sjhibbits ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 1258296177Sjhibbits WRITE_UINT32(p_Regs->kggcr,GET_UINT32(p_Regs->kggcr) | FM_PCD_KG_KGGCR_EN); 1259296177Sjhibbits} 1260296177Sjhibbits 1261296177Sjhibbitsvoid KgDisable(t_FmPcd *p_FmPcd) 1262296177Sjhibbits{ 1263296177Sjhibbits t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 1264296177Sjhibbits 1265296177Sjhibbits ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 1266296177Sjhibbits WRITE_UINT32(p_Regs->kggcr,GET_UINT32(p_Regs->kggcr) & ~FM_PCD_KG_KGGCR_EN); 1267296177Sjhibbits} 1268296177Sjhibbits 1269296177Sjhibbitsvoid KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set) 1270296177Sjhibbits{ 1271296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1272296177Sjhibbits t_FmPcdKgClsPlanRegs *p_FmPcdKgPortRegs; 1273296177Sjhibbits uint32_t tmpKgarReg=0, intFlags; 1274296177Sjhibbits uint16_t i, j; 1275296177Sjhibbits 1276296177Sjhibbits SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); 1277296177Sjhibbits SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 1278296177Sjhibbits 1279296177Sjhibbits ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 1280296177Sjhibbits p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs; 1281296177Sjhibbits 1282296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 1283296177Sjhibbits for(i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8) 1284296177Sjhibbits { 1285296177Sjhibbits tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); 1286296177Sjhibbits 1287296177Sjhibbits for (j = i; j < i+8; j++) 1288296177Sjhibbits { 1289296177Sjhibbits ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1)); 1290296177Sjhibbits WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]); 1291296177Sjhibbits } 1292296177Sjhibbits 1293296177Sjhibbits if(WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK) 1294296177Sjhibbits { 1295296177Sjhibbits REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED")); 1296296177Sjhibbits return; 1297296177Sjhibbits } 1298296177Sjhibbits } 1299296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1300296177Sjhibbits} 1301296177Sjhibbits 1302296177Sjhibbitsstatic void PcdKgErrorException(t_Handle h_FmPcd) 1303296177Sjhibbits{ 1304296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1305296177Sjhibbits uint32_t event, force, schemeIndexes = 0,index = 0, mask = 0; 1306296177Sjhibbits 1307296177Sjhibbits ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); 1308296177Sjhibbits event = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeer); 1309296177Sjhibbits mask = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer); 1310296177Sjhibbits 1311296177Sjhibbits schemeIndexes = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseer); 1312296177Sjhibbits schemeIndexes &= GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseeer); 1313296177Sjhibbits 1314296177Sjhibbits event &= mask; 1315296177Sjhibbits 1316296177Sjhibbits /* clear the forced events */ 1317296177Sjhibbits force = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer); 1318296177Sjhibbits if(force & event) 1319296177Sjhibbits WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, force & ~event); 1320296177Sjhibbits 1321296177Sjhibbits WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeer, event); 1322296177Sjhibbits WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseer, schemeIndexes); 1323296177Sjhibbits 1324296177Sjhibbits if(event & FM_PCD_KG_DOUBLE_ECC) 1325296177Sjhibbits p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC); 1326296177Sjhibbits if(event & FM_PCD_KG_KEYSIZE_OVERFLOW) 1327296177Sjhibbits { 1328296177Sjhibbits if(schemeIndexes) 1329296177Sjhibbits { 1330296177Sjhibbits while(schemeIndexes) 1331296177Sjhibbits { 1332296177Sjhibbits if(schemeIndexes & 0x1) 1333296177Sjhibbits p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index)); 1334296177Sjhibbits schemeIndexes >>= 1; 1335296177Sjhibbits index+=1; 1336296177Sjhibbits } 1337296177Sjhibbits } 1338296177Sjhibbits else /* this should happen only when interrupt is forced. */ 1339296177Sjhibbits p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW); 1340296177Sjhibbits } 1341296177Sjhibbits} 1342296177Sjhibbits 1343296177Sjhibbitsstatic t_Error KgInitGuest(t_FmPcd *p_FmPcd) 1344296177Sjhibbits{ 1345296177Sjhibbits t_Error err = E_OK; 1346296177Sjhibbits t_FmPcdIpcKgSchemesParams kgAlloc; 1347296177Sjhibbits uint32_t replyLength; 1348296177Sjhibbits t_FmPcdIpcReply reply; 1349296177Sjhibbits t_FmPcdIpcMsg msg; 1350296177Sjhibbits 1351296177Sjhibbits ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID); 1352296177Sjhibbits 1353296177Sjhibbits /* in GUEST_PARTITION, we use the IPC */ 1354296177Sjhibbits memset(&reply, 0, sizeof(reply)); 1355296177Sjhibbits memset(&msg, 0, sizeof(msg)); 1356296177Sjhibbits memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams)); 1357296177Sjhibbits kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; 1358296177Sjhibbits kgAlloc.guestId = p_FmPcd->guestId; 1359296177Sjhibbits msg.msgId = FM_PCD_ALLOC_KG_SCHEMES; 1360296177Sjhibbits memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 1361296177Sjhibbits replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t); 1362296177Sjhibbits if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1363296177Sjhibbits (uint8_t*)&msg, 1364296177Sjhibbits sizeof(msg.msgId) + sizeof(kgAlloc), 1365296177Sjhibbits (uint8_t*)&reply, 1366296177Sjhibbits &replyLength, 1367296177Sjhibbits NULL, 1368296177Sjhibbits NULL)) != E_OK) 1369296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1370296177Sjhibbits if(replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t))) 1371296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 1372296177Sjhibbits memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)); 1373296177Sjhibbits 1374296177Sjhibbits return (t_Error)reply.error; 1375296177Sjhibbits} 1376296177Sjhibbits 1377296177Sjhibbitsstatic t_Error KgInitMaster(t_FmPcd *p_FmPcd) 1378296177Sjhibbits{ 1379296177Sjhibbits t_Error err = E_OK; 1380296177Sjhibbits t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 1381296177Sjhibbits int i; 1382296177Sjhibbits uint8_t hardwarePortId = 0; 1383296177Sjhibbits uint32_t tmpReg; 1384296177Sjhibbits 1385296177Sjhibbits ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); 1386296177Sjhibbits 1387296177Sjhibbits /**********************KGEER******************/ 1388296177Sjhibbits WRITE_UINT32(p_Regs->kgeer, (FM_PCD_KG_DOUBLE_ECC | FM_PCD_KG_KEYSIZE_OVERFLOW)); 1389296177Sjhibbits /**********************KGEER******************/ 1390296177Sjhibbits 1391296177Sjhibbits /**********************KGEEER******************/ 1392296177Sjhibbits tmpReg = 0; 1393296177Sjhibbits if(p_FmPcd->exceptions & FM_PCD_EX_KG_DOUBLE_ECC) 1394296177Sjhibbits { 1395296177Sjhibbits FmEnableRamsEcc(p_FmPcd->h_Fm); 1396296177Sjhibbits tmpReg |= FM_PCD_KG_DOUBLE_ECC; 1397296177Sjhibbits } 1398296177Sjhibbits if(p_FmPcd->exceptions & FM_PCD_EX_KG_KEYSIZE_OVERFLOW) 1399296177Sjhibbits tmpReg |= FM_PCD_KG_KEYSIZE_OVERFLOW; 1400296177Sjhibbits WRITE_UINT32(p_Regs->kgeeer,tmpReg); 1401296177Sjhibbits /**********************KGEEER******************/ 1402296177Sjhibbits 1403296177Sjhibbits /**********************KGFDOR******************/ 1404296177Sjhibbits WRITE_UINT32(p_Regs->kgfdor,0); 1405296177Sjhibbits /**********************KGFDOR******************/ 1406296177Sjhibbits 1407296177Sjhibbits /**********************KGGDV0R******************/ 1408296177Sjhibbits WRITE_UINT32(p_Regs->kggdv0r,0); 1409296177Sjhibbits /**********************KGGDV0R******************/ 1410296177Sjhibbits 1411296177Sjhibbits /**********************KGGDV1R******************/ 1412296177Sjhibbits WRITE_UINT32(p_Regs->kggdv1r,0); 1413296177Sjhibbits /**********************KGGDV1R******************/ 1414296177Sjhibbits 1415296177Sjhibbits /**********************KGGCR******************/ 1416296177Sjhibbits WRITE_UINT32(p_Regs->kggcr, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); 1417296177Sjhibbits /**********************KGGCR******************/ 1418296177Sjhibbits 1419296177Sjhibbits /* register even if no interrupts enabled, to allow future enablement */ 1420296177Sjhibbits FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR, PcdKgErrorException, p_FmPcd); 1421296177Sjhibbits 1422296177Sjhibbits /* clear binding between ports to schemes so that all ports are not bound to any schemes */ 1423296177Sjhibbits for (i=0;i<FM_MAX_NUM_OF_PORTS;i++) 1424296177Sjhibbits { 1425296177Sjhibbits SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, i); 1426296177Sjhibbits 1427296177Sjhibbits err = KgWriteSp(p_FmPcd, hardwarePortId, 0xffffffff, FALSE); 1428296177Sjhibbits if(err) 1429296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 1430296177Sjhibbits 1431296177Sjhibbits err = KgWriteCpp(p_FmPcd, hardwarePortId, 0); 1432296177Sjhibbits if(err) 1433296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 1434296177Sjhibbits } 1435296177Sjhibbits 1436296177Sjhibbits /* enable and enable all scheme interrupts */ 1437296177Sjhibbits WRITE_UINT32(p_Regs->kgseer, 0xFFFFFFFF); 1438296177Sjhibbits WRITE_UINT32(p_Regs->kgseeer, 0xFFFFFFFF); 1439296177Sjhibbits 1440296177Sjhibbits if(p_FmPcd->p_FmPcdKg->numOfSchemes) 1441296177Sjhibbits { 1442296177Sjhibbits err = FmPcdKgAllocSchemes(p_FmPcd, 1443296177Sjhibbits p_FmPcd->p_FmPcdKg->numOfSchemes, 1444296177Sjhibbits p_FmPcd->guestId, 1445296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesIds); 1446296177Sjhibbits if(err) 1447296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 1448296177Sjhibbits } 1449296177Sjhibbits 1450296177Sjhibbits return E_OK; 1451296177Sjhibbits} 1452296177Sjhibbits 1453296177Sjhibbits 1454296177Sjhibbits/****************************************/ 1455296177Sjhibbits/* API routines */ 1456296177Sjhibbits/****************************************/ 1457296177Sjhibbitst_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset) 1458296177Sjhibbits{ 1459296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1460296177Sjhibbits t_FmPcdKgRegs *p_Regs; 1461296177Sjhibbits 1462296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1463296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); 1464296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); 1465296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); 1466296177Sjhibbits 1467296177Sjhibbits p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 1468296177Sjhibbits if(!FmIsMaster(p_FmPcd->h_Fm)) 1469296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!")); 1470296177Sjhibbits 1471296177Sjhibbits/* not needed 1472296177Sjhibbits if(payloadOffset > 256) 1473296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("data exatraction offset from parseing end can not be more than 256")); 1474296177Sjhibbits*/ 1475296177Sjhibbits 1476296177Sjhibbits WRITE_UINT32(p_Regs->kgfdor,payloadOffset); 1477296177Sjhibbits 1478296177Sjhibbits return E_OK; 1479296177Sjhibbits} 1480296177Sjhibbits 1481296177Sjhibbitst_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value) 1482296177Sjhibbits{ 1483296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1484296177Sjhibbits t_FmPcdKgRegs *p_Regs; 1485296177Sjhibbits 1486296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1487296177Sjhibbits SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE); 1488296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); 1489296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); 1490296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); 1491296177Sjhibbits 1492296177Sjhibbits p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; 1493296177Sjhibbits 1494296177Sjhibbits if(!FmIsMaster(p_FmPcd->h_Fm)) 1495296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!")); 1496296177Sjhibbits 1497296177Sjhibbits if(valueId == 0) 1498296177Sjhibbits WRITE_UINT32(p_Regs->kggdv0r,value); 1499296177Sjhibbits else 1500296177Sjhibbits WRITE_UINT32(p_Regs->kggdv1r,value); 1501296177Sjhibbits return E_OK; 1502296177Sjhibbits} 1503296177Sjhibbits 1504296177Sjhibbits#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) 1505296177Sjhibbitst_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd) 1506296177Sjhibbits{ 1507296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 1508296177Sjhibbits int i = 0, j = 0; 1509296177Sjhibbits uint8_t hardwarePortId = 0; 1510296177Sjhibbits uint32_t tmpKgarReg, intFlags; 1511296177Sjhibbits t_Error err = E_OK; 1512296177Sjhibbits t_FmPcdIpcMsg msg; 1513296177Sjhibbits 1514296177Sjhibbits DECLARE_DUMP; 1515296177Sjhibbits 1516296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 1517296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 1518296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 1519296177Sjhibbits 1520296177Sjhibbits if(p_FmPcd->guestId != NCSW_MASTER_ID) 1521296177Sjhibbits { 1522296177Sjhibbits memset(&msg, 0, sizeof(msg)); 1523296177Sjhibbits msg.msgId = FM_PCD_KG_DUMP_REGS; 1524296177Sjhibbits return XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1525296177Sjhibbits (uint8_t*)&msg, 1526296177Sjhibbits sizeof(msg.msgId), 1527296177Sjhibbits NULL, 1528296177Sjhibbits NULL, 1529296177Sjhibbits NULL, 1530296177Sjhibbits NULL); 1531296177Sjhibbits } 1532296177Sjhibbits DUMP_SUBTITLE(("\n")); 1533296177Sjhibbits DUMP_TITLE(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, ("FmPcdKgRegs Regs")); 1534296177Sjhibbits 1535296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggcr); 1536296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgeer); 1537296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgeeer); 1538296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgseer); 1539296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgseeer); 1540296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggsr); 1541296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgtpc); 1542296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgserc); 1543296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfdor); 1544296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggdv0r); 1545296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggdv1r); 1546296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfer); 1547296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfeer); 1548296177Sjhibbits DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgar); 1549296177Sjhibbits 1550296177Sjhibbits DUMP_SUBTITLE(("\n")); 1551296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 1552296177Sjhibbits for(j = 0;j<FM_PCD_KG_NUM_OF_SCHEMES;j++) 1553296177Sjhibbits { 1554296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadSchemeActionReg((uint8_t)j); 1555296177Sjhibbits if(WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK) 1556296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 1557296177Sjhibbits 1558296177Sjhibbits DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs, ("FmPcdKgIndirectAccessSchemeRegs Scheme %d Regs", j)); 1559296177Sjhibbits 1560296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_mode); 1561296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ekfc); 1562296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ekdv); 1563296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_bmch); 1564296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_bmcl); 1565296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_fqb); 1566296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_hc); 1567296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ppc); 1568296177Sjhibbits 1569296177Sjhibbits DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_gec, ("kgse_gec")); 1570296177Sjhibbits DUMP_SUBSTRUCT_ARRAY(i, FM_PCD_KG_NUM_OF_GENERIC_REGS) 1571296177Sjhibbits { 1572296177Sjhibbits DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_gec[i], sizeof(uint32_t)); 1573296177Sjhibbits } 1574296177Sjhibbits 1575296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_spc); 1576296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_dv0); 1577296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_dv1); 1578296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ccbs); 1579296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_mv); 1580296177Sjhibbits } 1581296177Sjhibbits DUMP_SUBTITLE(("\n")); 1582296177Sjhibbits 1583296177Sjhibbits for (i=0;i<FM_MAX_NUM_OF_PORTS;i++) 1584296177Sjhibbits { 1585296177Sjhibbits SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, i); 1586296177Sjhibbits 1587296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId); 1588296177Sjhibbits 1589296177Sjhibbits err = WriteKgarWait(p_FmPcd, tmpKgarReg); 1590296177Sjhibbits if(err) 1591296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 1592296177Sjhibbits 1593296177Sjhibbits DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, ("FmPcdKgIndirectAccessPortRegs PCD Port %d regs", hardwarePortId)); 1594296177Sjhibbits 1595296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, kgoe_sp); 1596296177Sjhibbits DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, kgoe_cpp); 1597296177Sjhibbits } 1598296177Sjhibbits 1599296177Sjhibbits DUMP_SUBTITLE(("\n")); 1600296177Sjhibbits for(j=0;j<FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;j++) 1601296177Sjhibbits { 1602296177Sjhibbits DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs, ("FmPcdKgIndirectAccessClsPlanRegs Regs group %d", j)); 1603296177Sjhibbits DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs.kgcpe, ("kgcpe")); 1604296177Sjhibbits 1605296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadClsPlanBlockActionReg((uint8_t)j); 1606296177Sjhibbits err = WriteKgarWait(p_FmPcd, tmpKgarReg); 1607296177Sjhibbits if(err) 1608296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 1609296177Sjhibbits DUMP_SUBSTRUCT_ARRAY(i, 8) 1610296177Sjhibbits DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs.kgcpe[i], sizeof(uint32_t)); 1611296177Sjhibbits } 1612296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 1613296177Sjhibbits 1614296177Sjhibbits return E_OK; 1615296177Sjhibbits} 1616296177Sjhibbits#endif /* (defined(DEBUG_ERRORS) && ... */ 1617296177Sjhibbits 1618296177Sjhibbitst_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) 1619296177Sjhibbits{ 1620296177Sjhibbits t_FmPcdKg *p_FmPcdKg; 1621296177Sjhibbits 1622296177Sjhibbits UNUSED(p_FmPcd); 1623296177Sjhibbits 1624296177Sjhibbits if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES) 1625296177Sjhibbits { 1626296177Sjhibbits REPORT_ERROR(MAJOR, E_INVALID_VALUE, 1627296177Sjhibbits ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES)); 1628296177Sjhibbits return NULL; 1629296177Sjhibbits } 1630296177Sjhibbits 1631296177Sjhibbits p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg)); 1632296177Sjhibbits if (!p_FmPcdKg) 1633296177Sjhibbits { 1634296177Sjhibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED")); 1635296177Sjhibbits return NULL; 1636296177Sjhibbits } 1637296177Sjhibbits memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg)); 1638296177Sjhibbits 1639296177Sjhibbits if(FmIsMaster(p_FmPcd->h_Fm)) 1640296177Sjhibbits { 1641296177Sjhibbits p_FmPcdKg->p_FmPcdKgRegs = (t_FmPcdKgRegs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm)); 1642296177Sjhibbits p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions; 1643296177Sjhibbits } 1644296177Sjhibbits 1645296177Sjhibbits p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes; 1646296177Sjhibbits if((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes) 1647296177Sjhibbits { 1648296177Sjhibbits p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES; 1649296177Sjhibbits DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES")); 1650296177Sjhibbits } 1651296177Sjhibbits 1652296177Sjhibbits p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; 1653296177Sjhibbits 1654296177Sjhibbits return p_FmPcdKg; 1655296177Sjhibbits} 1656296177Sjhibbits 1657296177Sjhibbitst_Error KgInit(t_FmPcd *p_FmPcd) 1658296177Sjhibbits{ 1659296177Sjhibbits if (p_FmPcd->guestId == NCSW_MASTER_ID) 1660296177Sjhibbits return KgInitMaster(p_FmPcd); 1661296177Sjhibbits else 1662296177Sjhibbits return KgInitGuest(p_FmPcd); 1663296177Sjhibbits} 1664296177Sjhibbits 1665296177Sjhibbitst_Error KgFree(t_FmPcd *p_FmPcd) 1666296177Sjhibbits{ 1667296177Sjhibbits t_FmPcdIpcKgSchemesParams kgAlloc; 1668296177Sjhibbits t_Error err = E_OK; 1669296177Sjhibbits t_FmPcdIpcMsg msg; 1670296177Sjhibbits uint32_t replyLength; 1671296177Sjhibbits t_FmPcdIpcReply reply; 1672296177Sjhibbits 1673296177Sjhibbits FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR); 1674296177Sjhibbits 1675296177Sjhibbits if(p_FmPcd->guestId == NCSW_MASTER_ID) 1676296177Sjhibbits return FmPcdKgFreeSchemes(p_FmPcd, 1677296177Sjhibbits p_FmPcd->p_FmPcdKg->numOfSchemes, 1678296177Sjhibbits p_FmPcd->guestId, 1679296177Sjhibbits p_FmPcd->p_FmPcdKg->schemesIds); 1680296177Sjhibbits 1681296177Sjhibbits /* guest */ 1682296177Sjhibbits memset(&reply, 0, sizeof(reply)); 1683296177Sjhibbits memset(&msg, 0, sizeof(msg)); 1684296177Sjhibbits kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; 1685296177Sjhibbits kgAlloc.guestId = p_FmPcd->guestId; 1686296177Sjhibbits ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES); 1687296177Sjhibbits memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds , (sizeof(uint8_t))*kgAlloc.numOfSchemes); 1688296177Sjhibbits msg.msgId = FM_PCD_FREE_KG_SCHEMES; 1689296177Sjhibbits memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); 1690296177Sjhibbits replyLength = sizeof(uint32_t); 1691296177Sjhibbits if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, 1692296177Sjhibbits (uint8_t*)&msg, 1693296177Sjhibbits sizeof(msg.msgId) + sizeof(kgAlloc), 1694296177Sjhibbits (uint8_t*)&reply, 1695296177Sjhibbits &replyLength, 1696296177Sjhibbits NULL, 1697296177Sjhibbits NULL)) != E_OK) 1698296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1699296177Sjhibbits if (replyLength != sizeof(uint32_t)) 1700296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); 1701296177Sjhibbits 1702296177Sjhibbits return (t_Error)reply.error; 1703296177Sjhibbits} 1704296177Sjhibbits 1705296177Sjhibbitst_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp) 1706296177Sjhibbits{ 1707296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1708296177Sjhibbits t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams; 1709296177Sjhibbits t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; 1710296177Sjhibbits t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; 1711296177Sjhibbits t_Error err; 1712296177Sjhibbits 1713296177Sjhibbits memset(&grpParams, 0, sizeof(grpParams)); 1714296177Sjhibbits grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN; 1715296177Sjhibbits p_GrpParams = &grpParams; 1716296177Sjhibbits 1717296177Sjhibbits p_GrpParams->netEnvId = netEnvId; 1718296177Sjhibbits err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams); 1719296177Sjhibbits if(err) 1720296177Sjhibbits RETURN_ERROR(MINOR,err,NO_MSG); 1721296177Sjhibbits if(p_GrpParams->grpExists) 1722296177Sjhibbits *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; 1723296177Sjhibbits else 1724296177Sjhibbits { 1725296177Sjhibbits p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); 1726296177Sjhibbits if (!p_ClsPlanSet) 1727296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSet")); 1728296177Sjhibbits memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); 1729296177Sjhibbits err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet); 1730296177Sjhibbits if (err) 1731296177Sjhibbits { 1732296177Sjhibbits XX_Free(p_ClsPlanSet); 1733296177Sjhibbits RETURN_ERROR(MINOR,err,NO_MSG); 1734296177Sjhibbits } 1735296177Sjhibbits *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; 1736296177Sjhibbits 1737296177Sjhibbits if (p_FmPcd->h_Hc) 1738296177Sjhibbits { 1739296177Sjhibbits /* write clsPlan entries to memory */ 1740296177Sjhibbits err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet); 1741296177Sjhibbits if (err) 1742296177Sjhibbits { 1743296177Sjhibbits XX_Free(p_ClsPlanSet); 1744296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1745296177Sjhibbits } 1746296177Sjhibbits } 1747296177Sjhibbits else 1748296177Sjhibbits /* write clsPlan entries to memory */ 1749296177Sjhibbits KgSetClsPlan(p_FmPcd, p_ClsPlanSet); 1750296177Sjhibbits 1751296177Sjhibbits XX_Free(p_ClsPlanSet); 1752296177Sjhibbits } 1753296177Sjhibbits 1754296177Sjhibbits /* mark if this is an empty classification group */ 1755296177Sjhibbits if(*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) 1756296177Sjhibbits *p_IsEmptyClsPlanGrp = TRUE; 1757296177Sjhibbits else 1758296177Sjhibbits *p_IsEmptyClsPlanGrp = FALSE; 1759296177Sjhibbits 1760296177Sjhibbits p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId]; 1761296177Sjhibbits 1762296177Sjhibbits /* increment owners number */ 1763296177Sjhibbits p_ClsPlanGrp->owners++; 1764296177Sjhibbits 1765296177Sjhibbits /* copy options array for port */ 1766296177Sjhibbits memcpy(p_OptArray, &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId].optArray, FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)*sizeof(protocolOpt_t)); 1767296177Sjhibbits 1768296177Sjhibbits /* bind port to the new or existing group */ 1769296177Sjhibbits err = KgBindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId); 1770296177Sjhibbits if(err) 1771296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 1772296177Sjhibbits 1773296177Sjhibbits return E_OK; 1774296177Sjhibbits} 1775296177Sjhibbits 1776296177Sjhibbitst_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) 1777296177Sjhibbits{ 1778296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1779296177Sjhibbits t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId]; 1780296177Sjhibbits t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; 1781296177Sjhibbits 1782296177Sjhibbits FmPcdKgUnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId); 1783296177Sjhibbits 1784296177Sjhibbits /* decrement owners number */ 1785296177Sjhibbits ASSERT_COND(p_ClsPlanGrp->owners); 1786296177Sjhibbits p_ClsPlanGrp->owners--; 1787296177Sjhibbits 1788296177Sjhibbits if(!p_ClsPlanGrp->owners) 1789296177Sjhibbits { 1790296177Sjhibbits if (p_FmPcd->h_Hc) 1791296177Sjhibbits return FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId); 1792296177Sjhibbits else 1793296177Sjhibbits { 1794296177Sjhibbits /* clear clsPlan entries in memory */ 1795296177Sjhibbits p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); 1796296177Sjhibbits if (!p_ClsPlanSet) 1797296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSet")); 1798296177Sjhibbits memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); 1799296177Sjhibbits p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry; 1800296177Sjhibbits p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp; 1801296177Sjhibbits KgSetClsPlan(p_FmPcd, p_ClsPlanSet); 1802296177Sjhibbits XX_Free(p_ClsPlanSet); 1803296177Sjhibbits FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId); 1804296177Sjhibbits } 1805296177Sjhibbits } 1806296177Sjhibbits return E_OK; 1807296177Sjhibbits} 1808296177Sjhibbits 1809296177Sjhibbitst_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t_FmPcdKgInterModuleSchemeRegs *p_SchemeRegs) 1810296177Sjhibbits{ 1811296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; 1812296177Sjhibbits uint32_t grpBits = 0; 1813296177Sjhibbits uint8_t grpBase; 1814296177Sjhibbits bool direct=TRUE, absolute=FALSE; 1815296177Sjhibbits uint16_t profileId=0, numOfProfiles=0, relativeProfileId; 1816296177Sjhibbits t_Error err = E_OK; 1817296177Sjhibbits int i = 0; 1818296177Sjhibbits t_NetEnvParams netEnvParams; 1819296177Sjhibbits uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp; 1820296177Sjhibbits t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL; 1821296177Sjhibbits uint8_t j, curr, idx; 1822296177Sjhibbits uint8_t id, shift=0, code=0, offset=0, size=0; 1823296177Sjhibbits t_FmPcdExtractEntry *p_Extract = NULL; 1824296177Sjhibbits t_FmPcdKgExtractedOrParams *p_ExtractOr; 1825296177Sjhibbits bool generic = FALSE; 1826296177Sjhibbits t_KnownFieldsMasks bitMask; 1827296177Sjhibbits e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0; 1828296177Sjhibbits t_FmPcdKgSchemesExtracts *p_LocalExtractsArray; 1829296177Sjhibbits uint8_t numOfSwDefaults = 0; 1830296177Sjhibbits t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS]; 1831296177Sjhibbits uint8_t currGenId = 0, relativeSchemeId; 1832296177Sjhibbits 1833296177Sjhibbits if(!p_Scheme->modify) 1834296177Sjhibbits relativeSchemeId = p_Scheme->id.relativeSchemeId; 1835296177Sjhibbits else 1836296177Sjhibbits relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1)); 1837296177Sjhibbits 1838296177Sjhibbits memset(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId], 0, sizeof(t_FmPcdKgScheme)); 1839296177Sjhibbits memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt)); 1840296177Sjhibbits memset(p_SchemeRegs, 0, sizeof(t_FmPcdKgInterModuleSchemeRegs)); 1841296177Sjhibbits 1842296177Sjhibbits if (p_Scheme->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) 1843296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, 1844296177Sjhibbits ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)); 1845296177Sjhibbits 1846296177Sjhibbits /* by netEnv parameters, get match vector */ 1847296177Sjhibbits if(!p_Scheme->alwaysDirect) 1848296177Sjhibbits { 1849296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId = 1850296177Sjhibbits (uint8_t)(PTR_TO_UINT(p_Scheme->netEnvParams.h_NetEnv)-1); 1851296177Sjhibbits netEnvParams.netEnvId = p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId; 1852296177Sjhibbits netEnvParams.numOfDistinctionUnits = p_Scheme->netEnvParams.numOfDistinctionUnits; 1853296177Sjhibbits memcpy(netEnvParams.unitIds, p_Scheme->netEnvParams.unitIds, (sizeof(uint8_t))*p_Scheme->netEnvParams.numOfDistinctionUnits); 1854296177Sjhibbits err = PcdGetUnitsVector(p_FmPcd, &netEnvParams); 1855296177Sjhibbits if(err) 1856296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); 1857296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector = netEnvParams.vector; 1858296177Sjhibbits } 1859296177Sjhibbits else 1860296177Sjhibbits { 1861296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector = SCHEME_ALWAYS_DIRECT; 1862296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId = ILLEGAL_NETENV; 1863296177Sjhibbits } 1864296177Sjhibbits 1865296177Sjhibbits if(p_Scheme->nextEngine == e_FM_PCD_INVALID) 1866296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid")); 1867296177Sjhibbits 1868296177Sjhibbits if(p_Scheme->bypassFqidGeneration) 1869296177Sjhibbits { 1870296177Sjhibbits#ifdef FM_KG_NO_BYPASS_FQID_GEN 1871296177Sjhibbits { 1872296177Sjhibbits t_FmRevisionInfo revInfo; 1873296177Sjhibbits 1874296177Sjhibbits FM_GetRevision(p_FmPcd->h_Fm, &revInfo); 1875296177Sjhibbits if (revInfo.majorRev != 4) 1876296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration.")); 1877296177Sjhibbits } 1878296177Sjhibbits#endif /* FM_KG_NO_BYPASS_FQID_GEN */ 1879296177Sjhibbits if(p_Scheme->baseFqid) 1880296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID")); 1881296177Sjhibbits } 1882296177Sjhibbits else 1883296177Sjhibbits if(!p_Scheme->baseFqid) 1884296177Sjhibbits DBG(WARNING, ("baseFqid is 0.")); 1885296177Sjhibbits 1886296177Sjhibbits if(p_Scheme->nextEngine == e_FM_PCD_PLCR) 1887296177Sjhibbits { 1888296177Sjhibbits direct = p_Scheme->kgNextEngineParams.plcrProfile.direct; 1889296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr = direct; 1890296177Sjhibbits absolute = (bool)(p_Scheme->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE); 1891296177Sjhibbits if(!direct && absolute) 1892296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared.")); 1893296177Sjhibbits 1894296177Sjhibbits if(direct) 1895296177Sjhibbits { 1896296177Sjhibbits profileId = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId; 1897296177Sjhibbits numOfProfiles = 1; 1898296177Sjhibbits } 1899296177Sjhibbits else 1900296177Sjhibbits { 1901296177Sjhibbits profileId = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; 1902296177Sjhibbits shift = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; 1903296177Sjhibbits numOfProfiles = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles; 1904296177Sjhibbits } 1905296177Sjhibbits } 1906296177Sjhibbits 1907296177Sjhibbits if(p_Scheme->nextEngine == e_FM_PCD_CC) 1908296177Sjhibbits { 1909296177Sjhibbits#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN 1910296177Sjhibbits if((p_Scheme->kgNextEngineParams.cc.plcrNext) && (p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) 1911296177Sjhibbits { 1912296177Sjhibbits t_FmRevisionInfo revInfo; 1913296177Sjhibbits 1914296177Sjhibbits FM_GetRevision(p_FmPcd->h_Fm, &revInfo); 1915296177Sjhibbits if (revInfo.majorRev != 4) 1916296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration.")); 1917296177Sjhibbits } 1918296177Sjhibbits#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */ 1919296177Sjhibbits 1920296177Sjhibbits err = FmPcdCcGetGrpParams(p_Scheme->kgNextEngineParams.cc.h_CcTree, 1921296177Sjhibbits p_Scheme->kgNextEngineParams.cc.grpId, 1922296177Sjhibbits &grpBits, 1923296177Sjhibbits &grpBase); 1924296177Sjhibbits if(err) 1925296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 1926296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].ccUnits = grpBits; 1927296177Sjhibbits 1928296177Sjhibbits if((p_Scheme->kgNextEngineParams.cc.plcrNext) && 1929296177Sjhibbits (!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) 1930296177Sjhibbits { 1931296177Sjhibbits if(p_Scheme->kgNextEngineParams.cc.plcrProfile.sharedProfile) 1932296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification.")); 1933296177Sjhibbits absolute = FALSE; 1934296177Sjhibbits direct = p_Scheme->kgNextEngineParams.cc.plcrProfile.direct; 1935296177Sjhibbits if(direct) 1936296177Sjhibbits { 1937296177Sjhibbits profileId = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId; 1938296177Sjhibbits numOfProfiles = 1; 1939296177Sjhibbits } 1940296177Sjhibbits else 1941296177Sjhibbits { 1942296177Sjhibbits profileId = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; 1943296177Sjhibbits shift = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; 1944296177Sjhibbits numOfProfiles = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles; 1945296177Sjhibbits } 1946296177Sjhibbits } 1947296177Sjhibbits } 1948296177Sjhibbits 1949296177Sjhibbits /* if policer is used directly after KG, or after CC */ 1950296177Sjhibbits if((p_Scheme->nextEngine == e_FM_PCD_PLCR) || 1951296177Sjhibbits ((p_Scheme->nextEngine == e_FM_PCD_CC) && 1952296177Sjhibbits (p_Scheme->kgNextEngineParams.cc.plcrNext) && 1953296177Sjhibbits (!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration))) 1954296177Sjhibbits { 1955296177Sjhibbits /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ 1956296177Sjhibbits if(absolute) 1957296177Sjhibbits { 1958296177Sjhibbits /* for absolute direct policy only, */ 1959296177Sjhibbits relativeProfileId = profileId; 1960296177Sjhibbits err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId); 1961296177Sjhibbits if(err) 1962296177Sjhibbits RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset")); 1963296177Sjhibbits if(!FmPcdPlcrIsProfileValid(p_FmPcd, profileId)) 1964296177Sjhibbits RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid.")); 1965296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId = profileId; 1966296177Sjhibbits } 1967296177Sjhibbits else 1968296177Sjhibbits { 1969296177Sjhibbits /* save relative profile id's for later check */ 1970296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile = TRUE; 1971296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId = profileId; 1972296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].numOfProfiles = numOfProfiles; 1973296177Sjhibbits } 1974296177Sjhibbits } 1975296177Sjhibbits else 1976296177Sjhibbits { 1977296177Sjhibbits /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration 1978296177Sjhibbits is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */ 1979296177Sjhibbits if(p_Scheme->bypassFqidGeneration && p_Scheme->numOfUsedExtractedOrs) 1980296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, 1981296177Sjhibbits ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID")); 1982296177Sjhibbits if(p_Scheme->bypassFqidGeneration && 1983296177Sjhibbits p_Scheme->useHash && 1984296177Sjhibbits p_Scheme->keyExtractAndHashParams.hashDistributionNumOfFqids) 1985296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, 1986296177Sjhibbits ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID")); 1987296177Sjhibbits } 1988296177Sjhibbits 1989296177Sjhibbits /* configure all 21 scheme registers */ 1990296177Sjhibbits tmpReg = KG_SCH_MODE_EN; 1991296177Sjhibbits switch(p_Scheme->nextEngine) 1992296177Sjhibbits { 1993296177Sjhibbits case(e_FM_PCD_PLCR): 1994296177Sjhibbits /* add to mode register - NIA */ 1995296177Sjhibbits tmpReg |= KG_SCH_MODE_NIA_PLCR; 1996296177Sjhibbits tmpReg |= NIA_ENG_PLCR; 1997296177Sjhibbits tmpReg |= (uint32_t)(p_Scheme->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0); 1998296177Sjhibbits /* initialize policer profile command - */ 1999296177Sjhibbits /* configure kgse_ppc */ 2000296177Sjhibbits if(direct) 2001296177Sjhibbits /* use profileId as base, other fields are 0 */ 2002296177Sjhibbits p_SchemeRegs->kgse_ppc = (uint32_t)profileId; 2003296177Sjhibbits else 2004296177Sjhibbits { 2005296177Sjhibbits if(shift > MAX_PP_SHIFT) 2006296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); 2007296177Sjhibbits 2008296177Sjhibbits if(!numOfProfiles || !POWER_OF_2(numOfProfiles)) 2009296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); 2010296177Sjhibbits 2011296177Sjhibbits ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; 2012296177Sjhibbits ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW; 2013296177Sjhibbits ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT); 2014296177Sjhibbits ppcTmp |= (uint32_t)profileId; 2015296177Sjhibbits 2016296177Sjhibbits p_SchemeRegs->kgse_ppc = ppcTmp; 2017296177Sjhibbits } 2018296177Sjhibbits break; 2019296177Sjhibbits case(e_FM_PCD_CC): 2020296177Sjhibbits /* mode reg - define NIA */ 2021296177Sjhibbits tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); 2022296177Sjhibbits 2023296177Sjhibbits p_SchemeRegs->kgse_ccbs = grpBits; 2024296177Sjhibbits tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT); 2025296177Sjhibbits 2026296177Sjhibbits if(p_Scheme->kgNextEngineParams.cc.plcrNext) 2027296177Sjhibbits { 2028296177Sjhibbits if(!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration) 2029296177Sjhibbits { 2030296177Sjhibbits /* find out if absolute or relative */ 2031296177Sjhibbits if(absolute) 2032296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("It is illegal to request a shared profile in a scheme that is in a KG->CC->PLCR flow")); 2033296177Sjhibbits if(direct) 2034296177Sjhibbits { 2035296177Sjhibbits /* mask = 0, base = directProfileId */ 2036296177Sjhibbits p_SchemeRegs->kgse_ppc = (uint32_t)profileId; 2037296177Sjhibbits } 2038296177Sjhibbits else 2039296177Sjhibbits { 2040296177Sjhibbits if(shift > MAX_PP_SHIFT) 2041296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); 2042296177Sjhibbits if(!numOfProfiles || !POWER_OF_2(numOfProfiles)) 2043296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); 2044296177Sjhibbits 2045296177Sjhibbits ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; 2046296177Sjhibbits ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW; 2047296177Sjhibbits ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT); 2048296177Sjhibbits ppcTmp |= (uint32_t)profileId; 2049296177Sjhibbits 2050296177Sjhibbits p_SchemeRegs->kgse_ppc = ppcTmp; 2051296177Sjhibbits } 2052296177Sjhibbits } 2053296177Sjhibbits else 2054296177Sjhibbits ppcTmp = KG_SCH_PP_NO_GEN; 2055296177Sjhibbits } 2056296177Sjhibbits break; 2057296177Sjhibbits case(e_FM_PCD_DONE): 2058296177Sjhibbits if(p_Scheme->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME) 2059296177Sjhibbits tmpReg |= (NIA_ENG_BMI | NIA_BMI_AC_DISCARD); 2060296177Sjhibbits else 2061296177Sjhibbits tmpReg |= (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME); 2062296177Sjhibbits break; 2063296177Sjhibbits default: 2064296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported")); 2065296177Sjhibbits } 2066296177Sjhibbits p_SchemeRegs->kgse_mode = tmpReg; 2067296177Sjhibbits 2068296177Sjhibbits p_SchemeRegs->kgse_mv = p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector; 2069296177Sjhibbits 2070296177Sjhibbits if(p_Scheme->useHash) 2071296177Sjhibbits { 2072296177Sjhibbits p_KeyAndHash = &p_Scheme->keyExtractAndHashParams; 2073296177Sjhibbits 2074296177Sjhibbits if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY) 2075296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range")); 2076296177Sjhibbits 2077296177Sjhibbits /* configure kgse_dv0 */ 2078296177Sjhibbits p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0; 2079296177Sjhibbits 2080296177Sjhibbits /* configure kgse_dv1 */ 2081296177Sjhibbits p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1; 2082296177Sjhibbits 2083296177Sjhibbits if(!p_Scheme->bypassFqidGeneration) 2084296177Sjhibbits { 2085296177Sjhibbits if(!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids)) 2086296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2")); 2087296177Sjhibbits if((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_Scheme->baseFqid) 2088296177Sjhibbits DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues.")); 2089296177Sjhibbits } 2090296177Sjhibbits 2091296177Sjhibbits /* configure kgse_ekdv */ 2092296177Sjhibbits tmpReg = 0; 2093296177Sjhibbits for( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++) 2094296177Sjhibbits { 2095296177Sjhibbits switch(p_KeyAndHash->dflts[i].type) 2096296177Sjhibbits { 2097296177Sjhibbits case(e_FM_PCD_KG_MAC_ADDR): 2098296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT); 2099296177Sjhibbits break; 2100296177Sjhibbits case(e_FM_PCD_KG_TCI): 2101296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT); 2102296177Sjhibbits break; 2103296177Sjhibbits case(e_FM_PCD_KG_ENET_TYPE): 2104296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT); 2105296177Sjhibbits break; 2106296177Sjhibbits case(e_FM_PCD_KG_PPP_SESSION_ID): 2107296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT); 2108296177Sjhibbits break; 2109296177Sjhibbits case(e_FM_PCD_KG_PPP_PROTOCOL_ID): 2110296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT); 2111296177Sjhibbits break; 2112296177Sjhibbits case(e_FM_PCD_KG_MPLS_LABEL): 2113296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT); 2114296177Sjhibbits break; 2115296177Sjhibbits case(e_FM_PCD_KG_IP_ADDR): 2116296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT); 2117296177Sjhibbits break; 2118296177Sjhibbits case(e_FM_PCD_KG_PROTOCOL_TYPE): 2119296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT); 2120296177Sjhibbits break; 2121296177Sjhibbits case(e_FM_PCD_KG_IP_TOS_TC): 2122296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT); 2123296177Sjhibbits break; 2124296177Sjhibbits case(e_FM_PCD_KG_IPV6_FLOW_LABEL): 2125296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); 2126296177Sjhibbits break; 2127296177Sjhibbits case(e_FM_PCD_KG_IPSEC_SPI): 2128296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT); 2129296177Sjhibbits break; 2130296177Sjhibbits case(e_FM_PCD_KG_L4_PORT): 2131296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); 2132296177Sjhibbits break; 2133296177Sjhibbits case(e_FM_PCD_KG_TCP_FLAG): 2134296177Sjhibbits tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT); 2135296177Sjhibbits break; 2136296177Sjhibbits case(e_FM_PCD_KG_GENERIC_FROM_DATA): 2137296177Sjhibbits swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA; 2138296177Sjhibbits swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; 2139296177Sjhibbits numOfSwDefaults ++; 2140296177Sjhibbits break; 2141296177Sjhibbits case(e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V): 2142296177Sjhibbits swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V; 2143296177Sjhibbits swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; 2144296177Sjhibbits numOfSwDefaults ++; 2145296177Sjhibbits break; 2146296177Sjhibbits case(e_FM_PCD_KG_GENERIC_NOT_FROM_DATA): 2147296177Sjhibbits swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA; 2148296177Sjhibbits swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; 2149296177Sjhibbits numOfSwDefaults ++; 2150296177Sjhibbits break; 2151296177Sjhibbits default: 2152296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 2153296177Sjhibbits } 2154296177Sjhibbits } 2155296177Sjhibbits p_SchemeRegs->kgse_ekdv = tmpReg; 2156296177Sjhibbits 2157296177Sjhibbits p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts)); 2158296177Sjhibbits if(!p_LocalExtractsArray) 2159296177Sjhibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); 2160296177Sjhibbits 2161296177Sjhibbits /* configure kgse_ekfc and kgse_gec */ 2162296177Sjhibbits knownTmp = 0; 2163296177Sjhibbits for( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++) 2164296177Sjhibbits { 2165296177Sjhibbits p_Extract = &p_KeyAndHash->extractArray[i]; 2166296177Sjhibbits switch(p_Extract->type) 2167296177Sjhibbits { 2168296177Sjhibbits case(e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): 2169296177Sjhibbits knownTmp |= KG_SCH_KN_PORT_ID; 2170296177Sjhibbits /* save in driver structure */ 2171296177Sjhibbits p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID); 2172296177Sjhibbits p_LocalExtractsArray->extractsArray[i].known = TRUE; 2173296177Sjhibbits break; 2174296177Sjhibbits case(e_FM_PCD_EXTRACT_BY_HDR): 2175296177Sjhibbits switch(p_Extract->extractByHdr.hdr) 2176296177Sjhibbits { 2177296177Sjhibbits case(HEADER_TYPE_UDP_ENCAP_ESP): 2178296177Sjhibbits switch(p_Extract->extractByHdr.type) 2179296177Sjhibbits { 2180296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_HDR): 2181296177Sjhibbits /* case where extraction from ESP only */ 2182296177Sjhibbits if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE) 2183296177Sjhibbits { 2184296177Sjhibbits p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 2185296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE; 2186296177Sjhibbits p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 2187296177Sjhibbits } 2188296177Sjhibbits else 2189296177Sjhibbits { 2190296177Sjhibbits p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; 2191296177Sjhibbits p_Extract->extractByHdr.ignoreProtocolValidation = FALSE; 2192296177Sjhibbits } 2193296177Sjhibbits break; 2194296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_FIELD): 2195296177Sjhibbits switch(p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp) 2196296177Sjhibbits { 2197296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): 2198296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): 2199296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): 2200296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): 2201296177Sjhibbits p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; 2202296177Sjhibbits break; 2203296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): 2204296177Sjhibbits p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 2205296177Sjhibbits p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 2206296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromField.size = p_Extract->extractByHdr.extractByHdrType.fromField.size; 2207296177Sjhibbits /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/ 2208296177Sjhibbits p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 2209296177Sjhibbits break; 2210296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): 2211296177Sjhibbits p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 2212296177Sjhibbits p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 2213296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromField.size = p_Extract->extractByHdr.extractByHdrType.fromField.size; 2214296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET; 2215296177Sjhibbits p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 2216296177Sjhibbits break; 2217296177Sjhibbits } 2218296177Sjhibbits break; 2219296177Sjhibbits case(e_FM_PCD_EXTRACT_FULL_FIELD): 2220296177Sjhibbits switch(p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp) 2221296177Sjhibbits { 2222296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): 2223296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): 2224296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): 2225296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): 2226296177Sjhibbits p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; 2227296177Sjhibbits break; 2228296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): 2229296177Sjhibbits p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 2230296177Sjhibbits p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 2231296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE; 2232296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET; 2233296177Sjhibbits p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 2234296177Sjhibbits break; 2235296177Sjhibbits case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): 2236296177Sjhibbits p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; 2237296177Sjhibbits p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); 2238296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE; 2239296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET; 2240296177Sjhibbits p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; 2241296177Sjhibbits break; 2242296177Sjhibbits } 2243296177Sjhibbits break; 2244296177Sjhibbits } 2245296177Sjhibbits break; 2246296177Sjhibbits default: 2247296177Sjhibbits break; 2248296177Sjhibbits } 2249296177Sjhibbits switch(p_Extract->extractByHdr.type) 2250296177Sjhibbits { 2251296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_HDR): 2252296177Sjhibbits generic = TRUE; 2253296177Sjhibbits /* get the header code for the generic extract */ 2254296177Sjhibbits code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation); 2255296177Sjhibbits /* set generic register fields */ 2256296177Sjhibbits offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset; 2257296177Sjhibbits size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size; 2258296177Sjhibbits break; 2259296177Sjhibbits case(e_FM_PCD_EXTRACT_FROM_FIELD): 2260296177Sjhibbits generic = TRUE; 2261296177Sjhibbits /* get the field code for the generic extract */ 2262296177Sjhibbits code = GetGenFieldCode(p_Extract->extractByHdr.hdr, 2263296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex); 2264296177Sjhibbits offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset; 2265296177Sjhibbits size = p_Extract->extractByHdr.extractByHdrType.fromField.size; 2266296177Sjhibbits break; 2267296177Sjhibbits case(e_FM_PCD_EXTRACT_FULL_FIELD): 2268296177Sjhibbits if(!p_Extract->extractByHdr.ignoreProtocolValidation) 2269296177Sjhibbits { 2270296177Sjhibbits /* if we have a known field for it - use it, otherwise use generic */ 2271296177Sjhibbits bitMask = GetKnownProtMask(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, 2272296177Sjhibbits p_Extract->extractByHdr.extractByHdrType.fullField); 2273296177Sjhibbits if(bitMask) 2274296177Sjhibbits { 2275296177Sjhibbits knownTmp |= bitMask; 2276296177Sjhibbits /* save in driver structure */ 2277296177Sjhibbits p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask); 2278296177Sjhibbits p_LocalExtractsArray->extractsArray[i].known = TRUE; 2279296177Sjhibbits } 2280296177Sjhibbits else 2281296177Sjhibbits generic = TRUE; 2282296177Sjhibbits 2283296177Sjhibbits } 2284296177Sjhibbits else 2285296177Sjhibbits generic = TRUE; 2286296177Sjhibbits if(generic) 2287296177Sjhibbits { 2288296177Sjhibbits /* tmp - till we cover more headers under generic */ 2289296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported")); 2290296177Sjhibbits } 2291296177Sjhibbits break; 2292296177Sjhibbits default: 2293296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 2294296177Sjhibbits } 2295296177Sjhibbits break; 2296296177Sjhibbits case(e_FM_PCD_EXTRACT_NON_HDR): 2297296177Sjhibbits /* use generic */ 2298296177Sjhibbits generic = TRUE; 2299296177Sjhibbits offset = 0; 2300296177Sjhibbits /* get the field code for the generic extract */ 2301296177Sjhibbits code = GetGenCode(p_Extract->extractNonHdr.src, &offset); 2302296177Sjhibbits offset += p_Extract->extractNonHdr.offset; 2303296177Sjhibbits size = p_Extract->extractNonHdr.size; 2304296177Sjhibbits break; 2305296177Sjhibbits default: 2306296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 2307296177Sjhibbits } 2308296177Sjhibbits 2309296177Sjhibbits if(generic) 2310296177Sjhibbits { 2311296177Sjhibbits /* set generic register fields */ 2312296177Sjhibbits if(currGenId >= FM_PCD_KG_NUM_OF_GENERIC_REGS) 2313296177Sjhibbits RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); 2314296177Sjhibbits if(!code) 2315296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); 2316296177Sjhibbits 2317296177Sjhibbits genTmp = KG_SCH_GEN_VALID; 2318296177Sjhibbits genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); 2319296177Sjhibbits genTmp |= offset; 2320296177Sjhibbits if((size > MAX_KG_SCH_SIZE) || (size < 1)) 2321296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)")); 2322296177Sjhibbits genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT); 2323296177Sjhibbits swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code); 2324296177Sjhibbits if(swDefault == e_FM_PCD_KG_DFLT_ILLEGAL) 2325296177Sjhibbits DBG(WARNING, ("No sw default configured")); 2326296177Sjhibbits 2327296177Sjhibbits genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT; 2328296177Sjhibbits genTmp |= KG_SCH_GEN_MASK; 2329296177Sjhibbits p_SchemeRegs->kgse_gec[currGenId] = genTmp; 2330296177Sjhibbits /* save in driver structure */ 2331296177Sjhibbits p_LocalExtractsArray->extractsArray[i].id = currGenId++; 2332296177Sjhibbits p_LocalExtractsArray->extractsArray[i].known = FALSE; 2333296177Sjhibbits generic = FALSE; 2334296177Sjhibbits } 2335296177Sjhibbits } 2336296177Sjhibbits p_SchemeRegs->kgse_ekfc = knownTmp; 2337296177Sjhibbits 2338296177Sjhibbits selectTmp = 0; 2339296177Sjhibbits maskTmp = 0xFFFFFFFF; 2340296177Sjhibbits /* configure kgse_bmch, kgse_bmcl and kgse_fqb */ 2341296177Sjhibbits 2342296177Sjhibbits if(p_KeyAndHash->numOfUsedMasks >= FM_PCD_KG_NUM_OF_EXTRACT_MASKS) 2343296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS)); 2344296177Sjhibbits for( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++) 2345296177Sjhibbits { 2346296177Sjhibbits /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */ 2347296177Sjhibbits id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id; 2348296177Sjhibbits /* Get the shift of the select field (depending on i) */ 2349296177Sjhibbits GET_MASK_SEL_SHIFT(shift,i); 2350296177Sjhibbits if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known) 2351296177Sjhibbits selectTmp |= id << shift; 2352296177Sjhibbits else 2353296177Sjhibbits selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift; 2354296177Sjhibbits 2355296177Sjhibbits /* Get the shift of the offset field (depending on i) - may 2356296177Sjhibbits be in kgse_bmch or in kgse_fqb (depending on i) */ 2357296177Sjhibbits GET_MASK_OFFSET_SHIFT(shift,i); 2358296177Sjhibbits if (i<=1) 2359296177Sjhibbits selectTmp |= p_KeyAndHash->masks[i].offset << shift; 2360296177Sjhibbits else 2361296177Sjhibbits fqbTmp |= p_KeyAndHash->masks[i].offset << shift; 2362296177Sjhibbits 2363296177Sjhibbits /* Get the shift of the mask field (depending on i) */ 2364296177Sjhibbits GET_MASK_SHIFT(shift,i); 2365296177Sjhibbits /* pass all bits */ 2366296177Sjhibbits maskTmp |= KG_SCH_BITMASK_MASK << shift; 2367296177Sjhibbits /* clear bits that need masking */ 2368296177Sjhibbits maskTmp &= ~(0xFF << shift) ; 2369296177Sjhibbits /* set mask bits */ 2370296177Sjhibbits maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ; 2371296177Sjhibbits } 2372296177Sjhibbits p_SchemeRegs->kgse_bmch = selectTmp; 2373296177Sjhibbits p_SchemeRegs->kgse_bmcl = maskTmp; 2374296177Sjhibbits /* kgse_fqb will be written t the end of the routine */ 2375296177Sjhibbits 2376296177Sjhibbits /* configure kgse_hc */ 2377296177Sjhibbits if(p_KeyAndHash->hashShift > MAX_HASH_SHIFT) 2378296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT)); 2379296177Sjhibbits if(p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT) 2380296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT)); 2381296177Sjhibbits 2382296177Sjhibbits tmpReg = 0; 2383296177Sjhibbits 2384296177Sjhibbits tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift); 2385296177Sjhibbits tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT; 2386296177Sjhibbits 2387296177Sjhibbits if(p_KeyAndHash->symmetricHash) 2388296177Sjhibbits { 2389296177Sjhibbits if((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) || 2390296177Sjhibbits (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) || 2391296177Sjhibbits (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) || 2392296177Sjhibbits (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST))) 2393296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing")); 2394296177Sjhibbits tmpReg |= KG_SCH_HASH_CONFIG_SYM; 2395296177Sjhibbits } 2396296177Sjhibbits p_SchemeRegs->kgse_hc = tmpReg; 2397296177Sjhibbits 2398296177Sjhibbits /* build the return array describing the order of the extractions */ 2399296177Sjhibbits 2400296177Sjhibbits /* the last currGenId places of the array 2401296177Sjhibbits are for generic extracts that are always last. 2402296177Sjhibbits We now sort for the calculation of the order of the known 2403296177Sjhibbits extractions we sort the known extracts between orderedArray[0] and 2404296177Sjhibbits orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1]. 2405296177Sjhibbits for the calculation of the order of the generic extractions we use: 2406296177Sjhibbits num_of_generic - currGenId 2407296177Sjhibbits num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId 2408296177Sjhibbits first_generic_index = num_of_known */ 2409296177Sjhibbits curr = 0; 2410296177Sjhibbits for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++) 2411296177Sjhibbits { 2412296177Sjhibbits if(p_LocalExtractsArray->extractsArray[i].known) 2413296177Sjhibbits { 2414296177Sjhibbits ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId)); 2415296177Sjhibbits j = curr; 2416296177Sjhibbits /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original 2417296177Sjhibbits index in the user's extractions array */ 2418296177Sjhibbits /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1] 2419296177Sjhibbits location */ 2420296177Sjhibbits while((j > 0) && (p_LocalExtractsArray->extractsArray[i].id < 2421296177Sjhibbits p_LocalExtractsArray->extractsArray[p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j-1]].id)) 2422296177Sjhibbits { 2423296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j] = 2424296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j-1]; 2425296177Sjhibbits j--; 2426296177Sjhibbits } 2427296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j] = (uint8_t)i; 2428296177Sjhibbits curr++; 2429296177Sjhibbits } 2430296177Sjhibbits else 2431296177Sjhibbits { 2432296177Sjhibbits /* index is first_generic_index + generic index (id) */ 2433296177Sjhibbits idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id); 2434296177Sjhibbits ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY); 2435296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[idx]= (uint8_t)i; 2436296177Sjhibbits } 2437296177Sjhibbits } 2438296177Sjhibbits XX_Free(p_LocalExtractsArray); 2439296177Sjhibbits p_LocalExtractsArray = NULL; 2440296177Sjhibbits 2441296177Sjhibbits } 2442296177Sjhibbits else 2443296177Sjhibbits { 2444296177Sjhibbits /* clear all unused registers: */ 2445296177Sjhibbits p_SchemeRegs->kgse_ekfc = 0; 2446296177Sjhibbits p_SchemeRegs->kgse_ekdv = 0; 2447296177Sjhibbits p_SchemeRegs->kgse_bmch = 0; 2448296177Sjhibbits p_SchemeRegs->kgse_bmcl = 0; 2449296177Sjhibbits p_SchemeRegs->kgse_hc = 0; 2450296177Sjhibbits p_SchemeRegs->kgse_dv0 = 0; 2451296177Sjhibbits p_SchemeRegs->kgse_dv1 = 0; 2452296177Sjhibbits } 2453296177Sjhibbits 2454296177Sjhibbits if(p_Scheme->bypassFqidGeneration) 2455296177Sjhibbits p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID; 2456296177Sjhibbits 2457296177Sjhibbits /* configure kgse_spc */ 2458296177Sjhibbits if( p_Scheme->schemeCounter.update) 2459296177Sjhibbits p_SchemeRegs->kgse_spc = p_Scheme->schemeCounter.value; 2460296177Sjhibbits 2461296177Sjhibbits 2462296177Sjhibbits /* check that are enough generic registers */ 2463296177Sjhibbits if(p_Scheme->numOfUsedExtractedOrs + currGenId > FM_PCD_KG_NUM_OF_GENERIC_REGS) 2464296177Sjhibbits RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); 2465296177Sjhibbits 2466296177Sjhibbits /* extracted OR mask on Qid */ 2467296177Sjhibbits for( i=0 ;i<p_Scheme->numOfUsedExtractedOrs ; i++) 2468296177Sjhibbits { 2469296177Sjhibbits 2470296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs = TRUE; 2471296177Sjhibbits /* configure kgse_gec[i] */ 2472296177Sjhibbits p_ExtractOr = &p_Scheme->extractedOrs[i]; 2473296177Sjhibbits switch(p_ExtractOr->type) 2474296177Sjhibbits { 2475296177Sjhibbits case(e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): 2476296177Sjhibbits code = KG_SCH_GEN_PARSE_RESULT_N_FQID; 2477296177Sjhibbits offset = 0; 2478296177Sjhibbits break; 2479296177Sjhibbits case(e_FM_PCD_EXTRACT_BY_HDR): 2480296177Sjhibbits /* get the header code for the generic extract */ 2481296177Sjhibbits code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation); 2482296177Sjhibbits /* set generic register fields */ 2483296177Sjhibbits offset = p_ExtractOr->extractionOffset; 2484296177Sjhibbits break; 2485296177Sjhibbits case(e_FM_PCD_EXTRACT_NON_HDR): 2486296177Sjhibbits /* get the field code for the generic extract */ 2487296177Sjhibbits offset = 0; 2488296177Sjhibbits code = GetGenCode(p_ExtractOr->src, &offset); 2489296177Sjhibbits offset += p_ExtractOr->extractionOffset; 2490296177Sjhibbits break; 2491296177Sjhibbits default: 2492296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); 2493296177Sjhibbits } 2494296177Sjhibbits 2495296177Sjhibbits /* set generic register fields */ 2496296177Sjhibbits if(!code) 2497296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); 2498296177Sjhibbits genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID; 2499296177Sjhibbits genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); 2500296177Sjhibbits genTmp |= offset; 2501296177Sjhibbits if(!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile) 2502296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile")); 2503296177Sjhibbits 2504296177Sjhibbits /************************************************************************************ 2505296177Sjhibbits bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter 2506296177Sjhibbits in the following way: 2507296177Sjhibbits 2508296177Sjhibbits Driver API and implementation: 2509296177Sjhibbits ============================== 2510296177Sjhibbits FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID. 2511296177Sjhibbits if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that 2512296177Sjhibbits are not overlapping FQID. 2513296177Sjhibbits ------------------------ 2514296177Sjhibbits | FQID (24) | 2515296177Sjhibbits ------------------------ 2516296177Sjhibbits -------- 2517296177Sjhibbits | | extracted OR byte 2518296177Sjhibbits -------- 2519296177Sjhibbits 2520296177Sjhibbits Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the 2521296177Sjhibbits PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that 2522296177Sjhibbits are not overlapping PP id. 2523296177Sjhibbits 2524296177Sjhibbits -------- 2525296177Sjhibbits | PP (8) | 2526296177Sjhibbits -------- 2527296177Sjhibbits -------- 2528296177Sjhibbits | | extracted OR byte 2529296177Sjhibbits -------- 2530296177Sjhibbits 2531296177Sjhibbits HW implementation 2532296177Sjhibbits ================= 2533296177Sjhibbits FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located 2534296177Sjhibbits as the highest byte of that word and may be rotated to effect any part os the FQID or 2535296177Sjhibbits the PP. 2536296177Sjhibbits ------------------------ -------- 2537296177Sjhibbits | FQID (24) || PP (8) | 2538296177Sjhibbits ------------------------ -------- 2539296177Sjhibbits -------- 2540296177Sjhibbits | | extracted OR byte 2541296177Sjhibbits -------- 2542296177Sjhibbits 2543296177Sjhibbits ************************************************************************************/ 2544296177Sjhibbits 2545296177Sjhibbits if(p_ExtractOr->bitOffsetInFqid) 2546296177Sjhibbits { 2547296177Sjhibbits if(p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET ) 2548296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)")); 2549296177Sjhibbits if(p_ExtractOr->bitOffsetInFqid<8) 2550296177Sjhibbits genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT); 2551296177Sjhibbits else 2552296177Sjhibbits genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT); 2553296177Sjhibbits p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE); 2554296177Sjhibbits } 2555296177Sjhibbits else /* effect policer profile */ 2556296177Sjhibbits { 2557296177Sjhibbits if(p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET ) 2558296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)")); 2559296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile; 2560296177Sjhibbits genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT); 2561296177Sjhibbits p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE); 2562296177Sjhibbits } 2563296177Sjhibbits 2564296177Sjhibbits genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT); 2565296177Sjhibbits /* clear bits that need masking */ 2566296177Sjhibbits genTmp &= ~KG_SCH_GEN_MASK ; 2567296177Sjhibbits /* set mask bits */ 2568296177Sjhibbits genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT); 2569296177Sjhibbits p_SchemeRegs->kgse_gec[currGenId++] = genTmp; 2570296177Sjhibbits 2571296177Sjhibbits } 2572296177Sjhibbits /* clear all unused GEC registers */ 2573296177Sjhibbits for( i=currGenId ;i<FM_PCD_KG_NUM_OF_GENERIC_REGS ; i++) 2574296177Sjhibbits p_SchemeRegs->kgse_gec[i] = 0; 2575296177Sjhibbits 2576296177Sjhibbits /* add base Qid for this scheme */ 2577296177Sjhibbits /* add configuration for kgse_fqb */ 2578296177Sjhibbits if(p_Scheme->baseFqid & ~0x00FFFFFF) 2579296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1")); 2580296177Sjhibbits 2581296177Sjhibbits fqbTmp |= p_Scheme->baseFqid; 2582296177Sjhibbits p_SchemeRegs->kgse_fqb = fqbTmp; 2583296177Sjhibbits 2584296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine = p_Scheme->nextEngine; 2585296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction = p_Scheme->kgNextEngineParams.doneAction; 2586296177Sjhibbits return E_OK; 2587296177Sjhibbits} 2588296177Sjhibbits 2589296177Sjhibbitsvoid FmPcdKgValidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId) 2590296177Sjhibbits{ 2591296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2592296177Sjhibbits 2593296177Sjhibbits ASSERT_COND(!p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2594296177Sjhibbits 2595296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId != ILLEGAL_NETENV) 2596296177Sjhibbits FmPcdIncNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId); 2597296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[schemeId].valid = TRUE; 2598296177Sjhibbits} 2599296177Sjhibbits 2600296177Sjhibbitsvoid FmPcdKgInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId) 2601296177Sjhibbits{ 2602296177Sjhibbits 2603296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2604296177Sjhibbits 2605296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId != ILLEGAL_NETENV) 2606296177Sjhibbits FmPcdDecNetEnvOwners(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId); 2607296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[schemeId].valid = FALSE; 2608296177Sjhibbits} 2609296177Sjhibbits 2610296177Sjhibbitsuint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId) 2611296177Sjhibbits{ 2612296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2613296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2614296177Sjhibbits 2615296177Sjhibbits return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction; 2616296177Sjhibbits} 2617296177Sjhibbits 2618296177Sjhibbitsuint32_t FmPcdKgGetPointedOwners(t_Handle h_FmPcd, uint8_t schemeId) 2619296177Sjhibbits{ 2620296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2621296177Sjhibbits 2622296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2623296177Sjhibbits 2624296177Sjhibbits return p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners; 2625296177Sjhibbits} 2626296177Sjhibbits 2627296177Sjhibbitsbool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId) 2628296177Sjhibbits{ 2629296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2630296177Sjhibbits 2631296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2632296177Sjhibbits 2633296177Sjhibbits return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr; 2634296177Sjhibbits} 2635296177Sjhibbits 2636296177Sjhibbits 2637296177Sjhibbitsuint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId) 2638296177Sjhibbits{ 2639296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2640296177Sjhibbits 2641296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2642296177Sjhibbits 2643296177Sjhibbits return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId; 2644296177Sjhibbits} 2645296177Sjhibbits 2646296177Sjhibbits 2647296177Sjhibbitsbool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId) 2648296177Sjhibbits{ 2649296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2650296177Sjhibbits 2651296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2652296177Sjhibbits 2653296177Sjhibbits if((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs && 2654296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) || 2655296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile) 2656296177Sjhibbits return TRUE; 2657296177Sjhibbits else 2658296177Sjhibbits return FALSE; 2659296177Sjhibbits 2660296177Sjhibbits} 2661296177Sjhibbitsvoid FmPcdKgUpatePointedOwner(t_Handle h_FmPcd, uint8_t schemeId, bool add) 2662296177Sjhibbits{ 2663296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2664296177Sjhibbits 2665296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2666296177Sjhibbits 2667296177Sjhibbits if(add) 2668296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners++; 2669296177Sjhibbits else 2670296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners--; 2671296177Sjhibbits} 2672296177Sjhibbits 2673296177Sjhibbitse_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId) 2674296177Sjhibbits{ 2675296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2676296177Sjhibbits 2677296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2678296177Sjhibbits 2679296177Sjhibbits return p_FmPcd->p_FmPcdKg->schemes[schemeId].nextEngine; 2680296177Sjhibbits} 2681296177Sjhibbits 2682296177Sjhibbitse_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId) 2683296177Sjhibbits{ 2684296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2685296177Sjhibbits 2686296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2687296177Sjhibbits 2688296177Sjhibbits return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction; 2689296177Sjhibbits} 2690296177Sjhibbits 2691296177Sjhibbitsvoid FmPcdKgUpdateRequiredAction(t_Handle h_FmPcd, uint8_t schemeId, uint32_t requiredAction) 2692296177Sjhibbits{ 2693296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2694296177Sjhibbits 2695296177Sjhibbits ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); 2696296177Sjhibbits 2697296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction = requiredAction; 2698296177Sjhibbits} 2699296177Sjhibbits 2700296177Sjhibbitst_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId) 2701296177Sjhibbits{ 2702296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2703296177Sjhibbits 2704296177Sjhibbits if(schemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 2705296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 2706296177Sjhibbits 2707296177Sjhibbits /* check that no port is bound to this scheme */ 2708296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemes[schemeId].owners) 2709296177Sjhibbits RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to")); 2710296177Sjhibbits if(!p_FmPcd->p_FmPcdKg->schemes[schemeId].valid) 2711296177Sjhibbits RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete an invalid scheme")); 2712296177Sjhibbits return E_OK; 2713296177Sjhibbits} 2714296177Sjhibbits 2715296177Sjhibbitsuint32_t FmPcdKgBuildCppReg(t_Handle h_FmPcd, uint8_t clsPlanGrpId) 2716296177Sjhibbits{ 2717296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2718296177Sjhibbits uint32_t tmpKgpeCpp; 2719296177Sjhibbits 2720296177Sjhibbits tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8); 2721296177Sjhibbits tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_PCD_KG_PE_CPP_MASK_SHIFT); 2722296177Sjhibbits return tmpKgpeCpp; 2723296177Sjhibbits} 2724296177Sjhibbits 2725296177Sjhibbitsbool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg) 2726296177Sjhibbits{ 2727296177Sjhibbits 2728296177Sjhibbits if(schemeModeReg & KG_SCH_MODE_EN) 2729296177Sjhibbits return TRUE; 2730296177Sjhibbits else 2731296177Sjhibbits return FALSE; 2732296177Sjhibbits} 2733296177Sjhibbits 2734296177Sjhibbitsuint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter) 2735296177Sjhibbits{ 2736296177Sjhibbits return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT)| 2737296177Sjhibbits FM_PCD_KG_KGAR_GO | 2738296177Sjhibbits FM_PCD_KG_KGAR_WRITE | 2739296177Sjhibbits FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY | 2740296177Sjhibbits DUMMY_PORT_ID | 2741296177Sjhibbits (updateCounter ? FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT:0)); 2742296177Sjhibbits 2743296177Sjhibbits} 2744296177Sjhibbits 2745296177Sjhibbitsuint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId) 2746296177Sjhibbits{ 2747296177Sjhibbits return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT)| 2748296177Sjhibbits FM_PCD_KG_KGAR_GO | 2749296177Sjhibbits FM_PCD_KG_KGAR_READ | 2750296177Sjhibbits FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY | 2751296177Sjhibbits DUMMY_PORT_ID | 2752296177Sjhibbits FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT); 2753296177Sjhibbits 2754296177Sjhibbits} 2755296177Sjhibbits 2756296177Sjhibbits 2757296177Sjhibbitsuint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId) 2758296177Sjhibbits{ 2759296177Sjhibbits return (uint32_t)(FM_PCD_KG_KGAR_GO | 2760296177Sjhibbits FM_PCD_KG_KGAR_WRITE | 2761296177Sjhibbits FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | 2762296177Sjhibbits DUMMY_PORT_ID | 2763296177Sjhibbits ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | 2764296177Sjhibbits FM_PCD_KG_KGAR_WSEL_MASK); 2765296177Sjhibbits 2766296177Sjhibbits 2767296177Sjhibbits /* if we ever want to write 1 by 1, use: 2768296177Sjhibbits sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));*/ 2769296177Sjhibbits} 2770296177Sjhibbits 2771296177Sjhibbitsuint32_t FmPcdKgBuildReadClsPlanBlockActionReg(uint8_t grpId) 2772296177Sjhibbits{ 2773296177Sjhibbits return (uint32_t)(FM_PCD_KG_KGAR_GO | 2774296177Sjhibbits FM_PCD_KG_KGAR_READ | 2775296177Sjhibbits FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | 2776296177Sjhibbits DUMMY_PORT_ID | 2777296177Sjhibbits ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | 2778296177Sjhibbits FM_PCD_KG_KGAR_WSEL_MASK); 2779296177Sjhibbits 2780296177Sjhibbits 2781296177Sjhibbits /* if we ever want to write 1 by 1, use: 2782296177Sjhibbits sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));*/ 2783296177Sjhibbits} 2784296177Sjhibbits 2785296177Sjhibbitsuint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId) 2786296177Sjhibbits{ 2787296177Sjhibbits 2788296177Sjhibbits return (uint32_t)(FM_PCD_KG_KGAR_GO | 2789296177Sjhibbits FM_PCD_KG_KGAR_WRITE | 2790296177Sjhibbits FM_PCD_KG_KGAR_SEL_PORT_ENTRY | 2791296177Sjhibbits hardwarePortId | 2792296177Sjhibbits FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); 2793296177Sjhibbits} 2794296177Sjhibbits 2795296177Sjhibbitsuint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId) 2796296177Sjhibbits{ 2797296177Sjhibbits 2798296177Sjhibbits return (uint32_t)(FM_PCD_KG_KGAR_GO | 2799296177Sjhibbits FM_PCD_KG_KGAR_READ | 2800296177Sjhibbits FM_PCD_KG_KGAR_SEL_PORT_ENTRY | 2801296177Sjhibbits hardwarePortId | 2802296177Sjhibbits FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); 2803296177Sjhibbits} 2804296177Sjhibbitsuint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId) 2805296177Sjhibbits{ 2806296177Sjhibbits 2807296177Sjhibbits return (uint32_t)(FM_PCD_KG_KGAR_GO | 2808296177Sjhibbits FM_PCD_KG_KGAR_WRITE | 2809296177Sjhibbits FM_PCD_KG_KGAR_SEL_PORT_ENTRY | 2810296177Sjhibbits hardwarePortId | 2811296177Sjhibbits FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP); 2812296177Sjhibbits} 2813296177Sjhibbits 2814296177Sjhibbitsuint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp) 2815296177Sjhibbits{ 2816296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2817296177Sjhibbits 2818296177Sjhibbits return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry; 2819296177Sjhibbits} 2820296177Sjhibbits 2821296177Sjhibbitsuint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp) 2822296177Sjhibbits{ 2823296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2824296177Sjhibbits 2825296177Sjhibbits return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp; 2826296177Sjhibbits} 2827296177Sjhibbits 2828296177Sjhibbitsuint8_t FmPcdKgGetSchemeSwId(t_Handle h_FmPcd, uint8_t schemeHwId) 2829296177Sjhibbits{ 2830296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2831296177Sjhibbits uint8_t i; 2832296177Sjhibbits 2833296177Sjhibbits for(i=0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++) 2834296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeHwId) 2835296177Sjhibbits return i; 2836296177Sjhibbits ASSERT_COND(i!=p_FmPcd->p_FmPcdKg->numOfSchemes); 2837296177Sjhibbits return FM_PCD_KG_NUM_OF_SCHEMES; 2838296177Sjhibbits} 2839296177Sjhibbits 2840296177Sjhibbitsuint8_t FmPcdKgGetNumOfPartitionSchemes(t_Handle h_FmPcd) 2841296177Sjhibbits{ 2842296177Sjhibbits return ((t_FmPcd*)h_FmPcd)->p_FmPcdKg->numOfSchemes; 2843296177Sjhibbits} 2844296177Sjhibbits 2845296177Sjhibbitsuint8_t FmPcdKgGetPhysicalSchemeId(t_Handle h_FmPcd, uint8_t relativeSchemeId) 2846296177Sjhibbits{ 2847296177Sjhibbits return ((t_FmPcd*)h_FmPcd)->p_FmPcdKg->schemesIds[relativeSchemeId]; 2848296177Sjhibbits} 2849296177Sjhibbits 2850296177Sjhibbitsuint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId) 2851296177Sjhibbits{ 2852296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2853296177Sjhibbits uint8_t i; 2854296177Sjhibbits 2855296177Sjhibbits for(i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++) 2856296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId) 2857296177Sjhibbits return i; 2858296177Sjhibbits 2859296177Sjhibbits if(i == p_FmPcd->p_FmPcdKg->numOfSchemes) 2860296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range")); 2861296177Sjhibbits 2862296177Sjhibbits return FM_PCD_KG_NUM_OF_SCHEMES; 2863296177Sjhibbits} 2864296177Sjhibbits 2865296177Sjhibbitst_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction) 2866296177Sjhibbits{ 2867296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2868296177Sjhibbits uint8_t relativeSchemeId, physicalSchemeId; 2869296177Sjhibbits uint32_t tmpKgarReg, tmpReg32 = 0, intFlags; 2870296177Sjhibbits t_Error err; 2871296177Sjhibbits 2872296177Sjhibbits SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); 2873296177Sjhibbits SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); 2874296177Sjhibbits SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); 2875296177Sjhibbits 2876296177Sjhibbits if (p_FmPcd->h_Hc) 2877296177Sjhibbits return FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction); 2878296177Sjhibbits 2879296177Sjhibbits physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); 2880296177Sjhibbits 2881296177Sjhibbits relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); 2882296177Sjhibbits if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 2883296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 2884296177Sjhibbits 2885296177Sjhibbits if (FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE)) 2886296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Lock of the scheme FAILED")); 2887296177Sjhibbits 2888296177Sjhibbits if(!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].pointedOwners || 2889296177Sjhibbits !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction)) 2890296177Sjhibbits { 2891296177Sjhibbits if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) 2892296177Sjhibbits { 2893296177Sjhibbits switch(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine) 2894296177Sjhibbits { 2895296177Sjhibbits case(e_FM_PCD_DONE): 2896296177Sjhibbits if(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME) 2897296177Sjhibbits { 2898296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 2899296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 2900296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 2901296177Sjhibbits if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) 2902296177Sjhibbits { 2903296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 2904296177Sjhibbits RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); 2905296177Sjhibbits } 2906296177Sjhibbits tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode); 2907296177Sjhibbits ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); 2908296177Sjhibbits WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA); 2909296177Sjhibbits /* call indirect command for scheme write */ 2910296177Sjhibbits tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); 2911296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 2912296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 2913296177Sjhibbits } 2914296177Sjhibbits break; 2915296177Sjhibbits case(e_FM_PCD_PLCR): 2916296177Sjhibbits if(!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr || 2917296177Sjhibbits (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs && 2918296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) || 2919296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile) 2920296177Sjhibbits { 2921296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 2922296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared")); 2923296177Sjhibbits } 2924296177Sjhibbits err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction); 2925296177Sjhibbits if(err) 2926296177Sjhibbits { 2927296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 2928296177Sjhibbits RETURN_ERROR(MAJOR, err, NO_MSG); 2929296177Sjhibbits } 2930296177Sjhibbits break; 2931296177Sjhibbits default: 2932296177Sjhibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME")); 2933296177Sjhibbits } 2934296177Sjhibbits } 2935296177Sjhibbits } 2936296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].pointedOwners += 1; 2937296177Sjhibbits p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction |= requiredAction; 2938296177Sjhibbits 2939296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 2940296177Sjhibbits return E_OK; 2941296177Sjhibbits} 2942296177Sjhibbits 2943296177Sjhibbitst_Error FmPcdKgSchemeTryLock(t_Handle h_FmPcd, uint8_t schemeId, bool intr) 2944296177Sjhibbits{ 2945296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2946296177Sjhibbits bool ans; 2947296177Sjhibbits 2948296177Sjhibbits if (intr) 2949296177Sjhibbits ans = TRY_LOCK(NULL, &p_FmPcd->p_FmPcdKg->schemes[schemeId].lock); 2950296177Sjhibbits else 2951296177Sjhibbits ans = TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->p_FmPcdKg->schemes[schemeId].lock); 2952296177Sjhibbits if (ans) 2953296177Sjhibbits return E_OK; 2954296177Sjhibbits return ERROR_CODE(E_BUSY); 2955296177Sjhibbits} 2956296177Sjhibbits 2957296177Sjhibbitsvoid FmPcdKgReleaseSchemeLock(t_Handle h_FmPcd, uint8_t schemeId) 2958296177Sjhibbits{ 2959296177Sjhibbits RELEASE_LOCK(((t_FmPcd*)h_FmPcd)->p_FmPcdKg->schemes[schemeId].lock); 2960296177Sjhibbits} 2961296177Sjhibbits 2962296177Sjhibbitst_Handle FM_PCD_KgSetScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme) 2963296177Sjhibbits{ 2964296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 2965296177Sjhibbits uint32_t tmpReg; 2966296177Sjhibbits t_FmPcdKgInterModuleSchemeRegs schemeRegs; 2967296177Sjhibbits t_FmPcdKgInterModuleSchemeRegs *p_MemRegs; 2968296177Sjhibbits uint8_t i; 2969296177Sjhibbits t_Error err = E_OK; 2970296177Sjhibbits uint32_t tmpKgarReg; 2971296177Sjhibbits uint32_t intFlags; 2972296177Sjhibbits uint8_t physicalSchemeId, relativeSchemeId; 2973296177Sjhibbits 2974296177Sjhibbits SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); 2975296177Sjhibbits SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); 2976296177Sjhibbits SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); 2977296177Sjhibbits 2978296177Sjhibbits if (p_FmPcd->h_Hc) 2979296177Sjhibbits return FmHcPcdKgSetScheme(p_FmPcd->h_Hc, p_Scheme); 2980296177Sjhibbits 2981296177Sjhibbits /* if not called for modification, check first that this scheme is unused */ 2982296177Sjhibbits if(!p_Scheme->modify) 2983296177Sjhibbits { 2984296177Sjhibbits /* check that schemeId is in range */ 2985296177Sjhibbits if(p_Scheme->id.relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) 2986296177Sjhibbits { 2987296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of range")); 2988296177Sjhibbits return NULL; 2989296177Sjhibbits } 2990296177Sjhibbits relativeSchemeId = p_Scheme->id.relativeSchemeId; 2991296177Sjhibbits 2992296177Sjhibbits if (FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE)) 2993296177Sjhibbits return NULL; 2994296177Sjhibbits 2995296177Sjhibbits physicalSchemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId]; 2996296177Sjhibbits 2997296177Sjhibbits /* read specified scheme into scheme registers */ 2998296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 2999296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 3000296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 3001296177Sjhibbits tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode); 3002296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3003296177Sjhibbits 3004296177Sjhibbits if (tmpReg & KG_SCH_MODE_EN) 3005296177Sjhibbits { 3006296177Sjhibbits REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, 3007296177Sjhibbits ("Scheme %d(phys %d) is already used", relativeSchemeId, physicalSchemeId)); 3008296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 3009296177Sjhibbits return NULL; 3010296177Sjhibbits } 3011296177Sjhibbits } 3012296177Sjhibbits else 3013296177Sjhibbits { 3014296177Sjhibbits SANITY_CHECK_RETURN_VALUE(p_Scheme->id.h_Scheme, E_INVALID_HANDLE, NULL); 3015296177Sjhibbits 3016296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 3017296177Sjhibbits physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1); 3018296177Sjhibbits relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); 3019296177Sjhibbits 3020296177Sjhibbits /* check that schemeId is in range */ 3021296177Sjhibbits if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 3022296177Sjhibbits { 3023296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 3024296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3025296177Sjhibbits return NULL; 3026296177Sjhibbits } 3027296177Sjhibbits 3028296177Sjhibbits err = FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, TRUE); 3029296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3030296177Sjhibbits if (err) 3031296177Sjhibbits return NULL; 3032296177Sjhibbits } 3033296177Sjhibbits 3034296177Sjhibbits err = FmPcdKgBuildScheme(h_FmPcd, p_Scheme, &schemeRegs); 3035296177Sjhibbits if(err) 3036296177Sjhibbits { 3037296177Sjhibbits REPORT_ERROR(MAJOR, err, NO_MSG); 3038296177Sjhibbits FmPcdKgInvalidateSchemeSw(h_FmPcd, relativeSchemeId); 3039296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 3040296177Sjhibbits return NULL; 3041296177Sjhibbits } 3042296177Sjhibbits 3043296177Sjhibbits /* configure all 21 scheme registers */ 3044296177Sjhibbits p_MemRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs; 3045296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 3046296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc); 3047296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs); 3048296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode); 3049296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv); 3050296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0); 3051296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1); 3052296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv); 3053296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc); 3054296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch); 3055296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl); 3056296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc); 3057296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc); 3058296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb); 3059296177Sjhibbits for(i=0 ; i<FM_PCD_KG_NUM_OF_GENERIC_REGS ; i++) 3060296177Sjhibbits WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]); 3061296177Sjhibbits 3062296177Sjhibbits /* call indirect command for scheme write */ 3063296177Sjhibbits tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_Scheme->schemeCounter.update); 3064296177Sjhibbits 3065296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 3066296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3067296177Sjhibbits 3068296177Sjhibbits FmPcdKgValidateSchemeSw(h_FmPcd, relativeSchemeId); 3069296177Sjhibbits 3070296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 3071296177Sjhibbits 3072296177Sjhibbits return UINT_TO_PTR((uint64_t)physicalSchemeId+1); 3073296177Sjhibbits} 3074296177Sjhibbits 3075296177Sjhibbitst_Error FM_PCD_KgDeleteScheme(t_Handle h_FmPcd, t_Handle h_Scheme) 3076296177Sjhibbits{ 3077296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 3078296177Sjhibbits uint8_t physicalSchemeId; 3079296177Sjhibbits uint32_t tmpKgarReg, intFlags; 3080296177Sjhibbits t_Error err = E_OK; 3081296177Sjhibbits uint8_t relativeSchemeId; 3082296177Sjhibbits 3083296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); 3084296177Sjhibbits SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); 3085296177Sjhibbits SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); 3086296177Sjhibbits 3087296177Sjhibbits if (p_FmPcd->h_Hc) 3088296177Sjhibbits return FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme); 3089296177Sjhibbits 3090296177Sjhibbits physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); 3091296177Sjhibbits relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); 3092296177Sjhibbits 3093296177Sjhibbits if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) 3094296177Sjhibbits RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 3095296177Sjhibbits 3096296177Sjhibbits if ((err = FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE)) != E_OK) 3097296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 3098296177Sjhibbits 3099296177Sjhibbits /* check that no port is bound to this scheme */ 3100296177Sjhibbits err = FmPcdKgCheckInvalidateSchemeSw(h_FmPcd, relativeSchemeId); 3101296177Sjhibbits if(err) 3102296177Sjhibbits RETURN_ERROR(MINOR, err, NO_MSG); 3103296177Sjhibbits 3104296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 3105296177Sjhibbits /* clear mode register, including enable bit */ 3106296177Sjhibbits WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode, 0); 3107296177Sjhibbits 3108296177Sjhibbits /* call indirect command for scheme write */ 3109296177Sjhibbits tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); 3110296177Sjhibbits 3111296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 3112296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3113296177Sjhibbits 3114296177Sjhibbits FmPcdKgInvalidateSchemeSw(h_FmPcd, relativeSchemeId); 3115296177Sjhibbits 3116296177Sjhibbits RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock); 3117296177Sjhibbits 3118296177Sjhibbits return E_OK; 3119296177Sjhibbits} 3120296177Sjhibbits 3121296177Sjhibbitsuint32_t FM_PCD_KgGetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme) 3122296177Sjhibbits{ 3123296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 3124296177Sjhibbits uint32_t tmpKgarReg, spc, intFlags; 3125296177Sjhibbits uint8_t physicalSchemeId; 3126296177Sjhibbits 3127296177Sjhibbits SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); 3128296177Sjhibbits SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); 3129296177Sjhibbits SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); 3130296177Sjhibbits 3131296177Sjhibbits if (p_FmPcd->h_Hc) 3132296177Sjhibbits return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme); 3133296177Sjhibbits 3134296177Sjhibbits physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); 3135296177Sjhibbits 3136296177Sjhibbits if(FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) 3137296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 3138296177Sjhibbits 3139296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 3140296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 3141296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 3142296177Sjhibbits if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) 3143296177Sjhibbits REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); 3144296177Sjhibbits spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_spc); 3145296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3146296177Sjhibbits 3147296177Sjhibbits return spc; 3148296177Sjhibbits} 3149296177Sjhibbits 3150296177Sjhibbitst_Error FM_PCD_KgSetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t value) 3151296177Sjhibbits{ 3152296177Sjhibbits t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; 3153296177Sjhibbits uint32_t tmpKgarReg, intFlags; 3154296177Sjhibbits uint8_t physicalSchemeId; 3155296177Sjhibbits 3156296177Sjhibbits SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); 3157296177Sjhibbits SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); 3158296177Sjhibbits SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); 3159296177Sjhibbits 3160296177Sjhibbits if (p_FmPcd->h_Hc) 3161296177Sjhibbits return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value); 3162296177Sjhibbits 3163296177Sjhibbits physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1); 3164296177Sjhibbits /* check that schemeId is in range */ 3165296177Sjhibbits if(FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) 3166296177Sjhibbits REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); 3167296177Sjhibbits 3168296177Sjhibbits /* read specified scheme into scheme registers */ 3169296177Sjhibbits tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); 3170296177Sjhibbits intFlags = FmPcdLock(p_FmPcd); 3171296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 3172296177Sjhibbits if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) 3173296177Sjhibbits { 3174296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3175296177Sjhibbits RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); 3176296177Sjhibbits } 3177296177Sjhibbits 3178296177Sjhibbits /* change counter value */ 3179296177Sjhibbits WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_spc, value); 3180296177Sjhibbits 3181296177Sjhibbits /* call indirect command for scheme write */ 3182296177Sjhibbits tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); 3183296177Sjhibbits 3184296177Sjhibbits WriteKgarWait(p_FmPcd, tmpKgarReg); 3185296177Sjhibbits FmPcdUnlock(p_FmPcd, intFlags); 3186296177Sjhibbits 3187296177Sjhibbits return E_OK; 3188296177Sjhibbits} 3189296177Sjhibbits 3190