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