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