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_manip.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_manip.c
36
37
@Description FM PCD manip ...
38
*//***************************************************************************/
39
#include "std_ext.h"
40
#include "error_ext.h"
41
#include "string_ext.h"
42
#include "debug_ext.h"
43
#include "fm_pcd_ext.h"
44
#include "fm_port_ext.h"
45
#include "fm_muram_ext.h"
46
#include "memcpy_ext.h"
47
48
#include "fm_common.h"
49
#include "fm_hc.h"
50
#include "fm_manip.h"
51
52
/****************************************/
53
/* static functions */
54
/****************************************/
55
static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
56
{
57
t_FmPcdManip *p_CurManip = p_Manip;
58
59
if (!MANIP_IS_UNIFIED(p_Manip))
60
p_CurManip = p_Manip;
61
else
62
{
63
/* go to first unified */
64
while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
65
p_CurManip = p_CurManip->h_PrevManip;
66
}
67
68
switch (manipInfo)
69
{
70
case (e_MANIP_HMCT):
71
return p_CurManip->p_Hmct;
72
case (e_MANIP_HMTD):
73
return p_CurManip->h_Ad;
74
case (e_MANIP_HANDLER_TABLE_OWNER):
75
return (t_Handle)p_CurManip;
76
default:
77
return NULL;
78
}
79
}
80
81
static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
82
{
83
uint16_t size = 0;
84
t_FmPcdManip *p_CurManip = p_Manip;
85
86
if (!MANIP_IS_UNIFIED(p_Manip))
87
return p_Manip->tableSize;
88
89
/* accumulate sizes, starting with the first node */
90
while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
91
p_CurManip = p_CurManip->h_PrevManip;
92
93
while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
94
{
95
size += p_CurManip->tableSize;
96
p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
97
}
98
size += p_CurManip->tableSize; /* add last size */
99
100
return (size);
101
}
102
103
static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
104
{
105
uint16_t size = 0;
106
t_FmPcdManip *p_CurManip = p_Manip;
107
108
if (!MANIP_IS_UNIFIED(p_Manip))
109
return p_Manip->dataSize;
110
111
/* accumulate sizes, starting with the first node */
112
while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
113
p_CurManip = p_CurManip->h_PrevManip;
114
115
while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
116
{
117
size += p_CurManip->dataSize;
118
p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
119
}
120
size += p_CurManip->dataSize; /* add last size */
121
122
return (size);
123
}
124
125
static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
126
uint16_t *p_TableSize, uint8_t *p_DataSize)
127
{
128
uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
129
130
if (p_FmPcdManipParams->u.hdr.rmv)
131
{
132
switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
133
{
134
case (e_FM_PCD_MANIP_RMV_GENERIC):
135
tableSize += HMCD_BASIC_SIZE;
136
break;
137
case (e_FM_PCD_MANIP_RMV_BY_HDR):
138
switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
139
{
140
case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
141
#if (DPAA_VERSION >= 11)
142
case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
143
case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
144
#endif /* (DPAA_VERSION >= 11) */
145
tableSize += HMCD_BASIC_SIZE;
146
break;
147
default:
148
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
149
("Unknown byHdr.type"));
150
}
151
break;
152
default:
153
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
154
("Unknown rmvParams.type"));
155
}
156
}
157
158
if (p_FmPcdManipParams->u.hdr.insrt)
159
{
160
switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
161
{
162
case (e_FM_PCD_MANIP_INSRT_GENERIC):
163
remain =
164
(uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
165
% 4);
166
if (remain)
167
localDataSize =
168
(uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
169
+ 4 - remain);
170
else
171
localDataSize =
172
p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
173
tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
174
break;
175
case (e_FM_PCD_MANIP_INSRT_BY_HDR):
176
{
177
switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
178
{
179
180
case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
181
tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
182
switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
183
{
184
case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
185
case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
186
dataSize +=
187
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
188
break;
189
default:
190
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
191
}
192
break;
193
#if (DPAA_VERSION >= 11)
194
case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
195
tableSize +=
196
(HMCD_BASIC_SIZE + HMCD_PTR_SIZE
197
+ HMCD_PARAM_SIZE
198
+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
199
dataSize += 2;
200
break;
201
202
case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
203
case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
204
tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
205
206
break;
207
208
case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
209
tableSize +=
210
(HMCD_BASIC_SIZE
211
+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
212
break;
213
#endif /* (DPAA_VERSION >= 11) */
214
default:
215
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
216
("Unknown byHdr.type"));
217
}
218
}
219
break;
220
default:
221
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
222
("Unknown insrtParams.type"));
223
}
224
}
225
226
if (p_FmPcdManipParams->u.hdr.fieldUpdate)
227
{
228
switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
229
{
230
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
231
tableSize += HMCD_BASIC_SIZE;
232
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
233
== e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
234
{
235
tableSize += HMCD_PTR_SIZE;
236
dataSize += DSCP_TO_VLAN_TABLE_SIZE;
237
}
238
break;
239
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
240
tableSize += HMCD_BASIC_SIZE;
241
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
242
& HDR_MANIP_IPV4_ID)
243
{
244
tableSize += HMCD_PARAM_SIZE;
245
dataSize += 2;
246
}
247
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
248
& HDR_MANIP_IPV4_SRC)
249
tableSize += HMCD_IPV4_ADDR_SIZE;
250
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
251
& HDR_MANIP_IPV4_DST)
252
tableSize += HMCD_IPV4_ADDR_SIZE;
253
break;
254
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
255
tableSize += HMCD_BASIC_SIZE;
256
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
257
& HDR_MANIP_IPV6_SRC)
258
tableSize += HMCD_IPV6_ADDR_SIZE;
259
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
260
& HDR_MANIP_IPV6_DST)
261
tableSize += HMCD_IPV6_ADDR_SIZE;
262
break;
263
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
264
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
265
== HDR_MANIP_TCP_UDP_CHECKSUM)
266
/* we implement this case with the update-checksum descriptor */
267
tableSize += HMCD_BASIC_SIZE;
268
else
269
/* we implement this case with the TCP/UDP-update descriptor */
270
tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
271
break;
272
default:
273
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
274
("Unknown fieldUpdateParams.type"));
275
}
276
}
277
278
if (p_FmPcdManipParams->u.hdr.custom)
279
{
280
switch (p_FmPcdManipParams->u.hdr.customParams.type)
281
{
282
case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
283
{
284
tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
285
dataSize +=
286
p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
287
if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
288
== e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
289
&& (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
290
dataSize += 2;
291
}
292
break;
293
case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
294
tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
295
break;
296
default:
297
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
298
("Unknown customParams.type"));
299
}
300
}
301
302
*p_TableSize = tableSize;
303
*p_DataSize = dataSize;
304
305
return E_OK;
306
}
307
308
static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
309
uint8_t *parseArrayOffset)
310
{
311
e_NetHeaderType hdr = p_HdrInfo->hdr;
312
e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
313
bool byField = p_HdrInfo->byField;
314
t_FmPcdFields field;
315
316
if (byField)
317
field = p_HdrInfo->fullField;
318
319
if (byField)
320
{
321
switch (hdr)
322
{
323
case (HEADER_TYPE_ETH):
324
switch (field.eth)
325
{
326
case (NET_HEADER_FIELD_ETH_TYPE):
327
*parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
328
break;
329
default:
330
RETURN_ERROR(
331
MAJOR,
332
E_NOT_SUPPORTED,
333
("Header manipulation of the type Ethernet with this field not supported"));
334
}
335
break;
336
case (HEADER_TYPE_VLAN):
337
switch (field.vlan)
338
{
339
case (NET_HEADER_FIELD_VLAN_TCI):
340
if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
341
|| (hdrIndex == e_FM_PCD_HDR_INDEX_1))
342
*parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
343
else
344
if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
345
*parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
346
break;
347
default:
348
RETURN_ERROR(
349
MAJOR,
350
E_NOT_SUPPORTED,
351
("Header manipulation of the type VLAN with this field not supported"));
352
}
353
break;
354
default:
355
RETURN_ERROR(
356
MAJOR,
357
E_NOT_SUPPORTED,
358
("Header manipulation of this header by field not supported"));
359
}
360
}
361
else
362
{
363
switch (hdr)
364
{
365
case (HEADER_TYPE_ETH):
366
*parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
367
break;
368
case (HEADER_TYPE_USER_DEFINED_SHIM1):
369
*parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
370
break;
371
case (HEADER_TYPE_USER_DEFINED_SHIM2):
372
*parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
373
break;
374
case (HEADER_TYPE_LLC_SNAP):
375
*parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
376
break;
377
case (HEADER_TYPE_PPPoE):
378
*parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
379
break;
380
case (HEADER_TYPE_MPLS):
381
if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
382
|| (hdrIndex == e_FM_PCD_HDR_INDEX_1))
383
*parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
384
else
385
if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
386
*parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
387
break;
388
case (HEADER_TYPE_IPv4):
389
case (HEADER_TYPE_IPv6):
390
if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
391
|| (hdrIndex == e_FM_PCD_HDR_INDEX_1))
392
*parseArrayOffset = CC_PC_PR_IP1_OFFSET;
393
else
394
if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
395
*parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
396
break;
397
case (HEADER_TYPE_MINENCAP):
398
*parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
399
break;
400
case (HEADER_TYPE_GRE):
401
*parseArrayOffset = CC_PC_PR_GRE_OFFSET;
402
break;
403
case (HEADER_TYPE_TCP):
404
case (HEADER_TYPE_UDP):
405
case (HEADER_TYPE_IPSEC_AH):
406
case (HEADER_TYPE_IPSEC_ESP):
407
case (HEADER_TYPE_DCCP):
408
case (HEADER_TYPE_SCTP):
409
*parseArrayOffset = CC_PC_PR_L4_OFFSET;
410
break;
411
case (HEADER_TYPE_CAPWAP):
412
case (HEADER_TYPE_CAPWAP_DTLS):
413
*parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
414
break;
415
default:
416
RETURN_ERROR(
417
MAJOR,
418
E_NOT_SUPPORTED,
419
("Header manipulation of this header is not supported"));
420
}
421
}
422
return E_OK;
423
}
424
425
static t_Error BuildHmct(t_FmPcdManip *p_Manip,
426
t_FmPcdManipParams *p_FmPcdManipParams,
427
uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
428
{
429
uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
430
uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
431
uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
432
p_DestData;
433
t_Handle h_FmPcd = p_Manip->h_FmPcd;
434
uint8_t j = 0;
435
436
if (p_FmPcdManipParams->u.hdr.rmv)
437
{
438
if (p_FmPcdManipParams->u.hdr.rmvParams.type
439
== e_FM_PCD_MANIP_RMV_GENERIC)
440
{
441
/* initialize HMCD */
442
tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
443
/* tmp, should be conditional */
444
tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
445
<< HMCD_RMV_OFFSET_SHIFT;
446
tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
447
<< HMCD_RMV_SIZE_SHIFT;
448
}
449
else
450
if (p_FmPcdManipParams->u.hdr.rmvParams.type
451
== e_FM_PCD_MANIP_RMV_BY_HDR)
452
{
453
switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
454
{
455
case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
456
{
457
uint8_t hmcdOpt;
458
459
/* initialize HMCD */
460
tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
461
462
switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
463
{
464
case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
465
hmcdOpt = HMCD_RMV_L2_ETHERNET;
466
break;
467
case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
468
hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
469
break;
470
case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
471
hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
472
break;
473
case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
474
hmcdOpt = HMCD_RMV_L2_MPLS;
475
break;
476
case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
477
hmcdOpt = HMCD_RMV_L2_PPPOE;
478
break;
479
default:
480
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
481
}
482
tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
483
break;
484
}
485
#if (DPAA_VERSION >= 11)
486
case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
487
tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
488
<< HMCD_OC_SHIFT;
489
break;
490
case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
491
{
492
uint8_t prsArrayOffset;
493
t_Error err = E_OK;
494
495
tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
496
<< HMCD_OC_SHIFT;
497
498
err =
499
GetPrOffsetByHeaderOrField(
500
&p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
501
&prsArrayOffset);
502
ASSERT_COND(!err);
503
/* was previously checked */
504
505
tmpReg |= ((uint32_t)prsArrayOffset << 16);
506
}
507
break;
508
#endif /* (DPAA_VERSION >= 11) */
509
default:
510
RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
511
("manip header remove by hdr type!"));
512
}
513
}
514
515
WRITE_UINT32(*p_TmpHmct, tmpReg);
516
/* save a pointer to the "last" indication word */
517
p_Last = p_TmpHmct;
518
/* advance to next command */
519
p_TmpHmct += HMCD_BASIC_SIZE / 4;
520
}
521
522
if (p_FmPcdManipParams->u.hdr.insrt)
523
{
524
if (p_FmPcdManipParams->u.hdr.insrtParams.type
525
== e_FM_PCD_MANIP_INSRT_GENERIC)
526
{
527
/* initialize HMCD */
528
if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
529
tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
530
<< HMCD_OC_SHIFT;
531
else
532
tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
533
534
tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
535
<< HMCD_INSRT_OFFSET_SHIFT;
536
tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
537
<< HMCD_INSRT_SIZE_SHIFT;
538
539
size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
540
p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
541
542
WRITE_UINT32(*p_TmpHmct, tmpReg);
543
/* save a pointer to the "last" indication word */
544
p_Last = p_TmpHmct;
545
546
p_TmpHmct += HMCD_BASIC_SIZE / 4;
547
548
/* initialize data to be inserted */
549
/* if size is not a multiple of 4, padd with 0's */
550
origSize = size;
551
remain = (uint8_t)(size % 4);
552
if (remain)
553
{
554
size += (uint8_t)(4 - remain);
555
p_LocalData = (uint32_t *)XX_Malloc(size);
556
memset((uint8_t *)p_LocalData, 0, size);
557
memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
558
}
559
else
560
p_LocalData = (uint32_t*)p_UsrData;
561
562
/* initialize data and advance pointer to next command */
563
MemCpy8(p_TmpHmct, p_LocalData, size);
564
p_TmpHmct += size / sizeof(uint32_t);
565
566
if (remain)
567
XX_Free(p_LocalData);
568
}
569
570
else
571
if (p_FmPcdManipParams->u.hdr.insrtParams.type
572
== e_FM_PCD_MANIP_INSRT_BY_HDR)
573
{
574
switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
575
{
576
case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
577
{
578
uint8_t hmcdOpt;
579
580
/* initialize HMCD */
581
tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
582
<< HMCD_OC_SHIFT;
583
584
switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
585
{
586
case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
587
if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
588
hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
589
else
590
hmcdOpt = HMCD_INSRT_L2_MPLS;
591
break;
592
case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
593
hmcdOpt = HMCD_INSRT_L2_PPPOE;
594
break;
595
default:
596
RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
597
}
598
tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
599
600
WRITE_UINT32(*p_TmpHmct, tmpReg);
601
/* save a pointer to the "last" indication word */
602
p_Last = p_TmpHmct;
603
604
p_TmpHmct += HMCD_BASIC_SIZE / 4;
605
606
/* set size and pointer of user's data */
607
size =
608
(uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
609
610
ASSERT_COND(p_TmpData);
611
MemCpy8(
612
p_TmpData,
613
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
614
size);
615
tmpReg =
616
(size << HMCD_INSRT_L2_SIZE_SHIFT)
617
| (uint32_t)(XX_VirtToPhys(p_TmpData)
618
- (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
619
WRITE_UINT32(*p_TmpHmct, tmpReg);
620
p_TmpHmct += HMCD_PTR_SIZE / 4;
621
p_TmpData += size;
622
}
623
break;
624
#if (DPAA_VERSION >= 11)
625
case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
626
tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
627
<< HMCD_OC_SHIFT;
628
if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
629
tmpReg |= HMCD_IP_L4_CS_CALC;
630
if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
631
== e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
632
tmpReg |= HMCD_IP_OR_QOS;
633
tmpReg |=
634
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
635
& HMCD_IP_LAST_PID_MASK;
636
tmpReg |=
637
((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
638
<< HMCD_IP_SIZE_SHIFT)
639
& HMCD_IP_SIZE_MASK);
640
if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
641
tmpReg |= HMCD_IP_DF_MODE;
642
643
WRITE_UINT32(*p_TmpHmct, tmpReg);
644
645
/* save a pointer to the "last" indication word */
646
p_Last = p_TmpHmct;
647
648
p_TmpHmct += HMCD_BASIC_SIZE / 4;
649
650
/* set IP id */
651
ASSERT_COND(p_TmpData);
652
WRITE_UINT16(
653
*(uint16_t*)p_TmpData,
654
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
655
WRITE_UINT32(
656
*p_TmpHmct,
657
(uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
658
p_TmpData += 2;
659
p_TmpHmct += HMCD_PTR_SIZE / 4;
660
661
WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
662
p_TmpHmct += HMCD_PARAM_SIZE / 4;
663
664
MemCpy8(
665
p_TmpHmct,
666
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
667
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
668
p_TmpHmct +=
669
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
670
/ 4;
671
break;
672
case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
673
tmpReg = HMCD_INSRT_UDP_LITE;
674
case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
675
tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
676
<< HMCD_OC_SHIFT;
677
678
WRITE_UINT32(*p_TmpHmct, tmpReg);
679
680
/* save a pointer to the "last" indication word */
681
p_Last = p_TmpHmct;
682
683
p_TmpHmct += HMCD_BASIC_SIZE / 4;
684
685
MemCpy8(
686
p_TmpHmct,
687
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
688
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
689
p_TmpHmct +=
690
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
691
/ 4;
692
break;
693
case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
694
tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
695
<< HMCD_OC_SHIFT;
696
tmpReg |= HMCD_CAPWAP_INSRT;
697
698
WRITE_UINT32(*p_TmpHmct, tmpReg);
699
700
/* save a pointer to the "last" indication word */
701
p_Last = p_TmpHmct;
702
703
p_TmpHmct += HMCD_BASIC_SIZE / 4;
704
705
MemCpy8(
706
p_TmpHmct,
707
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
708
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
709
p_TmpHmct +=
710
p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
711
/ 4;
712
break;
713
#endif /* (DPAA_VERSION >= 11) */
714
default:
715
RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
716
("manip header insert by header type!"));
717
718
}
719
}
720
}
721
722
if (p_FmPcdManipParams->u.hdr.fieldUpdate)
723
{
724
switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
725
{
726
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
727
/* set opcode */
728
tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
729
<< HMCD_OC_SHIFT;
730
731
/* set mode & table pointer */
732
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
733
== e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
734
{
735
/* set Mode */
736
tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
737
<< HMCD_VLAN_PRI_REP_MODE_SHIFT;
738
/* set VPRI default */
739
tmpReg |=
740
p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
741
WRITE_UINT32(*p_TmpHmct, tmpReg);
742
/* save a pointer to the "last" indication word */
743
p_Last = p_TmpHmct;
744
/* write the table pointer into the Manip descriptor */
745
p_TmpHmct += HMCD_BASIC_SIZE / 4;
746
747
tmpReg = 0;
748
ASSERT_COND(p_TmpData);
749
for (i = 0; i < HMCD_DSCP_VALUES; i++)
750
{
751
/* first we build from each 8 values a 32bit register */
752
tmpReg |=
753
(p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
754
<< (32 - 4 * (j + 1));
755
j++;
756
/* Than we write this register to the next table word
757
* (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
758
if ((i % 8) == 7)
759
{
760
WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
761
tmpReg);
762
tmpReg = 0;
763
j = 0;
764
}
765
}
766
767
WRITE_UINT32(
768
*p_TmpHmct,
769
(uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
770
p_TmpHmct += HMCD_PTR_SIZE / 4;
771
772
p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
773
}
774
else
775
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
776
== e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
777
{
778
/* set Mode */
779
/* line commented out as it has no-side-effect ('0' value). */
780
/*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
781
/* set VPRI parameter */
782
tmpReg |=
783
p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
784
WRITE_UINT32(*p_TmpHmct, tmpReg);
785
/* save a pointer to the "last" indication word */
786
p_Last = p_TmpHmct;
787
p_TmpHmct += HMCD_BASIC_SIZE / 4;
788
}
789
break;
790
791
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
792
/* set opcode */
793
tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
794
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
795
& HDR_MANIP_IPV4_TTL)
796
tmpReg |= HMCD_IPV4_UPDATE_TTL;
797
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
798
& HDR_MANIP_IPV4_TOS)
799
{
800
tmpReg |= HMCD_IPV4_UPDATE_TOS;
801
tmpReg |=
802
p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
803
<< HMCD_IPV4_UPDATE_TOS_SHIFT;
804
}
805
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
806
& HDR_MANIP_IPV4_ID)
807
tmpReg |= HMCD_IPV4_UPDATE_ID;
808
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
809
& HDR_MANIP_IPV4_SRC)
810
tmpReg |= HMCD_IPV4_UPDATE_SRC;
811
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
812
& HDR_MANIP_IPV4_DST)
813
tmpReg |= HMCD_IPV4_UPDATE_DST;
814
/* write the first 4 bytes of the descriptor */
815
WRITE_UINT32(*p_TmpHmct, tmpReg);
816
/* save a pointer to the "last" indication word */
817
p_Last = p_TmpHmct;
818
819
p_TmpHmct += HMCD_BASIC_SIZE / 4;
820
821
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
822
& HDR_MANIP_IPV4_ID)
823
{
824
ASSERT_COND(p_TmpData);
825
WRITE_UINT16(
826
*(uint16_t*)p_TmpData,
827
p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
828
WRITE_UINT32(
829
*p_TmpHmct,
830
(uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
831
p_TmpData += 2;
832
p_TmpHmct += HMCD_PTR_SIZE / 4;
833
}
834
835
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
836
& HDR_MANIP_IPV4_SRC)
837
{
838
WRITE_UINT32(
839
*p_TmpHmct,
840
p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
841
p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
842
}
843
844
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
845
& HDR_MANIP_IPV4_DST)
846
{
847
WRITE_UINT32(
848
*p_TmpHmct,
849
p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
850
p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
851
}
852
break;
853
854
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
855
/* set opcode */
856
tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
857
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
858
& HDR_MANIP_IPV6_HL)
859
tmpReg |= HMCD_IPV6_UPDATE_HL;
860
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
861
& HDR_MANIP_IPV6_TC)
862
{
863
tmpReg |= HMCD_IPV6_UPDATE_TC;
864
tmpReg |=
865
p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
866
<< HMCD_IPV6_UPDATE_TC_SHIFT;
867
}
868
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
869
& HDR_MANIP_IPV6_SRC)
870
tmpReg |= HMCD_IPV6_UPDATE_SRC;
871
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
872
& HDR_MANIP_IPV6_DST)
873
tmpReg |= HMCD_IPV6_UPDATE_DST;
874
/* write the first 4 bytes of the descriptor */
875
WRITE_UINT32(*p_TmpHmct, tmpReg);
876
/* save a pointer to the "last" indication word */
877
p_Last = p_TmpHmct;
878
879
p_TmpHmct += HMCD_BASIC_SIZE / 4;
880
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
881
& HDR_MANIP_IPV6_SRC)
882
{
883
for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
884
{
885
memcpy(&tmp_ipv6_addr,
886
&p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
887
sizeof(uint32_t));
888
WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
889
p_TmpHmct += HMCD_PTR_SIZE / 4;
890
}
891
}
892
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
893
& HDR_MANIP_IPV6_DST)
894
{
895
for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
896
{
897
memcpy(&tmp_ipv6_addr,
898
&p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
899
sizeof(uint32_t));
900
WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
901
p_TmpHmct += HMCD_PTR_SIZE / 4;
902
}
903
}
904
break;
905
906
case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
907
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
908
== HDR_MANIP_TCP_UDP_CHECKSUM)
909
{
910
/* we implement this case with the update-checksum descriptor */
911
/* set opcode */
912
tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
913
<< HMCD_OC_SHIFT;
914
/* write the first 4 bytes of the descriptor */
915
WRITE_UINT32(*p_TmpHmct, tmpReg);
916
/* save a pointer to the "last" indication word */
917
p_Last = p_TmpHmct;
918
919
p_TmpHmct += HMCD_BASIC_SIZE / 4;
920
}
921
else
922
{
923
/* we implement this case with the TCP/UDP update descriptor */
924
/* set opcode */
925
tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
926
<< HMCD_OC_SHIFT;
927
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
928
& HDR_MANIP_TCP_UDP_DST)
929
tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
930
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
931
& HDR_MANIP_TCP_UDP_SRC)
932
tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
933
/* write the first 4 bytes of the descriptor */
934
WRITE_UINT32(*p_TmpHmct, tmpReg);
935
/* save a pointer to the "last" indication word */
936
p_Last = p_TmpHmct;
937
938
p_TmpHmct += HMCD_BASIC_SIZE / 4;
939
940
tmpReg = 0;
941
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
942
& HDR_MANIP_TCP_UDP_SRC)
943
tmpReg |=
944
((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
945
<< HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
946
if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
947
& HDR_MANIP_TCP_UDP_DST)
948
tmpReg |=
949
((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
950
WRITE_UINT32(*p_TmpHmct, tmpReg);
951
p_TmpHmct += HMCD_PTR_SIZE / 4;
952
}
953
break;
954
955
default:
956
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
957
("Unknown fieldUpdateParams.type"));
958
}
959
}
960
961
if (p_FmPcdManipParams->u.hdr.custom)
962
{
963
switch (p_FmPcdManipParams->u.hdr.customParams.type)
964
{
965
case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
966
/* set opcode */
967
tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
968
969
if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
970
tmpReg |= HMCD_IP_REPLACE_TTL_HL;
971
if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
972
== e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
973
/* line commented out as it has no-side-effect ('0' value). */
974
/*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
975
else
976
if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
977
== e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
978
{
979
tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
980
if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
981
tmpReg |= HMCD_IP_REPLACE_ID;
982
}
983
else
984
RETURN_ERROR(
985
MINOR,
986
E_NOT_SUPPORTED,
987
("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
988
989
/* write the first 4 bytes of the descriptor */
990
WRITE_UINT32(*p_TmpHmct, tmpReg);
991
/* save a pointer to the "last" indication word */
992
p_Last = p_TmpHmct;
993
994
p_TmpHmct += HMCD_BASIC_SIZE / 4;
995
996
size =
997
p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
998
ASSERT_COND(p_TmpData);
999
MemCpy8(
1000
p_TmpData,
1001
p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
1002
size);
1003
tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
1004
tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
1005
- (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
1006
WRITE_UINT32(*p_TmpHmct, tmpReg);
1007
p_TmpHmct += HMCD_PTR_SIZE / 4;
1008
p_TmpData += size;
1009
1010
if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
1011
== e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
1012
&& (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
1013
{
1014
WRITE_UINT16(
1015
*(uint16_t*)p_TmpData,
1016
p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
1017
WRITE_UINT32(
1018
*p_TmpHmct,
1019
(uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
1020
p_TmpData += 2;
1021
}
1022
p_TmpHmct += HMCD_PTR_SIZE / 4;
1023
break;
1024
case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
1025
/* set opcode */
1026
tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
1027
tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
1028
tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
1029
tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
1030
if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
1031
tmpReg |= HMCD_GEN_FIELD_MASK_EN;
1032
1033
/* write the first 4 bytes of the descriptor */
1034
WRITE_UINT32(*p_TmpHmct, tmpReg);
1035
/* save a pointer to the "last" indication word */
1036
p_Last = p_TmpHmct;
1037
1038
p_TmpHmct += HMCD_BASIC_SIZE/4;
1039
1040
if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
1041
{
1042
tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
1043
tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
1044
/* write the next 4 bytes of the descriptor */
1045
WRITE_UINT32(*p_TmpHmct, tmpReg);
1046
}
1047
p_TmpHmct += HMCD_PARAM_SIZE/4;
1048
break;
1049
default:
1050
RETURN_ERROR(MINOR, E_INVALID_SELECTION,
1051
("Unknown customParams.type"));
1052
}
1053
}
1054
1055
/* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
1056
the old table and should be freed */
1057
if (p_FmPcdManipParams->h_NextManip
1058
&& (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
1059
&& (MANIP_DONT_REPARSE(p_Manip)))
1060
{
1061
if (new)
1062
{
1063
/* If this is the first time this manip is created we need to free unused memory. If it
1064
* is a dynamic changes case, the memory used is either the CC shadow or the existing
1065
* table - no allocation, no free */
1066
MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
1067
1068
p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
1069
}
1070
}
1071
else
1072
{
1073
ASSERT_COND(p_Last);
1074
/* set the "last" indication on the last command of the current table */
1075
WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
1076
}
1077
1078
return E_OK;
1079
}
1080
1081
static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
1082
t_FmPcdManipParams *p_FmPcdManipParams)
1083
{
1084
t_FmPcdManip *p_CurManip;
1085
t_Error err;
1086
uint32_t nextSize = 0, totalSize;
1087
uint16_t tmpReg;
1088
uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
1089
1090
/* set Manip structure */
1091
1092
p_Manip->dontParseAfterManip =
1093
p_FmPcdManipParams->u.hdr.dontParseAfterManip;
1094
1095
if (p_FmPcdManipParams->h_NextManip)
1096
{ /* Next Header manipulation exists */
1097
p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
1098
1099
if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
1100
nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
1101
+ GetDataSize(p_FmPcdManipParams->h_NextManip));
1102
else /* either parsing is required or next manip is Frag; no table merging. */
1103
p_Manip->cascaded = TRUE;
1104
/* pass up the "cascaded" attribute. The whole chain is cascaded
1105
* if something is cascaded along the way. */
1106
if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
1107
p_Manip->cascaded = TRUE;
1108
}
1109
1110
/* Allocate new table */
1111
/* calculate table size according to manip parameters */
1112
err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
1113
&p_Manip->dataSize);
1114
if (err)
1115
RETURN_ERROR(MINOR, err, NO_MSG);
1116
1117
totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
1118
1119
p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
1120
((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
1121
if (!p_Manip->p_Hmct)
1122
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
1123
1124
if (p_Manip->dataSize)
1125
p_Manip->p_Data =
1126
(uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
1127
1128
/* update shadow size to allow runtime replacement of Header manipulation */
1129
/* The allocated shadow is divided as follows:
1130
0 . . . 16 . . .
1131
--------------------------------
1132
| Shadow | Shadow HMTD |
1133
| HMTD | Match Table |
1134
| (16 bytes) | (maximal size) |
1135
--------------------------------
1136
*/
1137
1138
err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
1139
(uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
1140
if (err != E_OK)
1141
{
1142
FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
1143
RETURN_ERROR(MAJOR, E_NO_MEMORY,
1144
("MURAM allocation for HdrManip node shadow"));
1145
}
1146
1147
if (p_FmPcdManipParams->h_NextManip
1148
&& (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
1149
&& (MANIP_DONT_REPARSE(p_Manip)))
1150
{
1151
p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
1152
e_MANIP_HMCT);
1153
p_CurManip = p_FmPcdManipParams->h_NextManip;
1154
/* Run till the last Manip (which is the first to configure) */
1155
while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
1156
p_CurManip = p_CurManip->h_NextManip;
1157
1158
while (p_CurManip)
1159
{
1160
/* If this is a unified table, point to the part of the table
1161
* which is the relative offset in HMCT.
1162
*/
1163
p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
1164
(p_Manip->tableSize +
1165
(PTR_TO_UINT(p_CurManip->p_Hmct) -
1166
PTR_TO_UINT(p_OldHmct))));
1167
if (p_CurManip->p_Data)
1168
p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
1169
(p_Manip->tableSize +
1170
(PTR_TO_UINT(p_CurManip->p_Data) -
1171
PTR_TO_UINT(p_OldHmct))));
1172
else
1173
p_TmpDataPtr = NULL;
1174
1175
BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
1176
p_TmpDataPtr, FALSE);
1177
/* update old manip table pointer */
1178
MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
1179
MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
1180
1181
p_CurManip = p_CurManip->h_PrevManip;
1182
}
1183
/* We copied the HMCT to create a new large HMCT so we can free the old one */
1184
FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
1185
p_OldHmct);
1186
}
1187
1188
/* Fill table */
1189
err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
1190
p_Manip->p_Data, TRUE);
1191
if (err)
1192
{
1193
FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
1194
RETURN_ERROR(MINOR, err, NO_MSG);
1195
}
1196
1197
/* Build HMTD (table descriptor) */
1198
tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
1199
1200
/* add parseAfterManip */
1201
if (!p_Manip->dontParseAfterManip)
1202
tmpReg |= HMTD_CFG_PRS_AFTER_HM;
1203
1204
/* create cascade */
1205
/*if (p_FmPcdManipParams->h_NextManip
1206
&& (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
1207
if (p_Manip->cascaded)
1208
{
1209
uint16_t nextAd;
1210
/* indicate that there's another HM table descriptor */
1211
tmpReg |= HMTD_CFG_NEXT_AD_EN;
1212
/* get address of next HMTD (table descriptor; h_Ad).
1213
* If the next HMTD was removed due to table unifing, get the address
1214
* of the "next next" as written in the h_Ad of the next h_Manip node.
1215
*/
1216
if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
1217
nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
1218
else
1219
nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
1220
1221
WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
1222
}
1223
1224
WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
1225
WRITE_UINT32(
1226
((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
1227
(uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
1228
1229
WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
1230
1231
if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
1232
{
1233
/* The HMTD of the next Manip is never going to be used */
1234
if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
1235
FM_MURAM_FreeMem(
1236
((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
1237
((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
1238
else
1239
XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
1240
((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
1241
}
1242
1243
return E_OK;
1244
}
1245
1246
static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
1247
t_FmPcdManipParams *p_FmPcdManipParams)
1248
{
1249
uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
1250
uint16_t newSize;
1251
t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
1252
t_Error err;
1253
t_FmPcdManip *p_CurManip = p_Manip;
1254
1255
err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
1256
if (err)
1257
RETURN_ERROR(MINOR, err, NO_MSG);
1258
1259
/* check coherency of new table parameters */
1260
if (newSize > p_Manip->tableSize)
1261
RETURN_ERROR(
1262
MINOR,
1263
E_INVALID_VALUE,
1264
("New Hdr Manip configuration requires larger size than current one (command table)."));
1265
if (newDataSize > p_Manip->dataSize)
1266
RETURN_ERROR(
1267
MINOR,
1268
E_INVALID_VALUE,
1269
("New Hdr Manip configuration requires larger size than current one (data)."));
1270
if (p_FmPcdManipParams->h_NextManip)
1271
RETURN_ERROR(
1272
MINOR, E_INVALID_VALUE,
1273
("New Hdr Manip configuration can not contain h_NextManip."));
1274
if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
1275
RETURN_ERROR(
1276
MINOR,
1277
E_INVALID_VALUE,
1278
("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
1279
if (p_Manip->dontParseAfterManip
1280
!= p_FmPcdManipParams->u.hdr.dontParseAfterManip)
1281
RETURN_ERROR(
1282
MINOR,
1283
E_INVALID_VALUE,
1284
("New Hdr Manip configuration differs in dontParseAfterManip value."));
1285
1286
p_Manip->tableSize = newSize;
1287
p_Manip->dataSize = newDataSize;
1288
1289
/* Build the new table in the shadow */
1290
if (!MANIP_IS_UNIFIED(p_Manip))
1291
{
1292
p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
1293
if (p_Manip->p_Data)
1294
p_TmpDataPtr =
1295
(uint8_t*)PTR_MOVE(p_TmpHmctPtr,
1296
(PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
1297
1298
BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
1299
FALSE);
1300
}
1301
else
1302
{
1303
p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
1304
ASSERT_COND(p_WholeHmct);
1305
1306
/* Run till the last Manip (which is the first to configure) */
1307
while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
1308
p_CurManip = p_CurManip->h_NextManip;
1309
1310
while (p_CurManip)
1311
{
1312
/* If this is a non-head node in a unified table, point to the part of the shadow
1313
* which is the relative offset in HMCT.
1314
* else, point to the beginning of the
1315
* shadow table (we save 16 for the HMTD.
1316
*/
1317
p_TmpHmctPtr =
1318
(uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
1319
(16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
1320
if (p_CurManip->p_Data)
1321
p_TmpDataPtr =
1322
(uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
1323
(16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
1324
1325
BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
1326
p_TmpDataPtr, FALSE);
1327
p_CurManip = p_CurManip->h_PrevManip;
1328
}
1329
}
1330
1331
return E_OK;
1332
}
1333
1334
static t_Error CreateManipActionBackToOrig(
1335
t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
1336
{
1337
uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
1338
t_FmPcdManip *p_CurManip = p_Manip;
1339
1340
/* Build the new table in the shadow */
1341
if (!MANIP_IS_UNIFIED(p_Manip))
1342
BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
1343
FALSE);
1344
else
1345
{
1346
p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
1347
ASSERT_COND(p_WholeHmct);
1348
1349
/* Run till the last Manip (which is the first to configure) */
1350
while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
1351
p_CurManip = p_CurManip->h_NextManip;
1352
1353
while (p_CurManip)
1354
{
1355
/* If this is a unified table, point to the part of the table
1356
* which is the relative offset in HMCT.
1357
*/
1358
p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
1359
p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
1360
1361
BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
1362
p_TmpDataPtr, FALSE);
1363
1364
p_CurManip = p_CurManip->h_PrevManip;
1365
}
1366
}
1367
1368
return E_OK;
1369
}
1370
1371
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
1372
static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
1373
{
1374
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
1375
t_Handle p_Ad;
1376
uint32_t tmpReg32 = 0;
1377
SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
1378
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
1379
1380
switch (p_Manip->opcode)
1381
{
1382
case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
1383
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1384
if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
1385
{
1386
tmpReg32 =
1387
*(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
1388
tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
1389
*(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
1390
tmpReg32;
1391
p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
1392
p_Manip->icOffset = icOffset;
1393
}
1394
else
1395
{
1396
if (p_Manip->icOffset != icOffset)
1397
RETURN_ERROR(
1398
MAJOR,
1399
E_INVALID_VALUE,
1400
("this manipulation was updated previously by different value"););
1401
}
1402
break;
1403
case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
1404
if (p_Manip->h_Frag)
1405
{
1406
if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
1407
{
1408
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1409
tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
1410
tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
1411
WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
1412
p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
1413
p_Manip->icOffset = icOffset;
1414
}
1415
else
1416
{
1417
if (p_Manip->icOffset != icOffset)
1418
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
1419
}
1420
}
1421
break;
1422
}
1423
1424
return E_OK;
1425
}
1426
1427
static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
1428
t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
1429
{
1430
1431
t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
1432
t_FmPortGetSetCcParams fmPortGetSetCcParams;
1433
t_Error err;
1434
uint32_t tmpReg32;
1435
1436
memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
1437
1438
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
1439
SANITY_CHECK_RETURN_ERROR(
1440
(p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
1441
E_INVALID_STATE);
1442
SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
1443
1444
if (p_Manip->updateParams)
1445
{
1446
if ((!(p_Manip->updateParams & OFFSET_OF_PR))
1447
|| (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
1448
RETURN_ERROR(
1449
MAJOR, E_INVALID_STATE,
1450
("in this stage parameters from Port has not be updated"));
1451
1452
fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
1453
fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
1454
fmPortGetSetCcParams.setCcParams.psoSize = 16;
1455
1456
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1457
if (err)
1458
RETURN_ERROR(MAJOR, err, NO_MSG);
1459
if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
1460
RETURN_ERROR(
1461
MAJOR, E_INVALID_STATE,
1462
("Parser result offset wasn't configured previousely"));
1463
#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
1464
ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
1465
#endif
1466
}
1467
else
1468
if (validate)
1469
{
1470
if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
1471
|| (p_Manip->updateParams & OFFSET_OF_PR))
1472
RETURN_ERROR(
1473
MAJOR, E_INVALID_STATE,
1474
("in this stage parameters from Port has be updated"));
1475
fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
1476
fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
1477
fmPortGetSetCcParams.setCcParams.psoSize = 16;
1478
1479
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1480
if (err)
1481
RETURN_ERROR(MAJOR, err, NO_MSG);
1482
if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
1483
RETURN_ERROR(
1484
MAJOR, E_INVALID_STATE,
1485
("Parser result offset wasn't configured previousely"));
1486
1487
}
1488
1489
ASSERT_COND(p_Ad);
1490
1491
if (p_Manip->updateParams & OFFSET_OF_PR)
1492
{
1493
tmpReg32 = 0;
1494
tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
1495
WRITE_UINT32(p_Ad->matchTblPtr,
1496
(GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
1497
p_Manip->updateParams &= ~OFFSET_OF_PR;
1498
p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
1499
}
1500
else
1501
if (validate)
1502
{
1503
tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
1504
if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
1505
RETURN_ERROR(
1506
MAJOR,
1507
E_INVALID_STATE,
1508
("this manipulation was updated previousely by different value"););
1509
}
1510
1511
return E_OK;
1512
}
1513
1514
static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
1515
{
1516
t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
1517
t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
1518
uint32_t tmpReg32 = 0;
1519
1520
SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
1521
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
1522
SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
1523
SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
1524
1525
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
1526
1527
if (p_Manip->updateParams)
1528
{
1529
1530
if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
1531
((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
1532
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
1533
p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
1534
if (!p_SavedManipParams)
1535
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
1536
p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
1537
1538
tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
1539
tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
1540
WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
1541
1542
p_Manip->updateParams &= ~OFFSET_OF_DATA;
1543
p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
1544
}
1545
else if (validate)
1546
{
1547
1548
p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
1549
if (!p_SavedManipParams)
1550
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
1551
if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
1552
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
1553
}
1554
1555
return E_OK;
1556
}
1557
1558
static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
1559
t_FmPcdManip *p_Manip,
1560
t_Handle h_Ad,
1561
bool validate,
1562
t_Handle h_FmTree)
1563
{
1564
t_AdOfTypeContLookup *p_Ad;
1565
t_FmPortGetSetCcParams fmPortGetSetCcParams;
1566
t_Error err;
1567
uint32_t tmpReg32 = 0;
1568
t_FmPcdCcSavedManipParams *p_SavedManipParams;
1569
1570
UNUSED(h_Ad);
1571
1572
SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
1573
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
1574
SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
1575
SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
1576
(p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
1577
1578
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
1579
1580
if (p_Manip->updateParams)
1581
{
1582
if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
1583
((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
1584
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
1585
fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
1586
fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
1587
fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1588
/* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
1589
fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
1590
1591
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1592
if (err)
1593
RETURN_ERROR(MAJOR, err, NO_MSG);
1594
1595
if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1596
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
1597
1598
p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
1599
p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
1600
1601
#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
1602
ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
1603
#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
1604
1605
FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
1606
}
1607
else if (validate)
1608
{
1609
if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
1610
((p_Manip->updateParams & OFFSET_OF_DATA)))
1611
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
1612
fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
1613
fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
1614
fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1615
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1616
if (err)
1617
RETURN_ERROR(MAJOR, err, NO_MSG);
1618
1619
if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1620
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
1621
}
1622
1623
if (p_Manip->updateParams)
1624
{
1625
tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
1626
tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
1627
WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
1628
1629
p_Manip->updateParams &= ~OFFSET_OF_DATA;
1630
p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
1631
p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
1632
}
1633
else if (validate)
1634
{
1635
if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
1636
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
1637
}
1638
1639
return E_OK;
1640
}
1641
1642
static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
1643
t_Handle h_FmPort,
1644
t_FmPcdManip *p_Manip,
1645
t_Handle h_Ad,
1646
bool validate)
1647
{
1648
t_CapwapReasmPram *p_ReassmTbl;
1649
t_Error err;
1650
t_FmPortGetSetCcParams fmPortGetSetCcParams;
1651
uint8_t i = 0;
1652
uint16_t size;
1653
uint32_t tmpReg32;
1654
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
1655
t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
1656
1657
SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
1658
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
1659
SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
1660
SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
1661
SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
1662
SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
1663
1664
if (p_Manip->h_FmPcd != h_FmPcd)
1665
RETURN_ERROR(MAJOR, E_INVALID_STATE,
1666
("handler of PCD previously was initiated by different value"));
1667
1668
UNUSED(h_Ad);
1669
1670
memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
1671
p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
1672
1673
if (p_Manip->updateParams)
1674
{
1675
if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
1676
!(p_Manip->updateParams & OFFSET_OF_DATA) &&
1677
!(p_Manip->updateParams & OFFSET_OF_PR) &&
1678
!(p_Manip->updateParams & HW_PORT_ID)) ||
1679
((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
1680
(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
1681
(p_Manip->shadowUpdateParams & HW_PORT_ID)))
1682
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
1683
1684
fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
1685
fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
1686
fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1687
1688
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1689
if (err)
1690
RETURN_ERROR(MAJOR, err, NO_MSG);
1691
1692
if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
1693
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
1694
if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1695
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
1696
if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
1697
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
1698
#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
1699
ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
1700
#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
1701
}
1702
else if (validate)
1703
{
1704
if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
1705
!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
1706
!(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
1707
!(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
1708
((p_Manip->updateParams & NUM_OF_TASKS) ||
1709
(p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
1710
(p_Manip->updateParams & HW_PORT_ID)))
1711
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
1712
1713
fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
1714
fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
1715
fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
1716
1717
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1718
if (err)
1719
RETURN_ERROR(MAJOR, err, NO_MSG);
1720
1721
if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
1722
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
1723
if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
1724
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
1725
if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
1726
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
1727
}
1728
1729
if (p_Manip->updateParams)
1730
{
1731
if (p_Manip->updateParams & NUM_OF_TASKS)
1732
{
1733
/*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
1734
size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
1735
if (size > 255)
1736
RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
1737
1738
p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
1739
1740
/*p_ReassmFrmDescrIndxPoolTbl*/
1741
p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
1742
(t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1743
(uint32_t)(size + 1),
1744
4);
1745
if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
1746
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
1747
1748
MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
1749
1750
for ( i = 0; i < size; i++)
1751
WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
1752
1753
tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
1754
1755
WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
1756
1757
/*p_ReassmFrmDescrPoolTbl*/
1758
p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
1759
(t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1760
(uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
1761
4);
1762
1763
if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
1764
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
1765
1766
MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
1767
1768
tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
1769
1770
WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
1771
1772
/*p_TimeOutTbl*/
1773
1774
p_Manip->capwapFragParams.p_TimeOutTbl =
1775
(t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1776
(uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
1777
4);
1778
1779
if (!p_Manip->capwapFragParams.p_TimeOutTbl)
1780
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
1781
1782
MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
1783
1784
tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
1785
WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
1786
1787
p_Manip->updateParams &= ~NUM_OF_TASKS;
1788
p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
1789
}
1790
1791
if (p_Manip->updateParams & OFFSET_OF_DATA)
1792
{
1793
p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
1794
tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
1795
tmpReg32|= p_Manip->capwapFragParams.dataOffset;
1796
WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
1797
p_Manip->updateParams &= ~OFFSET_OF_DATA;
1798
p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
1799
}
1800
1801
if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
1802
{
1803
p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
1804
1805
tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
1806
tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
1807
WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
1808
1809
tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
1810
tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
1811
WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
1812
p_Manip->updateParams &= ~OFFSET_OF_PR;
1813
p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
1814
}
1815
else
1816
{
1817
p_Manip->capwapFragParams.prOffset = 0xff;
1818
p_Manip->updateParams &= ~OFFSET_OF_PR;
1819
p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
1820
}
1821
1822
p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
1823
p_Manip->updateParams &= ~HW_PORT_ID;
1824
p_Manip->shadowUpdateParams |= HW_PORT_ID;
1825
1826
/*timeout hc */
1827
ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
1828
ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
1829
ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
1830
ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
1831
return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
1832
}
1833
1834
else if (validate)
1835
{
1836
if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
1837
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
1838
if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
1839
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
1840
1841
if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
1842
{
1843
if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
1844
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
1845
}
1846
else
1847
{
1848
if (p_Manip->capwapFragParams.prOffset != 0xff)
1849
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
1850
}
1851
if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
1852
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
1853
}
1854
1855
return E_OK;
1856
}
1857
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
1858
1859
t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
1860
{
1861
t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
1862
t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
1863
t_Error err = E_OK;
1864
uint8_t result;
1865
uint32_t bitFor1Micro, tsbs, log2num;
1866
1867
ASSERT_COND(p_FmPcd);
1868
ASSERT_COND(h_ReasmCommonPramTbl);
1869
1870
bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
1871
if (bitFor1Micro == 0)
1872
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
1873
1874
bitFor1Micro = 32 - bitFor1Micro;
1875
LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
1876
tsbs = bitFor1Micro - log2num;
1877
1878
ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
1879
h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
1880
ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
1881
ccReassmTimeoutParams.activate = TRUE;
1882
if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
1883
&result)) != E_OK)
1884
RETURN_ERROR(MAJOR, err, NO_MSG);
1885
1886
switch (result)
1887
{
1888
case (0):
1889
return E_OK;
1890
case (1):
1891
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
1892
case (2):
1893
RETURN_ERROR(
1894
MAJOR, E_NO_MEMORY,
1895
("failed to allocate internal buffer from the HC-Port"));
1896
case (3):
1897
RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1898
("'Disable Timeout Task' with invalid IPRCPT"));
1899
case (4):
1900
RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
1901
case (5):
1902
RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
1903
default:
1904
RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1905
}
1906
return E_OK;
1907
}
1908
1909
static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
1910
{
1911
uint32_t tmpReg32 = 0, i, bitFor1Micro;
1912
uint64_t tmpReg64, size;
1913
t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
1914
t_Error err = E_OK;
1915
1916
bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
1917
if (bitFor1Micro == 0)
1918
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
1919
1920
/* Allocation of the Reassembly Common Parameters table. This table is located in the
1921
MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
1922
p_Manip->reassmParams.p_ReassCommonTbl =
1923
(t_ReassCommonTbl *)FM_MURAM_AllocMem(
1924
p_FmPcd->h_FmMuram,
1925
FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
1926
FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
1927
1928
if (!p_Manip->reassmParams.p_ReassCommonTbl)
1929
RETURN_ERROR(MAJOR, E_NO_MEMORY,
1930
("MURAM alloc for Reassembly common parameters table"));
1931
1932
MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
1933
FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
1934
1935
/* Setting the TimeOut Mode.*/
1936
tmpReg32 = 0;
1937
if (p_Manip->reassmParams.timeOutMode
1938
== e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
1939
tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
1940
1941
/* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
1942
In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
1943
tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
1944
WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
1945
tmpReg32);
1946
1947
/* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
1948
size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
1949
1950
/*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
1951
p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
1952
PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1953
(uint32_t)(size * 2),
1954
256));
1955
if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
1956
RETURN_ERROR(
1957
MAJOR, E_NO_MEMORY,
1958
("MURAM alloc for Reassembly frame descriptor indexes pool"));
1959
1960
MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
1961
0, (uint32_t)(size * 2));
1962
1963
/* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
1964
the maximum number of frames that are allowed to be reassembled simultaneously + 128.
1965
The last entry in this pool must contain the index zero*/
1966
for (i = 0; i < (size - 1); i++)
1967
WRITE_UINT16(
1968
*(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
1969
(uint16_t)(i+1));
1970
1971
/* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
1972
tmpReg32 = (uint32_t)(XX_VirtToPhys(
1973
UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
1974
- p_FmPcd->physicalMuramBase);
1975
WRITE_UINT32(
1976
p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
1977
tmpReg32);
1978
1979
/* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
1980
The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
1981
p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
1982
PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
1983
1984
if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
1985
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
1986
1987
MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
1988
(uint32_t)(size * 64));
1989
1990
/* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
1991
tmpReg64 = (uint64_t)(XX_VirtToPhys(
1992
UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
1993
tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
1994
& FM_PCD_MANIP_REASM_LIODN_MASK)
1995
<< (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
1996
tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
1997
& FM_PCD_MANIP_REASM_ELIODN_MASK)
1998
<< (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
1999
WRITE_UINT32(
2000
p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
2001
(uint32_t)(tmpReg64 >> 32));
2002
WRITE_UINT32(
2003
p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
2004
(uint32_t)tmpReg64);
2005
2006
/*Allocation of the TimeOut table - This table resides in the MURAM.
2007
The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
2008
p_Manip->reassmParams.timeOutTblAddr =
2009
PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
2010
2011
if (!p_Manip->reassmParams.timeOutTblAddr)
2012
RETURN_ERROR(MAJOR, E_NO_MEMORY,
2013
("MURAM alloc for Reassembly timeout table"));
2014
2015
MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
2016
(uint16_t)(size * 8));
2017
2018
/* Sets the TimeOut table offset from MURAM */
2019
tmpReg32 = (uint32_t)(XX_VirtToPhys(
2020
UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
2021
- p_FmPcd->physicalMuramBase);
2022
WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
2023
tmpReg32);
2024
2025
/* Sets the Expiration Delay */
2026
tmpReg32 = 0;
2027
tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
2028
* p_Manip->reassmParams.timeoutThresholdForReassmProcess);
2029
WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
2030
tmpReg32);
2031
2032
err = FmPcdRegisterReassmPort(p_FmPcd,
2033
p_Manip->reassmParams.p_ReassCommonTbl);
2034
if (err != E_OK)
2035
{
2036
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2037
p_Manip->reassmParams.p_ReassCommonTbl);
2038
RETURN_ERROR(MAJOR, err, ("port registration"));
2039
}
2040
2041
return err;
2042
}
2043
2044
static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
2045
{
2046
t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
2047
uint32_t tmpReg32, autoLearnHashTblSize;
2048
uint32_t numOfWays, setSize, setSizeCode, keySize;
2049
uint32_t waySize, numOfSets, numOfEntries;
2050
uint64_t tmpReg64;
2051
uint16_t minFragSize;
2052
uint16_t maxReassemSize;
2053
uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
2054
t_ReassTbl **p_ReassTbl;
2055
2056
switch (hdr)
2057
{
2058
case HEADER_TYPE_IPv4:
2059
p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
2060
p_AutoLearnHashTblAddr =
2061
&p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
2062
p_AutoLearnSetLockTblAddr =
2063
&p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
2064
minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
2065
maxReassemSize = 0;
2066
numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
2067
keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
2068
break;
2069
case HEADER_TYPE_IPv6:
2070
p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
2071
p_AutoLearnHashTblAddr =
2072
&p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
2073
p_AutoLearnSetLockTblAddr =
2074
&p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
2075
minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
2076
maxReassemSize = 0;
2077
numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
2078
keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
2079
if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
2080
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
2081
break;
2082
case HEADER_TYPE_CAPWAP:
2083
p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
2084
p_AutoLearnHashTblAddr =
2085
&p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
2086
p_AutoLearnSetLockTblAddr =
2087
&p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
2088
minFragSize = 0;
2089
maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
2090
numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
2091
keySize = 4;
2092
break;
2093
default:
2094
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
2095
}
2096
keySize += 2; /* 2 bytes reserved for RFDIndex */
2097
#if (DPAA_VERSION >= 11)
2098
keySize += 2; /* 2 bytes reserved */
2099
#endif /* (DPAA_VERSION >= 11) */
2100
waySize = ROUND_UP(keySize, 8);
2101
2102
/* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
2103
*p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
2104
p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
2105
FM_PCD_MANIP_REASM_TABLE_ALIGN);
2106
if (!*p_ReassTbl)
2107
RETURN_ERROR( MAJOR, E_NO_MEMORY,
2108
("MURAM alloc for Reassembly specific parameters table"));
2109
memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
2110
2111
/* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
2112
tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
2113
- p_FmPcd->physicalMuramBase);
2114
WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
2115
2116
/* Calculate set size (set size is rounded-up to next power of 2) */
2117
NEXT_POWER_OF_2(numOfWays * waySize, setSize);
2118
2119
/* Get set size code */
2120
LOG2(setSize, setSizeCode);
2121
2122
/* Sets ways number and set size code */
2123
WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
2124
(uint16_t)((numOfWays << 8) | setSizeCode));
2125
2126
/* It is recommended that the total number of entries in this table
2127
(number of sets * number of ways) will be twice the number of frames that
2128
are expected to be reassembled simultaneously.*/
2129
numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
2130
2131
/* sets number calculation - number of entries = number of sets * number of ways */
2132
numOfSets = numOfEntries / numOfWays;
2133
2134
/* Sets AutoLearnHashKeyMask*/
2135
NEXT_POWER_OF_2(numOfSets, numOfSets);
2136
2137
WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
2138
(uint16_t)(numOfSets - 1));
2139
2140
/* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
2141
The size of this table is determined by the number of sets and the set size.
2142
Table size = set size * number of sets
2143
This table base address should be aligned to SetSize.*/
2144
autoLearnHashTblSize = numOfSets * setSize;
2145
2146
*p_AutoLearnHashTblAddr =
2147
PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
2148
if (!*p_AutoLearnHashTblAddr)
2149
{
2150
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
2151
*p_ReassTbl = NULL;
2152
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
2153
}
2154
MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
2155
2156
/* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
2157
tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2158
& FM_PCD_MANIP_REASM_LIODN_MASK)
2159
<< (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
2160
tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2161
& FM_PCD_MANIP_REASM_ELIODN_MASK)
2162
<< (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
2163
tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
2164
WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
2165
(uint32_t)(tmpReg64 >> 32));
2166
WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
2167
2168
/* Allocation of the Set Lock table - This table resides in external memory
2169
The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
2170
This table resides in external memory and its base address should be 4-byte aligned */
2171
*p_AutoLearnSetLockTblAddr =
2172
PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
2173
if (!*p_AutoLearnSetLockTblAddr)
2174
{
2175
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
2176
*p_ReassTbl = NULL;
2177
XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
2178
*p_AutoLearnHashTblAddr = 0;
2179
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
2180
}
2181
MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
2182
2183
/* sets Set Lock table pointer and liodn offset*/
2184
tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2185
& FM_PCD_MANIP_REASM_LIODN_MASK)
2186
<< (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
2187
tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
2188
& FM_PCD_MANIP_REASM_ELIODN_MASK)
2189
<< (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
2190
tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
2191
WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
2192
(uint32_t)(tmpReg64 >> 32));
2193
WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
2194
2195
/* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
2196
WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
2197
2198
WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
2199
2200
return E_OK;
2201
}
2202
2203
static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
2204
t_Handle h_FmPort, t_FmPcdManip *p_Manip,
2205
t_Handle h_Ad, bool validate)
2206
{
2207
t_FmPortGetSetCcParams fmPortGetSetCcParams;
2208
uint32_t tmpReg32;
2209
t_Error err;
2210
t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
2211
#if (DPAA_VERSION >= 11)
2212
t_FmPcdCtrlParamsPage *p_ParamsPage;
2213
#endif /* (DPAA_VERSION >= 11) */
2214
2215
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
2216
SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
2217
SANITY_CHECK_RETURN_ERROR(
2218
(p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
2219
E_INVALID_STATE);
2220
SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
2221
SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
2222
E_INVALID_HANDLE);
2223
2224
UNUSED(h_Ad);
2225
2226
if (!p_Manip->updateParams)
2227
return E_OK;
2228
2229
if (p_Manip->h_FmPcd != h_FmPcd)
2230
RETURN_ERROR(
2231
MAJOR, E_INVALID_STATE,
2232
("handler of PCD previously was initiated by different value"));
2233
2234
if (p_Manip->updateParams)
2235
{
2236
if ((!(p_Manip->updateParams
2237
& (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
2238
|| ((p_Manip->shadowUpdateParams
2239
& (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
2240
RETURN_ERROR(
2241
MAJOR, E_INVALID_STATE,
2242
("in this stage parameters from Port has not be updated"));
2243
2244
fmPortGetSetCcParams.setCcParams.type = 0;
2245
if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
2246
{
2247
fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
2248
fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
2249
}
2250
fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
2251
if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
2252
!= E_OK)
2253
RETURN_ERROR(MAJOR, err, NO_MSG);
2254
if (fmPortGetSetCcParams.getCcParams.type
2255
& (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
2256
RETURN_ERROR(MAJOR, E_INVALID_STATE,
2257
("offset of the data wasn't configured previously"));
2258
if (p_Manip->updateParams
2259
& (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
2260
{
2261
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
2262
uint8_t *p_Ptr, i, totalNumOfTnums;
2263
2264
totalNumOfTnums =
2265
(uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
2266
+ fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
2267
2268
p_Manip->reassmParams.internalBufferPoolAddr =
2269
PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2270
(uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
2271
BMI_FIFO_UNITS));
2272
if (!p_Manip->reassmParams.internalBufferPoolAddr)
2273
RETURN_ERROR(
2274
MAJOR, E_NO_MEMORY,
2275
("MURAM alloc for Reassembly internal buffers pool"));
2276
MemSet8(
2277
UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
2278
0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
2279
2280
p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
2281
PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2282
(uint32_t)(5 + totalNumOfTnums),
2283
4));
2284
if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
2285
RETURN_ERROR(
2286
MAJOR,
2287
E_NO_MEMORY,
2288
("MURAM alloc for Reassembly internal buffers management"));
2289
2290
p_Ptr =
2291
(uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
2292
WRITE_UINT32(
2293
*(uint32_t*)p_Ptr,
2294
(uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
2295
for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
2296
WRITE_UINT8(*p_Ptr, i);
2297
WRITE_UINT8(*p_Ptr, 0xFF);
2298
2299
tmpReg32 =
2300
(4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
2301
| ((uint32_t)(XX_VirtToPhys(
2302
UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
2303
- p_FmPcd->physicalMuramBase));
2304
WRITE_UINT32(
2305
p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
2306
tmpReg32);
2307
2308
p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
2309
| DISCARD_MASK);
2310
p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
2311
| DISCARD_MASK);
2312
}
2313
}
2314
2315
if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
2316
{
2317
if (p_Manip->reassmParams.capwap.h_Scheme)
2318
{
2319
p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
2320
p_Manip->reassmParams.capwap.h_Scheme;
2321
p_PcdParams->p_KgParams->numOfSchemes++;
2322
}
2323
2324
}
2325
else
2326
{
2327
if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
2328
{
2329
p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
2330
p_Manip->reassmParams.ip.h_Ipv4Scheme;
2331
p_PcdParams->p_KgParams->numOfSchemes++;
2332
}
2333
if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
2334
{
2335
p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
2336
p_Manip->reassmParams.ip.h_Ipv6Scheme;
2337
p_PcdParams->p_KgParams->numOfSchemes++;
2338
}
2339
#if (DPAA_VERSION >= 11)
2340
if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
2341
{
2342
if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
2343
(void**)&p_ParamsPage)) != E_OK)
2344
RETURN_ERROR(MAJOR, err, NO_MSG);
2345
2346
tmpReg32 = NIA_ENG_KG;
2347
if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
2348
{
2349
tmpReg32 |= NIA_KG_DIRECT;
2350
tmpReg32 |= NIA_KG_CC_EN;
2351
tmpReg32 |= FmPcdKgGetSchemeId(
2352
p_Manip->reassmParams.ip.h_Ipv4Scheme);
2353
WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
2354
}
2355
if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
2356
{
2357
tmpReg32 &= ~NIA_AC_MASK;
2358
tmpReg32 |= NIA_KG_DIRECT;
2359
tmpReg32 |= NIA_KG_CC_EN;
2360
tmpReg32 |= FmPcdKgGetSchemeId(
2361
p_Manip->reassmParams.ip.h_Ipv6Scheme);
2362
WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
2363
}
2364
}
2365
#else
2366
if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
2367
{
2368
WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
2369
fmPortGetSetCcParams.getCcParams.discardMask);
2370
}
2371
#endif /* (DPAA_VERSION >= 11) */
2372
}
2373
return E_OK;
2374
}
2375
2376
#if (DPAA_VERSION == 10)
2377
static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
2378
{
2379
t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
2380
t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
2381
t_Error err;
2382
2383
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
2384
2385
memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
2386
2387
fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
2388
fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
2389
if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
2390
RETURN_ERROR(MAJOR, err, NO_MSG);
2391
2392
if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
2393
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
2394
"Failed to release %d buffers to the BM (missing FBPRs)",
2395
fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
2396
2397
return E_OK;
2398
}
2399
2400
static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
2401
{
2402
t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
2403
t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
2404
t_Error err;
2405
2406
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
2407
2408
memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
2409
2410
fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
2411
if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
2412
RETURN_ERROR(MAJOR, err, NO_MSG);
2413
2414
return E_OK;
2415
}
2416
#endif /* (DPAA_VERSION == 10) */
2417
2418
static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
2419
{
2420
if (p_Manip->h_Ad)
2421
{
2422
if (p_Manip->muramAllocate)
2423
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
2424
else
2425
XX_Free(p_Manip->h_Ad);
2426
p_Manip->h_Ad = NULL;
2427
}
2428
if (p_Manip->p_Template)
2429
{
2430
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
2431
p_Manip->p_Template = NULL;
2432
}
2433
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
2434
if (p_Manip->h_Frag)
2435
{
2436
if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
2437
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2438
p_Manip->capwapFragParams.p_AutoLearnHashTbl);
2439
if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
2440
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2441
p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
2442
if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
2443
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2444
p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
2445
if (p_Manip->capwapFragParams.p_TimeOutTbl)
2446
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2447
p_Manip->capwapFragParams.p_TimeOutTbl);
2448
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
2449
2450
}
2451
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
2452
if (p_Manip->frag)
2453
{
2454
if (p_Manip->fragParams.p_Frag)
2455
{
2456
#if (DPAA_VERSION == 10)
2457
FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
2458
#endif /* (DPAA_VERSION == 10) */
2459
2460
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
2461
}
2462
}
2463
else
2464
if (p_Manip->reassm)
2465
{
2466
FmPcdUnregisterReassmPort(p_FmPcd,
2467
p_Manip->reassmParams.p_ReassCommonTbl);
2468
2469
if (p_Manip->reassmParams.timeOutTblAddr)
2470
FM_MURAM_FreeMem(
2471
p_FmPcd->h_FmMuram,
2472
UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
2473
if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
2474
XX_FreeSmart(
2475
UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
2476
if (p_Manip->reassmParams.p_ReassCommonTbl)
2477
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2478
p_Manip->reassmParams.p_ReassCommonTbl);
2479
if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
2480
FM_MURAM_FreeMem(
2481
p_FmPcd->h_FmMuram,
2482
UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
2483
if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
2484
FM_MURAM_FreeMem(
2485
p_FmPcd->h_FmMuram,
2486
UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
2487
if (p_Manip->reassmParams.internalBufferPoolAddr)
2488
FM_MURAM_FreeMem(
2489
p_FmPcd->h_FmMuram,
2490
UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
2491
if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
2492
{
2493
2494
}
2495
else
2496
{
2497
if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
2498
XX_FreeSmart(
2499
UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
2500
if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
2501
XX_FreeSmart(
2502
UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
2503
if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
2504
XX_FreeSmart(
2505
UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
2506
if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
2507
XX_FreeSmart(
2508
UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
2509
if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
2510
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2511
p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
2512
if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
2513
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
2514
p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
2515
if (p_Manip->reassmParams.ip.h_Ipv6Ad)
2516
XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
2517
if (p_Manip->reassmParams.ip.h_Ipv4Ad)
2518
XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
2519
}
2520
}
2521
2522
if (p_Manip->p_StatsTbl)
2523
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
2524
}
2525
2526
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
2527
static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
2528
{
2529
if (p_ManipParams->u.hdr.rmv)
2530
{
2531
switch (p_ManipParams->u.hdr.rmvParams.type)
2532
{
2533
case (e_FM_PCD_MANIP_RMV_BY_HDR):
2534
switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
2535
{
2536
case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
2537
if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
2538
{
2539
switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
2540
{
2541
case (HEADER_TYPE_CAPWAP_DTLS) :
2542
p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
2543
p_Manip->muramAllocate = TRUE;
2544
if (p_ManipParams->u.hdr.insrt)
2545
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
2546
if (p_ManipParams->fragOrReasm)
2547
{
2548
if (!p_ManipParams->fragOrReasmParams.frag)
2549
{
2550
switch (p_ManipParams->fragOrReasmParams.hdr)
2551
{
2552
case (HEADER_TYPE_CAPWAP):
2553
p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
2554
break;
2555
default:
2556
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
2557
}
2558
}
2559
else
2560
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
2561
}
2562
break;
2563
default:
2564
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
2565
}
2566
}
2567
else
2568
{
2569
switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
2570
{
2571
case (HEADER_TYPE_CAPWAP_DTLS) :
2572
case (HEADER_TYPE_CAPWAP) :
2573
if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
2574
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_CAPWAP can not be insert or fragOrReasm TRUE"));
2575
p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
2576
p_Manip->muramAllocate = TRUE;
2577
p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
2578
break;
2579
default :
2580
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
2581
}
2582
}
2583
break;
2584
default :
2585
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
2586
}
2587
break;
2588
default:
2589
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
2590
}
2591
}
2592
else if (p_ManipParams->u.hdr.insrt)
2593
{
2594
switch (p_ManipParams->u.hdr.insrtParams.type)
2595
{
2596
case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
2597
2598
p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
2599
p_Manip->muramAllocate = FALSE;
2600
if (p_ManipParams->fragOrReasm)
2601
{
2602
if (p_ManipParams->fragOrReasmParams.frag)
2603
{
2604
switch (p_ManipParams->fragOrReasmParams.hdr)
2605
{
2606
case (HEADER_TYPE_CAPWAP):
2607
p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
2608
break;
2609
default:
2610
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
2611
}
2612
}
2613
else
2614
RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
2615
}
2616
break;
2617
2618
default:
2619
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
2620
}
2621
}
2622
else if (p_ManipParams->fragOrReasm)
2623
{
2624
if (p_ManipParams->fragOrReasmParams.frag)
2625
{
2626
switch (p_ManipParams->fragOrReasmParams.hdr)
2627
{
2628
case (HEADER_TYPE_CAPWAP):
2629
p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
2630
p_Manip->muramAllocate = FALSE;
2631
break;
2632
default:
2633
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
2634
}
2635
}
2636
else
2637
{
2638
switch (p_ManipParams->fragOrReasmParams.hdr)
2639
{
2640
case (HEADER_TYPE_CAPWAP):
2641
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS"));
2642
default:
2643
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
2644
}
2645
}
2646
2647
}
2648
else
2649
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
2650
2651
p_Manip->insrt = p_ManipParams->u.hdr.insrt;
2652
p_Manip->rmv = p_ManipParams->u.hdr.rmv;
2653
2654
return E_OK;
2655
}
2656
2657
#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
2658
static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
2659
t_FmPcdManipParams *p_ManipParams)
2660
{
2661
switch (p_ManipParams->type)
2662
{
2663
case e_FM_PCD_MANIP_HDR:
2664
/* Check that next-manip is not already used */
2665
if (p_ManipParams->h_NextManip)
2666
{
2667
if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
2668
RETURN_ERROR(
2669
MAJOR, E_INVALID_STATE,
2670
("h_NextManip is already a part of another chain"));
2671
if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
2672
!= e_FM_PCD_MANIP_HDR) &&
2673
(MANIP_GET_TYPE(p_ManipParams->h_NextManip)
2674
!= e_FM_PCD_MANIP_FRAG))
2675
RETURN_ERROR(
2676
MAJOR,
2677
E_NOT_SUPPORTED,
2678
("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
2679
}
2680
2681
if (p_ManipParams->u.hdr.rmv)
2682
{
2683
switch (p_ManipParams->u.hdr.rmvParams.type)
2684
{
2685
case (e_FM_PCD_MANIP_RMV_BY_HDR):
2686
switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
2687
{
2688
case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
2689
break;
2690
#if (DPAA_VERSION >= 11)
2691
case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
2692
break;
2693
case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
2694
{
2695
t_Error err;
2696
uint8_t prsArrayOffset;
2697
2698
err =
2699
GetPrOffsetByHeaderOrField(
2700
&p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
2701
&prsArrayOffset);
2702
if (err)
2703
RETURN_ERROR(MAJOR, err, NO_MSG);
2704
break;
2705
}
2706
#endif /* (DPAA_VERSION >= 11) */
2707
default:
2708
RETURN_ERROR(
2709
MAJOR,
2710
E_INVALID_STATE,
2711
("invalid type of remove manipulation"));
2712
}
2713
break;
2714
case (e_FM_PCD_MANIP_RMV_GENERIC):
2715
break;
2716
default:
2717
RETURN_ERROR(MAJOR, E_INVALID_STATE,
2718
("invalid type of remove manipulation"));
2719
}
2720
p_Manip->opcode = HMAN_OC;
2721
p_Manip->muramAllocate = TRUE;
2722
p_Manip->rmv = TRUE;
2723
}
2724
else
2725
if (p_ManipParams->u.hdr.insrt)
2726
{
2727
switch (p_ManipParams->u.hdr.insrtParams.type)
2728
{
2729
case (e_FM_PCD_MANIP_INSRT_BY_HDR):
2730
{
2731
switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
2732
{
2733
case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
2734
/* nothing to check */
2735
break;
2736
#if (DPAA_VERSION >= 11)
2737
case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
2738
if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
2739
% 4)
2740
RETURN_ERROR(
2741
MAJOR,
2742
E_INVALID_VALUE,
2743
("IP inserted header must be of size which is a multiple of four bytes"));
2744
break;
2745
case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
2746
if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
2747
% 4)
2748
RETURN_ERROR(
2749
MAJOR,
2750
E_INVALID_VALUE,
2751
("CAPWAP inserted header must be of size which is a multiple of four bytes"));
2752
break;
2753
case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
2754
case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
2755
if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
2756
!= 8)
2757
RETURN_ERROR(
2758
MAJOR,
2759
E_INVALID_VALUE,
2760
("Inserted header must be of size 8"));
2761
break;
2762
#endif /* (DPAA_VERSION >= 11) */
2763
default:
2764
RETURN_ERROR(
2765
MAJOR,
2766
E_INVALID_STATE,
2767
("unsupported insert by header type"));
2768
}
2769
}
2770
case (e_FM_PCD_MANIP_INSRT_GENERIC):
2771
break;
2772
default:
2773
RETURN_ERROR(
2774
MAJOR,
2775
E_INVALID_STATE,
2776
("for only insert manipulation unsupported type"));
2777
}
2778
p_Manip->opcode = HMAN_OC;
2779
p_Manip->muramAllocate = TRUE;
2780
p_Manip->insrt = TRUE;
2781
}
2782
else
2783
if (p_ManipParams->u.hdr.fieldUpdate)
2784
{
2785
/* Check parameters */
2786
if (p_ManipParams->u.hdr.fieldUpdateParams.type
2787
== e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
2788
{
2789
if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
2790
== e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
2791
&& (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
2792
> 7))
2793
RETURN_ERROR(
2794
MAJOR, E_INVALID_VALUE,
2795
("vpri should get values of 0-7 "));
2796
if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
2797
== e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
2798
{
2799
int i;
2800
2801
if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
2802
> 7)
2803
RETURN_ERROR(
2804
MAJOR,
2805
E_INVALID_VALUE,
2806
("vpriDefVal should get values of 0-7 "));
2807
for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
2808
i++)
2809
if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
2810
& 0xf0)
2811
RETURN_ERROR(
2812
MAJOR,
2813
E_INVALID_VALUE,
2814
("dscpToVpriTabl value out of range (0-15)"));
2815
}
2816
2817
}
2818
2819
p_Manip->opcode = HMAN_OC;
2820
p_Manip->muramAllocate = TRUE;
2821
p_Manip->fieldUpdate = TRUE;
2822
}
2823
else
2824
if (p_ManipParams->u.hdr.custom)
2825
{
2826
if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
2827
{
2828
2829
if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
2830
(p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
2831
RETURN_ERROR(
2832
MAJOR, E_INVALID_VALUE,
2833
("size should get values of 1-8 "));
2834
2835
if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
2836
RETURN_ERROR(
2837
MAJOR, E_INVALID_VALUE,
2838
("srcOffset should be <= 7"));
2839
2840
if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
2841
p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
2842
RETURN_ERROR(
2843
MAJOR, E_INVALID_VALUE,
2844
("(srcOffset + size) should be <= 8"));
2845
2846
if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
2847
p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
2848
RETURN_ERROR(
2849
MAJOR, E_INVALID_VALUE,
2850
("(dstOffset + size) should be <= 256"));
2851
2852
}
2853
2854
p_Manip->opcode = HMAN_OC;
2855
p_Manip->muramAllocate = TRUE;
2856
p_Manip->custom = TRUE;
2857
}
2858
break;
2859
case e_FM_PCD_MANIP_REASSEM:
2860
if (p_ManipParams->h_NextManip)
2861
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2862
("next manip with reassembly"));
2863
switch (p_ManipParams->u.reassem.hdr)
2864
{
2865
case (HEADER_TYPE_IPv4):
2866
p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
2867
p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
2868
break;
2869
case (HEADER_TYPE_IPv6):
2870
p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
2871
p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
2872
break;
2873
#if (DPAA_VERSION >= 11)
2874
case (HEADER_TYPE_CAPWAP):
2875
p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
2876
p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
2877
break;
2878
#endif /* (DPAA_VERSION >= 11) */
2879
default:
2880
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2881
("header for reassembly"));
2882
}
2883
break;
2884
case e_FM_PCD_MANIP_FRAG:
2885
if (p_ManipParams->h_NextManip)
2886
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2887
("next manip with fragmentation"));
2888
switch (p_ManipParams->u.frag.hdr)
2889
{
2890
case (HEADER_TYPE_IPv4):
2891
case (HEADER_TYPE_IPv6):
2892
p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
2893
break;
2894
#if (DPAA_VERSION >= 11)
2895
case (HEADER_TYPE_CAPWAP):
2896
p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
2897
break;
2898
#endif /* (DPAA_VERSION >= 11) */
2899
default:
2900
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2901
("header for fragmentation"));
2902
}
2903
p_Manip->muramAllocate = TRUE;
2904
break;
2905
case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
2906
switch (p_ManipParams->u.specialOffload.type)
2907
{
2908
case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
2909
p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
2910
p_Manip->muramAllocate = TRUE;
2911
break;
2912
#if (DPAA_VERSION >= 11)
2913
case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
2914
p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
2915
p_Manip->muramAllocate = TRUE;
2916
break;
2917
#endif /* (DPAA_VERSION >= 11) */
2918
default:
2919
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
2920
("special offload type"));
2921
}
2922
break;
2923
default:
2924
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
2925
}
2926
2927
return E_OK;
2928
}
2929
#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
2930
2931
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
2932
2933
static t_Error UpdateIndxStats(t_Handle h_FmPcd,
2934
t_Handle h_FmPort,
2935
t_FmPcdManip *p_Manip)
2936
{
2937
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
2938
uint32_t tmpReg32 = 0;
2939
t_AdOfTypeContLookup *p_Ad;
2940
t_FmPortGetSetCcParams fmPortGetSetCcParams;
2941
t_Error err;
2942
2943
SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
2944
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
2945
2946
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
2947
if (p_Manip->h_FmPcd != h_FmPcd)
2948
RETURN_ERROR(MAJOR, E_INVALID_STATE,
2949
("handler of PCD previously was initiated by different value"));
2950
2951
memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
2952
2953
if (!p_Manip->p_StatsTbl)
2954
{
2955
2956
fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
2957
fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
2958
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
2959
if (err)
2960
RETURN_ERROR(MAJOR, err, NO_MSG);
2961
2962
tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
2963
2964
p_Manip->p_StatsTbl =
2965
(t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2966
(uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
2967
4);
2968
if (!p_Manip->p_StatsTbl)
2969
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
2970
2971
MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
2972
2973
tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
2974
2975
if (p_Manip->cnia)
2976
tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
2977
2978
tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
2979
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
2980
}
2981
else
2982
{
2983
fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
2984
fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
2985
err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
2986
if (err)
2987
RETURN_ERROR(MAJOR, err, NO_MSG);
2988
}
2989
2990
return E_OK;
2991
}
2992
2993
static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
2994
{
2995
t_AdOfTypeContLookup *p_Ad;
2996
uint32_t tmpReg32 = 0;
2997
uint8_t prsArrayOffset = 0;
2998
t_Error err;
2999
3000
SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
3001
SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
3002
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3003
3004
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3005
if (p_Manip->rmv)
3006
{
3007
err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
3008
if (err)
3009
RETURN_ERROR(MAJOR, err, NO_MSG);
3010
3011
tmpReg32 |= (uint32_t)prsArrayOffset << 24;
3012
tmpReg32 |= HMAN_RMV_HDR;
3013
}
3014
3015
if (p_Manip->insrt)
3016
tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
3017
3018
tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
3019
3020
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3021
3022
tmpReg32 = 0;
3023
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3024
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3025
3026
return E_OK;
3027
}
3028
3029
static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
3030
bool caamUsed)
3031
{
3032
t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3033
uint32_t tmpReg32 = 0;
3034
3035
SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
3036
3037
p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
3038
3039
tmpReg32 = 0;
3040
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3041
*(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
3042
3043
tmpReg32 = 0;
3044
tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
3045
tmpReg32 |= (uint32_t)0x16 << 16;
3046
*(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
3047
3048
if (caamUsed)
3049
*(uint32_t *)&p_Ad->gmask = 0xf0000000;
3050
3051
return E_OK;
3052
}
3053
3054
static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
3055
{
3056
t_AdOfTypeContLookup *p_Ad;
3057
uint32_t tmpReg32 = 0;
3058
t_Error err = E_OK;
3059
3060
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3061
3062
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3063
3064
tmpReg32 = 0;
3065
tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
3066
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3067
3068
tmpReg32 = 0;
3069
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3070
3071
3072
if (p_Manip->h_Frag)
3073
{
3074
p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
3075
tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
3076
}
3077
3078
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3079
3080
return err;
3081
}
3082
3083
static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
3084
t_FmPcdManip *p_Manip,
3085
t_FmPcd *p_FmPcd,
3086
uint8_t poolId)
3087
{
3088
t_Handle p_Table;
3089
uint32_t tmpReg32 = 0;
3090
int i = 0;
3091
uint8_t log2Num;
3092
uint8_t numOfSets;
3093
uint32_t j = 0;
3094
uint32_t bitFor1Micro;
3095
3096
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
3097
SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
3098
3099
if (!p_FmPcd->h_Hc)
3100
RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
3101
if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
3102
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
3103
if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
3104
RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
3105
if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
3106
DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
3107
if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
3108
{
3109
if ((p_ManipParams->maxNumFramesInProcess < 4) ||
3110
(p_ManipParams->maxNumFramesInProcess > 512))
3111
RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512"));
3112
}
3113
else
3114
{
3115
if ((p_ManipParams->maxNumFramesInProcess < 8) ||
3116
(p_ManipParams->maxNumFramesInProcess > 2048))
3117
RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048"));
3118
}
3119
3120
bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
3121
if (bitFor1Micro == 0)
3122
RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
3123
3124
p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
3125
3126
p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3127
FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
3128
FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
3129
if (!p_Manip->h_Frag)
3130
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
3131
3132
MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
3133
3134
p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
3135
3136
p_Manip->capwapFragParams.p_AutoLearnHashTbl =
3137
(t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3138
(uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
3139
FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
3140
3141
if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
3142
RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
3143
3144
MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
3145
3146
tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
3147
3148
WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
3149
3150
tmpReg32 = 0;
3151
if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
3152
tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
3153
if (p_ManipParams->haltOnDuplicationFrag)
3154
tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
3155
if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
3156
{
3157
i = 8;
3158
tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
3159
}
3160
else
3161
i = 4;
3162
3163
numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
3164
LOG2(numOfSets, log2Num);
3165
tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
3166
3167
WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
3168
3169
for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
3170
if (((j / i) % 2)== 0)
3171
WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
3172
3173
tmpReg32 = 0x00008000;
3174
tmpReg32 |= (uint32_t)poolId << 16;
3175
WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
3176
WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
3177
WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
3178
3179
p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
3180
3181
p_Manip->capwapFragParams.sgBpid = poolId;
3182
3183
p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
3184
p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
3185
p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
3186
3187
tmpReg32 = 0;
3188
tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
3189
WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
3190
3191
return E_OK;
3192
}
3193
3194
static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
3195
t_FmPcdManip *p_Manip,
3196
t_FmPcd *p_FmPcd,
3197
uint8_t poolId)
3198
{
3199
t_AdOfTypeContLookup *p_Ad;
3200
uint32_t tmpReg32 = 0;
3201
3202
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3203
3204
p_Manip->updateParams |= OFFSET_OF_DATA;
3205
3206
p_Manip->frag = TRUE;
3207
3208
p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3209
FM_PCD_CC_AD_ENTRY_SIZE,
3210
FM_PCD_CC_AD_TABLE_ALIGN);
3211
if (!p_Manip->h_Frag)
3212
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
3213
3214
MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3215
3216
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
3217
3218
tmpReg32 = 0;
3219
tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
3220
3221
if (p_ManipParams->headerOptionsCompr)
3222
tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
3223
tmpReg32 |= ((uint32_t)poolId << 8);
3224
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3225
3226
tmpReg32 = 0;
3227
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3228
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3229
3230
p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
3231
p_Manip->capwapFragParams.sgBpid = poolId;
3232
3233
return E_OK;
3234
}
3235
3236
static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
3237
{
3238
t_AdOfTypeContLookup *p_Ad;
3239
uint32_t tmpReg32 = 0;
3240
3241
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3242
3243
UNUSED(p_FmPcd);
3244
3245
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3246
3247
tmpReg32 = 0;
3248
tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
3249
if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
3250
tmpReg32 |= (uint32_t)0x16 << 16;
3251
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3252
3253
tmpReg32 = 0;
3254
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3255
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3256
3257
return E_OK;
3258
}
3259
3260
static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
3261
{
3262
t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
3263
uint8_t tmpReg8 = 0xff;
3264
t_AdOfTypeContLookup *p_Ad;
3265
bool ipModify = FALSE;
3266
uint32_t tmpReg32 = 0, tmpRegNia = 0;
3267
uint16_t tmpReg16 = 0;
3268
t_Error err = E_OK;
3269
uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
3270
uint8_t *p_Template = NULL;
3271
3272
SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
3273
SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
3274
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
3275
SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
3276
3277
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3278
if (p_Manip->insrt)
3279
{
3280
if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
3281
(!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
3282
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
3283
3284
if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
3285
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
3286
3287
if (p_InsrtByTemplate->size > 128)
3288
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
3289
3290
if (p_InsrtByTemplate->size)
3291
{
3292
p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
3293
p_InsrtByTemplate->size,
3294
FM_PCD_CC_AD_TABLE_ALIGN);
3295
if(!p_Manip->p_Template)
3296
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
3297
3298
tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
3299
tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
3300
*(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
3301
}
3302
3303
tmpReg32 = 0;
3304
3305
p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
3306
3307
if (!p_Template)
3308
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
3309
3310
memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
3311
3312
if (p_InsrtByTemplate->modifyOuterIp)
3313
{
3314
ipModify = TRUE;
3315
3316
tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
3317
3318
if((tmpReg8 & 0xf0) == 0x40)
3319
tmpReg8 = 4;
3320
else if((tmpReg8 & 0xf0) == 0x60)
3321
tmpReg8 = 6;
3322
else
3323
tmpReg8 = 0xff;
3324
3325
if (tmpReg8 != 0xff)
3326
{
3327
if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
3328
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
3329
if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
3330
{
3331
3332
if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
3333
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
3334
extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
3335
blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
3336
extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
3337
/*IP header template - IP totalLength -
3338
(1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
3339
in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
3340
second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
3341
}
3342
if (blockSize)
3343
{
3344
if (!POWER_OF_2(blockSize))
3345
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
3346
}
3347
3348
}
3349
if (tmpReg8 == 4)
3350
{
3351
if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
3352
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size"));
3353
3354
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
3355
3356
if (blockSize)
3357
blockSize -= 1;
3358
3359
if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
3360
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
3361
3362
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
3363
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);// for IPV6 decrement additional 40 bytes of IPV6 heade size
3364
3365
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
3366
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
3367
3368
/*IP header template - relevant only for ipv4 CheckSum = 0*/
3369
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
3370
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
3371
3372
/*UDP checksum has to be 0*/
3373
if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
3374
{
3375
if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
3376
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
3377
3378
p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
3379
p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
3380
3381
}
3382
3383
if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
3384
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
3385
3386
tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
3387
}
3388
else if (tmpReg8 == 6)
3389
{
3390
/*TODO - add check for maximum value of blockSize;*/
3391
if (blockSize)
3392
LOG2(blockSize, log2Num);
3393
tmpRegNia |= (uint32_t)log2Num << 24;
3394
3395
// for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
3396
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
3397
p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
3398
if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
3399
{
3400
if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
3401
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
3402
if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
3403
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
3404
p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
3405
p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
3406
p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
3407
p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
3408
}
3409
}
3410
else
3411
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
3412
}
3413
3414
tmpReg32 = tmpReg16 = tmpReg8 = 0;
3415
/*TODO - check it*/
3416
if (p_InsrtByTemplate->modifyOuterVlan)
3417
{
3418
if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
3419
RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
3420
3421
memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
3422
if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
3423
RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
3424
3425
memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
3426
tmpReg8 &= 0x1f;
3427
tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
3428
3429
p_Template[14] = tmpReg8;
3430
}
3431
3432
MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
3433
3434
XX_Free(p_Template);
3435
}
3436
3437
tmpReg32 = 0;
3438
if (p_Manip->h_Frag)
3439
{
3440
tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
3441
tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
3442
}
3443
else
3444
tmpReg32 = 0xffff0000;
3445
3446
if (ipModify)
3447
tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
3448
else
3449
tmpReg32 |= (uint32_t)0x0000ff00;
3450
3451
tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
3452
*(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
3453
3454
tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3455
*(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
3456
3457
return err;
3458
}
3459
3460
static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
3461
{
3462
3463
switch (p_StatsParams->type)
3464
{
3465
case (e_FM_PCD_STATS_PER_FLOWID):
3466
p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
3467
p_Manip->muramAllocate = TRUE;
3468
break;
3469
default:
3470
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
3471
}
3472
3473
return E_OK;
3474
}
3475
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
3476
3477
static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
3478
{
3479
t_AdOfTypeContLookup *p_Ad;
3480
t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
3481
uint32_t tmpReg32;
3482
t_Error err = E_OK;
3483
3484
/* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
3485
function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
3486
two separate IP Reassembly Parameter tables are required.*/
3487
if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
3488
RETURN_ERROR(MAJOR, err, NO_MSG);
3489
3490
/* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
3491
tmpReg32 = 0;
3492
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3493
3494
/* Gets the required Action descriptor table pointer */
3495
switch (hdr)
3496
{
3497
case HEADER_TYPE_IPv4:
3498
p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
3499
tmpReg32 |= (uint32_t)(XX_VirtToPhys(
3500
p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
3501
- (p_FmPcd->physicalMuramBase));
3502
break;
3503
case HEADER_TYPE_IPv6:
3504
p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
3505
tmpReg32 |= (uint32_t)(XX_VirtToPhys(
3506
p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
3507
- (p_FmPcd->physicalMuramBase));
3508
break;
3509
case HEADER_TYPE_CAPWAP:
3510
p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
3511
tmpReg32 |= (uint32_t)(XX_VirtToPhys(
3512
p_Manip->reassmParams.capwap.p_ReassTbl)
3513
- (p_FmPcd->physicalMuramBase));
3514
break;
3515
default:
3516
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
3517
}
3518
3519
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
3520
3521
/* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
3522
/* mark the Scatter/Gather table offset to be set later on when the port will be known */
3523
p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
3524
3525
if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
3526
{
3527
#if (DPAA_VERSION == 10)
3528
tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
3529
WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
3530
#endif /* (DPAA_VERSION == 10) */
3531
#if (DPAA_VERSION >= 11)
3532
if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
3533
{
3534
tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
3535
| (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
3536
WRITE_UINT32(p_Ad->gmask, tmpReg32);
3537
}
3538
#endif /* (DPAA_VERSION >= 11) */
3539
/* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
3540
tmpReg32 = 0;
3541
tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
3542
}
3543
#if (DPAA_VERSION >= 11)
3544
else
3545
if (hdr == HEADER_TYPE_CAPWAP)
3546
{
3547
tmpReg32 = 0;
3548
tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
3549
}
3550
#endif /* (DPAA_VERSION >= 11) */
3551
3552
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3553
3554
p_Manip->reassm = TRUE;
3555
3556
return E_OK;
3557
}
3558
3559
static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
3560
{
3561
t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
3562
3563
/* Allocation if IPv4 Action descriptor */
3564
p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
3565
FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
3566
FM_PCD_CC_AD_TABLE_ALIGN);
3567
if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
3568
{
3569
ReleaseManipHandler(p_Manip, p_FmPcd);
3570
RETURN_ERROR(MAJOR, E_NO_MEMORY,
3571
("Allocation of IPv4 table descriptor"));
3572
}
3573
3574
memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3575
3576
/* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
3577
return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
3578
}
3579
3580
static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
3581
{
3582
t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
3583
3584
/* Allocation if IPv6 Action descriptor */
3585
p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
3586
FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
3587
FM_PCD_CC_AD_TABLE_ALIGN);
3588
if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
3589
{
3590
ReleaseManipHandler(p_Manip, p_FmPcd);
3591
RETURN_ERROR(MAJOR, E_NO_MEMORY,
3592
("Allocation of IPv6 table descriptor"));
3593
}
3594
3595
memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3596
3597
/* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
3598
return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
3599
}
3600
3601
static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
3602
t_FmPcdManip *p_Manip)
3603
{
3604
uint32_t maxSetNumber = 10000;
3605
t_FmPcdManipReassemIpParams reassmManipParams =
3606
p_ManipReassmParams->u.ipReassem;
3607
t_Error res;
3608
3609
SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
3610
SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
3611
E_INVALID_HANDLE);
3612
3613
/* Check validation of user's parameter.*/
3614
if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
3615
|| (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
3616
RETURN_ERROR(
3617
MAJOR, E_INVALID_VALUE,
3618
("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
3619
/* It is recommended that the total number of entries in this table (number of sets * number of ways)
3620
will be twice the number of frames that are expected to be reassembled simultaneously.*/
3621
if (reassmManipParams.maxNumFramesInProcess
3622
> (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
3623
RETURN_ERROR(
3624
MAJOR,
3625
E_INVALID_VALUE,
3626
("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
3627
3628
if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
3629
&& (reassmManipParams.minFragSize[1] < 256))
3630
RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
3631
3632
/* Saves user's reassembly manipulation parameters */
3633
p_Manip->reassmParams.ip.relativeSchemeId[0] =
3634
reassmManipParams.relativeSchemeId[0];
3635
p_Manip->reassmParams.ip.relativeSchemeId[1] =
3636
reassmManipParams.relativeSchemeId[1];
3637
p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
3638
reassmManipParams.numOfFramesPerHashEntry[0];
3639
p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
3640
reassmManipParams.numOfFramesPerHashEntry[1];
3641
p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
3642
p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
3643
p_Manip->reassmParams.maxNumFramesInProcess =
3644
reassmManipParams.maxNumFramesInProcess;
3645
p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
3646
p_Manip->reassmParams.fqidForTimeOutFrames =
3647
reassmManipParams.fqidForTimeOutFrames;
3648
p_Manip->reassmParams.timeoutThresholdForReassmProcess =
3649
reassmManipParams.timeoutThresholdForReassmProcess;
3650
p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
3651
p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
3652
#if (DPAA_VERSION == 10)
3653
p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
3654
#endif /* (DPAA_VERSION == 10) */
3655
#if (DPAA_VERSION >= 11)
3656
if (reassmManipParams.nonConsistentSpFqid != 0)
3657
{
3658
p_Manip->reassmParams.ip.nonConsistentSpFqid =
3659
reassmManipParams.nonConsistentSpFqid;
3660
}
3661
#endif /* (DPAA_VERSION >= 11) */
3662
3663
/* Creates and initializes the IP Reassembly common parameter table */
3664
CreateReassCommonTable(p_Manip);
3665
3666
/* Creation of IPv4 reassembly manipulation */
3667
if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
3668
|| (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
3669
{
3670
res = SetIpv4ReassmManip(p_Manip);
3671
if (res != E_OK)
3672
return res;
3673
}
3674
3675
/* Creation of IPv6 reassembly manipulation */
3676
if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
3677
{
3678
res = SetIpv6ReassmManip(p_Manip);
3679
if (res != E_OK)
3680
return res;
3681
}
3682
3683
return E_OK;
3684
}
3685
3686
static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
3687
t_FmPcdKgSchemeParams *p_Scheme,
3688
t_Handle h_CcTree, bool ipv4,
3689
uint8_t groupId)
3690
{
3691
uint32_t j;
3692
uint8_t res;
3693
3694
/* Configures scheme's network environment parameters */
3695
p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
3696
if (ipv4)
3697
res = FmPcdNetEnvGetUnitId(
3698
p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
3699
HEADER_TYPE_IPv4, FALSE, 0);
3700
else
3701
res = FmPcdNetEnvGetUnitId(
3702
p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
3703
HEADER_TYPE_IPv6, FALSE, 0);
3704
ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
3705
p_Scheme->netEnvParams.unitIds[0] = res;
3706
3707
res = FmPcdNetEnvGetUnitId(
3708
p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
3709
HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
3710
ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
3711
p_Scheme->netEnvParams.unitIds[1] = res;
3712
3713
/* Configures scheme's next engine parameters*/
3714
p_Scheme->nextEngine = e_FM_PCD_CC;
3715
p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
3716
p_Scheme->kgNextEngineParams.cc.grpId = groupId;
3717
p_Scheme->useHash = TRUE;
3718
3719
/* Configures scheme's key*/
3720
if (ipv4 == TRUE)
3721
{
3722
p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
3723
p_Scheme->keyExtractAndHashParams.extractArray[0].type =
3724
e_FM_PCD_EXTRACT_BY_HDR;
3725
p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
3726
e_FM_PCD_EXTRACT_FULL_FIELD;
3727
p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
3728
HEADER_TYPE_IPv4;
3729
p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
3730
NET_HEADER_FIELD_IPv4_DST_IP;
3731
p_Scheme->keyExtractAndHashParams.extractArray[1].type =
3732
e_FM_PCD_EXTRACT_BY_HDR;
3733
p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
3734
e_FM_PCD_EXTRACT_FULL_FIELD;
3735
p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
3736
HEADER_TYPE_IPv4;
3737
p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
3738
NET_HEADER_FIELD_IPv4_SRC_IP;
3739
p_Scheme->keyExtractAndHashParams.extractArray[2].type =
3740
e_FM_PCD_EXTRACT_BY_HDR;
3741
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
3742
e_FM_PCD_EXTRACT_FULL_FIELD;
3743
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
3744
HEADER_TYPE_IPv4;
3745
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
3746
NET_HEADER_FIELD_IPv4_PROTO;
3747
p_Scheme->keyExtractAndHashParams.extractArray[3].type =
3748
e_FM_PCD_EXTRACT_BY_HDR;
3749
p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
3750
HEADER_TYPE_IPv4;
3751
p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
3752
e_FM_PCD_EXTRACT_FROM_HDR;
3753
p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
3754
FALSE;
3755
p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
3756
2;
3757
p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
3758
4;
3759
}
3760
else /* IPv6 */
3761
{
3762
p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
3763
p_Scheme->keyExtractAndHashParams.extractArray[0].type =
3764
e_FM_PCD_EXTRACT_BY_HDR;
3765
p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
3766
e_FM_PCD_EXTRACT_FULL_FIELD;
3767
p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
3768
HEADER_TYPE_IPv6;
3769
p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
3770
NET_HEADER_FIELD_IPv6_DST_IP;
3771
p_Scheme->keyExtractAndHashParams.extractArray[1].type =
3772
e_FM_PCD_EXTRACT_BY_HDR;
3773
p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
3774
e_FM_PCD_EXTRACT_FULL_FIELD;
3775
p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
3776
HEADER_TYPE_IPv6;
3777
p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
3778
NET_HEADER_FIELD_IPv6_SRC_IP;
3779
p_Scheme->keyExtractAndHashParams.extractArray[2].type =
3780
e_FM_PCD_EXTRACT_BY_HDR;
3781
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
3782
HEADER_TYPE_USER_DEFINED_SHIM2;
3783
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
3784
e_FM_PCD_EXTRACT_FROM_HDR;
3785
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
3786
4;
3787
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
3788
4;
3789
p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
3790
TRUE;
3791
}
3792
3793
p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
3794
p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
3795
p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
3796
FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
3797
for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
3798
{
3799
p_Scheme->keyExtractAndHashParams.dflts[j].type =
3800
(e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
3801
p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
3802
e_FM_PCD_KG_DFLT_GBL_0;
3803
}
3804
}
3805
3806
static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
3807
t_FmPcdManipReassemIpStats *p_Stats)
3808
{
3809
ASSERT_COND(p_Manip);
3810
ASSERT_COND(p_Stats);
3811
ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
3812
3813
p_Stats->timeout =
3814
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
3815
p_Stats->rfdPoolBusy =
3816
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
3817
p_Stats->internalBufferBusy =
3818
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
3819
p_Stats->externalBufferBusy =
3820
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
3821
p_Stats->sgFragments =
3822
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
3823
p_Stats->dmaSemaphoreDepletion =
3824
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
3825
#if (DPAA_VERSION >= 11)
3826
p_Stats->nonConsistentSp =
3827
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
3828
#endif /* (DPAA_VERSION >= 11) */
3829
3830
if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
3831
{
3832
p_Stats->specificHdrStatistics[0].successfullyReassembled =
3833
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
3834
p_Stats->specificHdrStatistics[0].validFragments =
3835
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
3836
p_Stats->specificHdrStatistics[0].processedFragments =
3837
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
3838
p_Stats->specificHdrStatistics[0].malformedFragments =
3839
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
3840
p_Stats->specificHdrStatistics[0].autoLearnBusy =
3841
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
3842
p_Stats->specificHdrStatistics[0].discardedFragments =
3843
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
3844
p_Stats->specificHdrStatistics[0].moreThan16Fragments =
3845
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
3846
}
3847
if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
3848
{
3849
p_Stats->specificHdrStatistics[1].successfullyReassembled =
3850
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
3851
p_Stats->specificHdrStatistics[1].validFragments =
3852
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
3853
p_Stats->specificHdrStatistics[1].processedFragments =
3854
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
3855
p_Stats->specificHdrStatistics[1].malformedFragments =
3856
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
3857
p_Stats->specificHdrStatistics[1].autoLearnBusy =
3858
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
3859
p_Stats->specificHdrStatistics[1].discardedFragments =
3860
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
3861
p_Stats->specificHdrStatistics[1].moreThan16Fragments =
3862
GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
3863
}
3864
return E_OK;
3865
}
3866
3867
static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
3868
t_FmPcdManipFragIpStats *p_Stats)
3869
{
3870
t_AdOfTypeContLookup *p_Ad;
3871
3872
ASSERT_COND(p_Manip);
3873
ASSERT_COND(p_Stats);
3874
ASSERT_COND(p_Manip->h_Ad);
3875
ASSERT_COND(p_Manip->fragParams.p_Frag);
3876
3877
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3878
3879
p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
3880
p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
3881
& 0x00ffffff;
3882
p_Stats->generatedFragments =
3883
GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
3884
3885
return E_OK;
3886
}
3887
3888
static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
3889
t_FmPcdManip *p_Manip)
3890
{
3891
uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
3892
t_FmPcd *p_FmPcd;
3893
#if (DPAA_VERSION == 10)
3894
t_Error err = E_OK;
3895
#endif /* (DPAA_VERSION == 10) */
3896
3897
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
3898
SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
3899
E_INVALID_VALUE);
3900
3901
p_FmPcd = p_Manip->h_FmPcd;
3902
/* Allocation of fragmentation Action Descriptor */
3903
p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
3904
p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
3905
FM_PCD_CC_AD_TABLE_ALIGN);
3906
if (!p_Manip->fragParams.p_Frag)
3907
RETURN_ERROR(MAJOR, E_NO_MEMORY,
3908
("MURAM alloc for Fragmentation table descriptor"));
3909
MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
3910
3911
/* Prepare the third Ad register (pcAndOffsets)- OperationCode */
3912
pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
3913
3914
/* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
3915
ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
3916
ccAdBaseReg |= (p_ManipParams->dontFragAction
3917
<< FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
3918
3919
3920
/* Set Scatter/Gather BPid */
3921
if (p_ManipParams->sgBpidEn)
3922
{
3923
ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
3924
pcAndOffsetsReg |= ((p_ManipParams->sgBpid
3925
<< FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
3926
& FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
3927
}
3928
3929
/* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
3930
gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
3931
- p_FmPcd->physicalMuramBase);
3932
#if (DPAA_VERSION == 10)
3933
gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
3934
#else
3935
gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
3936
#endif /* (DPAA_VERSION == 10) */
3937
3938
/* Set all Ad registers */
3939
WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
3940
WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
3941
WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
3942
3943
/* Saves user's fragmentation manipulation parameters */
3944
p_Manip->frag = TRUE;
3945
p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
3946
3947
#if (DPAA_VERSION == 10)
3948
p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
3949
3950
/* scratch buffer pool initialization */
3951
if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
3952
{
3953
FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
3954
p_Manip->fragParams.p_Frag = NULL;
3955
RETURN_ERROR(MAJOR, err, NO_MSG);
3956
}
3957
#endif /* (DPAA_VERSION == 10) */
3958
3959
return E_OK;
3960
}
3961
3962
static t_Error IPManip(t_FmPcdManip *p_Manip)
3963
{
3964
t_Error err = E_OK;
3965
t_FmPcd *p_FmPcd;
3966
t_AdOfTypeContLookup *p_Ad;
3967
uint32_t tmpReg32 = 0, tmpRegNia = 0;
3968
3969
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
3970
p_FmPcd = p_Manip->h_FmPcd;
3971
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
3972
3973
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
3974
3975
tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
3976
if (p_Manip->frag == TRUE)
3977
{
3978
tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
3979
- (p_FmPcd->physicalMuramBase));
3980
tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
3981
<< FM_PCD_MANIP_IP_MTU_SHIFT;
3982
}
3983
3984
tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
3985
tmpReg32 |= HMAN_OC_IP_MANIP;
3986
3987
#if (DPAA_VERSION >= 11)
3988
tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
3989
#endif /* (DPAA_VERSION >= 11) */
3990
3991
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
3992
WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
3993
WRITE_UINT32(p_Ad->gmask, 0);
3994
/* Total frame counter - MUST be initialized to zero.*/
3995
3996
return err;
3997
}
3998
3999
static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
4000
t_Handle h_FmPort, t_FmPcdManip *p_Manip,
4001
t_Handle h_Ad, bool validate)
4002
{
4003
t_FmPortGetSetCcParams fmPortGetSetCcParams;
4004
t_Error err;
4005
4006
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4007
SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
4008
E_INVALID_STATE);
4009
SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
4010
SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4011
4012
UNUSED(h_FmPcd);
4013
UNUSED(h_Ad);
4014
UNUSED(h_PcdParams);
4015
UNUSED(validate);
4016
UNUSED(p_Manip);
4017
4018
fmPortGetSetCcParams.setCcParams.type = 0;
4019
fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
4020
if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
4021
RETURN_ERROR(MAJOR, err, NO_MSG);
4022
4023
if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
4024
DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
4025
4026
return E_OK;
4027
}
4028
4029
static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
4030
t_FmPcdManip *p_Manip)
4031
{
4032
t_AdOfTypeContLookup *p_Ad;
4033
t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
4034
t_Error err = E_OK;
4035
uint32_t tmpReg32 = 0;
4036
uint32_t power;
4037
4038
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4039
SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
4040
4041
p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
4042
4043
SANITY_CHECK_RETURN_ERROR(
4044
!p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
4045
E_INVALID_VALUE);
4046
SANITY_CHECK_RETURN_ERROR(
4047
!p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
4048
E_INVALID_VALUE);
4049
SANITY_CHECK_RETURN_ERROR(
4050
!p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
4051
E_INVALID_VALUE);
4052
SANITY_CHECK_RETURN_ERROR(
4053
!p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
4054
E_INVALID_VALUE);
4055
SANITY_CHECK_RETURN_ERROR(
4056
!p_IPSecParams->arwSize || p_IPSecParams->decryption,
4057
E_INVALID_VALUE);
4058
SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
4059
4060
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4061
4062
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
4063
tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
4064
tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
4065
tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
4066
tmpReg32 |=
4067
(p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
4068
tmpReg32 |=
4069
(p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
4070
if (p_IPSecParams->arwSize)
4071
tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
4072
& (FM_MURAM_SIZE-1));
4073
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
4074
4075
tmpReg32 = 0;
4076
if (p_IPSecParams->arwSize) {
4077
NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
4078
LOG2(power, power);
4079
tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
4080
}
4081
4082
if (p_ManipParams->h_NextManip)
4083
tmpReg32 |=
4084
(uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
4085
(((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
4086
WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
4087
4088
tmpReg32 = HMAN_OC_IPSEC_MANIP;
4089
tmpReg32 |= p_IPSecParams->outerIPHdrLen
4090
<< FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
4091
if (p_ManipParams->h_NextManip)
4092
tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
4093
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
4094
4095
return err;
4096
}
4097
4098
static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
4099
{
4100
t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
4101
4102
/* Allocation if CAPWAP Action descriptor */
4103
p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
4104
FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
4105
FM_PCD_CC_AD_TABLE_ALIGN);
4106
if (!p_Manip->reassmParams.capwap.h_Ad)
4107
{
4108
ReleaseManipHandler(p_Manip, p_FmPcd);
4109
RETURN_ERROR(MAJOR, E_NO_MEMORY,
4110
("Allocation of CAPWAP table descriptor"));
4111
}
4112
4113
memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4114
4115
/* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
4116
return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
4117
}
4118
4119
static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
4120
t_FmPcdKgSchemeParams *p_Scheme,
4121
t_Handle h_CcTree, uint8_t groupId)
4122
{
4123
uint8_t res;
4124
4125
/* Configures scheme's network environment parameters */
4126
p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
4127
res = FmPcdNetEnvGetUnitId(
4128
p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
4129
HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
4130
ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
4131
p_Scheme->netEnvParams.unitIds[0] = res;
4132
4133
/* Configures scheme's next engine parameters*/
4134
p_Scheme->nextEngine = e_FM_PCD_CC;
4135
p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
4136
p_Scheme->kgNextEngineParams.cc.grpId = groupId;
4137
p_Scheme->useHash = TRUE;
4138
4139
/* Configures scheme's key*/
4140
p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
4141
p_Scheme->keyExtractAndHashParams.extractArray[0].type =
4142
e_FM_PCD_EXTRACT_NON_HDR;
4143
p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
4144
e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
4145
p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
4146
e_FM_PCD_ACTION_NONE;
4147
p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
4148
p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
4149
p_Scheme->keyExtractAndHashParams.extractArray[1].type =
4150
e_FM_PCD_EXTRACT_NON_HDR;
4151
p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
4152
e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
4153
p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
4154
e_FM_PCD_ACTION_NONE;
4155
p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
4156
p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
4157
4158
p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
4159
p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
4160
p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
4161
p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
4162
p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
4163
}
4164
4165
#if (DPAA_VERSION >= 11)
4166
static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
4167
t_FmPcdManipReassemCapwapStats *p_Stats)
4168
{
4169
ASSERT_COND(p_Manip);
4170
ASSERT_COND(p_Stats);
4171
ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
4172
4173
p_Stats->timeout =
4174
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
4175
p_Stats->rfdPoolBusy =
4176
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
4177
p_Stats->internalBufferBusy =
4178
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
4179
p_Stats->externalBufferBusy =
4180
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
4181
p_Stats->sgFragments =
4182
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
4183
p_Stats->dmaSemaphoreDepletion =
4184
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
4185
p_Stats->exceedMaxReassemblyFrameLen =
4186
GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
4187
4188
p_Stats->successfullyReassembled =
4189
GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
4190
p_Stats->validFragments =
4191
GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
4192
p_Stats->processedFragments =
4193
GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
4194
p_Stats->malformedFragments =
4195
GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
4196
p_Stats->autoLearnBusy =
4197
GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
4198
p_Stats->discardedFragments =
4199
GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
4200
p_Stats->moreThan16Fragments =
4201
GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
4202
4203
return E_OK;
4204
}
4205
4206
static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
4207
t_FmPcdManipFragCapwapStats *p_Stats)
4208
{
4209
t_AdOfTypeContLookup *p_Ad;
4210
4211
ASSERT_COND(p_Manip);
4212
ASSERT_COND(p_Stats);
4213
ASSERT_COND(p_Manip->h_Ad);
4214
ASSERT_COND(p_Manip->fragParams.p_Frag);
4215
4216
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4217
4218
p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
4219
4220
return E_OK;
4221
}
4222
4223
static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
4224
t_FmPcdManip *p_Manip)
4225
{
4226
uint32_t maxSetNumber = 10000;
4227
t_FmPcdManipReassemCapwapParams reassmManipParams =
4228
p_ManipReassmParams->u.capwapReassem;
4229
t_Error res;
4230
4231
SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
4232
SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
4233
E_INVALID_HANDLE);
4234
4235
/* Check validation of user's parameter.*/
4236
if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
4237
|| (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
4238
RETURN_ERROR(
4239
MAJOR, E_INVALID_VALUE,
4240
("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
4241
/* It is recommended that the total number of entries in this table (number of sets * number of ways)
4242
will be twice the number of frames that are expected to be reassembled simultaneously.*/
4243
if (reassmManipParams.maxNumFramesInProcess
4244
> (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
4245
RETURN_ERROR(
4246
MAJOR,
4247
E_INVALID_VALUE,
4248
("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
4249
4250
/* Saves user's reassembly manipulation parameters */
4251
p_Manip->reassmParams.capwap.relativeSchemeId =
4252
reassmManipParams.relativeSchemeId;
4253
p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
4254
reassmManipParams.numOfFramesPerHashEntry;
4255
p_Manip->reassmParams.capwap.maxRessembledsSize =
4256
reassmManipParams.maxReassembledFrameLength;
4257
p_Manip->reassmParams.maxNumFramesInProcess =
4258
reassmManipParams.maxNumFramesInProcess;
4259
p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
4260
p_Manip->reassmParams.fqidForTimeOutFrames =
4261
reassmManipParams.fqidForTimeOutFrames;
4262
p_Manip->reassmParams.timeoutThresholdForReassmProcess =
4263
reassmManipParams.timeoutThresholdForReassmProcess;
4264
p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
4265
p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
4266
4267
/* Creates and initializes the Reassembly common parameter table */
4268
CreateReassCommonTable(p_Manip);
4269
4270
res = SetCapwapReassmManip(p_Manip);
4271
if (res != E_OK)
4272
return res;
4273
4274
return E_OK;
4275
}
4276
4277
static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
4278
t_FmPcdManip *p_Manip)
4279
{
4280
t_FmPcd *p_FmPcd;
4281
t_AdOfTypeContLookup *p_Ad;
4282
uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
4283
uint32_t tmpReg32 = 0, tmpRegNia = 0;
4284
4285
SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
4286
SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
4287
E_INVALID_VALUE);
4288
p_FmPcd = p_Manip->h_FmPcd;
4289
SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
4290
4291
/* Allocation of fragmentation Action Descriptor */
4292
p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
4293
p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
4294
FM_PCD_CC_AD_TABLE_ALIGN);
4295
if (!p_Manip->fragParams.p_Frag)
4296
RETURN_ERROR(MAJOR, E_NO_MEMORY,
4297
("MURAM alloc for Fragmentation table descriptor"));
4298
MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4299
4300
/* Prepare the third Ad register (pcAndOffsets)- OperationCode */
4301
pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
4302
4303
/* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
4304
ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
4305
ccAdBaseReg |=
4306
(p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
4307
0;
4308
4309
/* Set Scatter/Gather BPid */
4310
if (p_ManipParams->sgBpidEn)
4311
{
4312
ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
4313
pcAndOffsetsReg |= ((p_ManipParams->sgBpid
4314
<< FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
4315
& FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
4316
}
4317
4318
/* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
4319
gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
4320
- p_FmPcd->physicalMuramBase);
4321
gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
4322
4323
/* Set all Ad registers */
4324
WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
4325
WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
4326
WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
4327
4328
/* Saves user's fragmentation manipulation parameters */
4329
p_Manip->frag = TRUE;
4330
p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
4331
4332
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4333
4334
tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
4335
- (p_FmPcd->physicalMuramBase));
4336
tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
4337
<< FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
4338
4339
tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
4340
tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
4341
4342
tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
4343
4344
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
4345
WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
4346
WRITE_UINT32(p_Ad->gmask, 0);
4347
/* Total frame counter - MUST be initialized to zero.*/
4348
4349
return E_OK;
4350
}
4351
4352
static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
4353
t_Handle h_FmPort, t_FmPcdManip *p_Manip,
4354
t_Handle h_Ad, bool validate)
4355
{
4356
t_FmPortGetSetCcParams fmPortGetSetCcParams;
4357
t_Error err;
4358
4359
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4360
SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
4361
E_INVALID_STATE);
4362
SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
4363
SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4364
4365
UNUSED(h_FmPcd);
4366
UNUSED(h_Ad);
4367
UNUSED(h_PcdParams);
4368
UNUSED(validate);
4369
UNUSED(p_Manip);
4370
4371
fmPortGetSetCcParams.setCcParams.type = 0;
4372
fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
4373
if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
4374
RETURN_ERROR(MAJOR, err, NO_MSG);
4375
4376
if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
4377
DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
4378
4379
return E_OK;
4380
}
4381
4382
static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
4383
t_FmPcdManip *p_Manip)
4384
{
4385
t_AdOfTypeContLookup *p_Ad;
4386
t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
4387
t_Error err = E_OK;
4388
uint32_t tmpReg32 = 0;
4389
4390
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
4391
SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
4392
4393
p_Params = &p_ManipParams->u.specialOffload.u.capwap;
4394
4395
p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
4396
tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
4397
tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
4398
/* TODO - add 'qosSrc' */
4399
WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
4400
4401
tmpReg32 = HMAN_OC_CAPWAP_MANIP;
4402
if (p_ManipParams->h_NextManip)
4403
{
4404
WRITE_UINT32(
4405
p_Ad->matchTblPtr,
4406
(uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
4407
4408
tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
4409
}
4410
4411
WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
4412
4413
return err;
4414
}
4415
#endif /* (DPAA_VERSION >= 11) */
4416
4417
static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
4418
bool stats)
4419
{
4420
t_FmPcdManip *p_Manip;
4421
t_Error err;
4422
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
4423
4424
p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
4425
if (!p_Manip)
4426
{
4427
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
4428
return NULL;
4429
}
4430
memset(p_Manip, 0, sizeof(t_FmPcdManip));
4431
4432
p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
4433
memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
4434
sizeof(p_Manip->manipParams));
4435
4436
if (!stats)
4437
err = CheckManipParamsAndSetType(p_Manip,
4438
(t_FmPcdManipParams *)p_Params);
4439
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4440
else
4441
err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
4442
#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4443
else
4444
{
4445
REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
4446
XX_Free(p_Manip);
4447
return NULL;
4448
}
4449
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4450
if (err)
4451
{
4452
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
4453
XX_Free(p_Manip);
4454
return NULL;
4455
}
4456
4457
if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
4458
{
4459
/* In Case of reassembly manipulation the reassembly action descriptor will
4460
be defines later on */
4461
if (p_Manip->muramAllocate)
4462
{
4463
p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
4464
p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
4465
FM_PCD_CC_AD_TABLE_ALIGN);
4466
if (!p_Manip->h_Ad)
4467
{
4468
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
4469
ReleaseManipHandler(p_Manip, p_FmPcd);
4470
XX_Free(p_Manip);
4471
return NULL;
4472
}
4473
4474
MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4475
}
4476
else
4477
{
4478
p_Manip->h_Ad = (t_Handle)XX_Malloc(
4479
FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
4480
if (!p_Manip->h_Ad)
4481
{
4482
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
4483
ReleaseManipHandler(p_Manip, p_FmPcd);
4484
XX_Free(p_Manip);
4485
return NULL;
4486
}
4487
4488
memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
4489
}
4490
}
4491
4492
p_Manip->h_FmPcd = h_FmPcd;
4493
4494
return p_Manip;
4495
}
4496
4497
static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
4498
t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
4499
{
4500
t_CcNodeInformation *p_CcNodeInformation;
4501
t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
4502
t_List *p_Pos;
4503
int i = 0;
4504
t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
4505
t_CcNodeInformation ccNodeInfo;
4506
4507
NCSW_LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
4508
{
4509
p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
4510
p_NodePtrOnCurrentMdfManip =
4511
(t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
4512
4513
ASSERT_COND(p_NodePtrOnCurrentMdfManip);
4514
4515
/* Search in the previous node which exact index points on this current modified node for getting AD */
4516
for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
4517
{
4518
if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
4519
== e_FM_PCD_CC)
4520
{
4521
if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
4522
== (t_Handle)p_CrntMdfManip)
4523
{
4524
if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
4525
p_AdTablePtOnCrntCurrentMdfNode =
4526
p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
4527
else
4528
p_AdTablePtOnCrntCurrentMdfNode =
4529
PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
4530
4531
memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
4532
ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
4533
EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
4534
}
4535
}
4536
}
4537
4538
ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
4539
}
4540
}
4541
4542
static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
4543
t_FmPcd *p_FmPcd)
4544
{
4545
t_Error err;
4546
4547
/* Copy the HMTD */
4548
MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
4549
/* Replace the HMCT table pointer */
4550
WRITE_UINT32(
4551
((t_Hmtd *)p_Dest)->hmcdBasePtr,
4552
(uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
4553
/* Call Host Command to replace HMTD by a new HMTD */
4554
err = FmHcPcdCcDoDynamicChange(
4555
p_FmPcd->h_Hc,
4556
(uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
4557
(uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
4558
if (err)
4559
REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
4560
}
4561
4562
static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
4563
t_Handle h_FmPort, t_Handle h_Manip,
4564
t_Handle h_Ad, bool validate, int level,
4565
t_Handle h_FmTree)
4566
{
4567
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4568
t_Error err = E_OK;
4569
4570
SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
4571
4572
UNUSED(level);
4573
UNUSED(h_FmTree);
4574
4575
switch (p_Manip->opcode)
4576
{
4577
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4578
case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4579
err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
4580
p_Manip,
4581
h_Ad,
4582
validate);
4583
break;
4584
case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4585
if (!p_Manip->h_Frag)
4586
break;
4587
case (HMAN_OC_CAPWAP_FRAGMENTATION):
4588
err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
4589
break;
4590
case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4591
if (p_Manip->h_Frag)
4592
err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
4593
break;
4594
case (HMAN_OC_CAPWAP_INDEXED_STATS):
4595
err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
4596
break;
4597
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4598
case (HMAN_OC_IP_REASSEMBLY):
4599
err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
4600
validate);
4601
break;
4602
case (HMAN_OC_IP_FRAGMENTATION):
4603
err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
4604
h_Ad, validate);
4605
break;
4606
#if (DPAA_VERSION >= 11)
4607
case (HMAN_OC_CAPWAP_FRAGMENTATION):
4608
err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
4609
h_Ad, validate);
4610
break;
4611
case (HMAN_OC_CAPWAP_REASSEMBLY):
4612
err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
4613
validate);
4614
break;
4615
#endif /* (DPAA_VERSION >= 11) */
4616
default:
4617
return E_OK;
4618
}
4619
4620
return err;
4621
}
4622
4623
static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
4624
bool validate, int level,
4625
t_Handle h_FmTree)
4626
{
4627
4628
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4629
t_Error err = E_OK;
4630
4631
UNUSED(level);
4632
4633
switch (p_Manip->opcode)
4634
{
4635
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4636
case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4637
RETURN_ERROR(
4638
MAJOR,
4639
E_INVALID_STATE,
4640
("modify node with this type of manipulation is not suppported"));
4641
case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4642
4643
if (p_Manip->h_Frag)
4644
{
4645
if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
4646
&& !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
4647
&& !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
4648
RETURN_ERROR(
4649
MAJOR,
4650
E_INVALID_STATE,
4651
("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
4652
}
4653
break;
4654
case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4655
if (p_Manip->h_Frag)
4656
err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
4657
break;
4658
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4659
default:
4660
return E_OK;
4661
}
4662
4663
return err;
4664
}
4665
4666
/*****************************************************************************/
4667
/* Inter-module API routines */
4668
/*****************************************************************************/
4669
4670
t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
4671
t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
4672
bool validate, int level, t_Handle h_FmTree,
4673
bool modify)
4674
{
4675
t_Error err;
4676
4677
if (!modify)
4678
err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
4679
h_Ad, validate, level, h_FmTree);
4680
else
4681
err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
4682
4683
return err;
4684
}
4685
4686
void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
4687
{
4688
4689
uint32_t intFlags;
4690
4691
intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
4692
if (add)
4693
((t_FmPcdManip *)h_Manip)->owner++;
4694
else
4695
{
4696
ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
4697
((t_FmPcdManip *)h_Manip)->owner--;
4698
}
4699
XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
4700
}
4701
4702
t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
4703
{
4704
ASSERT_COND(h_Manip);
4705
return &((t_FmPcdManip *)h_Manip)->nodesLst;
4706
}
4707
4708
t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
4709
{
4710
ASSERT_COND(h_Manip);
4711
return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
4712
}
4713
4714
t_Error FmPcdManipCheckParamsForCcNextEngine(
4715
t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
4716
uint32_t *requiredAction)
4717
{
4718
t_FmPcdManip *p_Manip;
4719
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4720
t_Error err = E_OK;
4721
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
4722
bool pointFromCc = TRUE;
4723
4724
SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
4725
SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
4726
E_NULL_POINTER);
4727
4728
p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
4729
*requiredAction = 0;
4730
4731
while (p_Manip)
4732
{
4733
switch (p_Manip->opcode)
4734
{
4735
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4736
case (HMAN_OC_CAPWAP_INDEXED_STATS):
4737
if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
4738
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
4739
if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
4740
p_Manip->cnia = TRUE;
4741
case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4742
*requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
4743
case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
4744
p_Manip->ownerTmp++;
4745
break;
4746
case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4747
if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
4748
&& !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
4749
RETURN_ERROR(
4750
MAJOR,
4751
E_INVALID_STATE,
4752
("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
4753
p_Manip->ownerTmp++;
4754
break;
4755
case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4756
if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
4757
&& (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
4758
!= CC_PC_GENERIC_IC_HASH_INDEXED))
4759
RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP"));
4760
err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
4761
FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
4762
if (err)
4763
RETURN_ERROR(MAJOR, err, NO_MSG);
4764
*requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
4765
break;
4766
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4767
case (HMAN_OC_IP_FRAGMENTATION):
4768
case (HMAN_OC_IP_REASSEMBLY):
4769
#if (DPAA_VERSION >= 11)
4770
case (HMAN_OC_CAPWAP_REASSEMBLY):
4771
case (HMAN_OC_CAPWAP_FRAGMENTATION):
4772
#endif /* (DPAA_VERSION >= 11) */
4773
if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
4774
RETURN_ERROR(
4775
MAJOR,
4776
E_INVALID_STATE,
4777
("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
4778
p_Manip->ownerTmp++;
4779
break;
4780
case (HMAN_OC_IPSEC_MANIP):
4781
#if (DPAA_VERSION >= 11)
4782
case (HMAN_OC_CAPWAP_MANIP):
4783
#endif /* (DPAA_VERSION >= 11) */
4784
p_Manip->ownerTmp++;
4785
break;
4786
case (HMAN_OC):
4787
if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
4788
&& MANIP_IS_CASCADED(p_Manip))
4789
RETURN_ERROR(
4790
MINOR,
4791
E_INVALID_STATE,
4792
("Can't have a cascaded manipulation when and Next Engine is CC"));
4793
if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
4794
RETURN_ERROR(
4795
MAJOR,
4796
E_INVALID_STATE,
4797
("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
4798
break;
4799
default:
4800
RETURN_ERROR(
4801
MAJOR, E_INVALID_STATE,
4802
("invalid type of header manipulation for this state"));
4803
}
4804
p_Manip = p_Manip->h_NextManip;
4805
pointFromCc = FALSE;
4806
}
4807
return E_OK;
4808
}
4809
4810
4811
t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
4812
t_Handle h_FmPcdCcNode)
4813
{
4814
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4815
t_Error err = E_OK;
4816
4817
SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
4818
SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
4819
4820
switch (p_Manip->opcode)
4821
{
4822
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4823
case (HMAN_OC_CAPWAP_INDEXED_STATS):
4824
if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
4825
RETURN_ERROR(
4826
MAJOR,
4827
E_INVALID_VALUE,
4828
("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
4829
break;
4830
case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4831
if (p_Manip->h_Frag)
4832
{
4833
if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
4834
RETURN_ERROR(
4835
MAJOR,
4836
E_INVALID_VALUE,
4837
("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
4838
err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
4839
if (err)
4840
RETURN_ERROR(MAJOR, err, NO_MSG);
4841
}
4842
break;
4843
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4844
default:
4845
break;
4846
}
4847
4848
return err;
4849
}
4850
4851
void FmPcdManipUpdateAdResultForCc(
4852
t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
4853
t_Handle p_Ad, t_Handle *p_AdNewPtr)
4854
{
4855
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4856
4857
/* This routine creates a Manip AD and can return in "p_AdNewPtr"
4858
* either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
4859
4860
ASSERT_COND(p_Manip);
4861
ASSERT_COND(p_CcNextEngineParams);
4862
ASSERT_COND(p_Ad);
4863
ASSERT_COND(p_AdNewPtr);
4864
4865
FmPcdManipUpdateOwner(h_Manip, TRUE);
4866
4867
/* According to "type", either build & initialize a new AD (p_AdNew) or initialize
4868
* p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
4869
switch (p_Manip->opcode)
4870
{
4871
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4872
case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
4873
case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
4874
case (HMAN_OC_CAPWAP_INDEXED_STATS):
4875
*p_AdNewPtr = p_Manip->h_Ad;
4876
break;
4877
case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
4878
case (HMAN_OC_CAPWAP_FRAGMENTATION):
4879
WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
4880
((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
4881
WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
4882
((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
4883
WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
4884
((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
4885
*p_AdNewPtr = NULL;
4886
break;
4887
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4888
case (HMAN_OC_IPSEC_MANIP):
4889
#if (DPAA_VERSION >= 11)
4890
case (HMAN_OC_CAPWAP_MANIP):
4891
#endif /* (DPAA_VERSION >= 11) */
4892
*p_AdNewPtr = p_Manip->h_Ad;
4893
break;
4894
case (HMAN_OC_IP_FRAGMENTATION):
4895
#if (DPAA_VERSION >= 11)
4896
case (HMAN_OC_CAPWAP_FRAGMENTATION):
4897
#endif /* (DPAA_VERSION >= 11) */
4898
if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
4899
&& (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
4900
{
4901
memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
4902
sizeof(t_AdOfTypeContLookup));
4903
#if (DPAA_VERSION >= 11)
4904
WRITE_UINT32(
4905
((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
4906
GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
4907
#endif /* (DPAA_VERSION >= 11) */
4908
*p_AdNewPtr = NULL;
4909
}
4910
else
4911
*p_AdNewPtr = p_Manip->h_Ad;
4912
break;
4913
case (HMAN_OC_IP_REASSEMBLY):
4914
if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
4915
{
4916
if (!p_Manip->reassmParams.ip.ipv6Assigned)
4917
{
4918
*p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
4919
p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
4920
FmPcdManipUpdateOwner(h_Manip, FALSE);
4921
}
4922
else
4923
{
4924
*p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
4925
p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
4926
}
4927
}
4928
else
4929
*p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
4930
memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
4931
sizeof(t_AdOfTypeContLookup));
4932
*p_AdNewPtr = NULL;
4933
break;
4934
#if (DPAA_VERSION >= 11)
4935
case (HMAN_OC_CAPWAP_REASSEMBLY):
4936
*p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
4937
memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
4938
sizeof(t_AdOfTypeContLookup));
4939
*p_AdNewPtr = NULL;
4940
break;
4941
#endif /* (DPAA_VERSION >= 11) */
4942
case (HMAN_OC):
4943
/* Allocate and initialize HMTD */
4944
*p_AdNewPtr = p_Manip->h_Ad;
4945
break;
4946
default:
4947
break;
4948
}
4949
}
4950
4951
void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
4952
t_Handle *p_AdNewPtr,
4953
uint32_t adTableOffset)
4954
{
4955
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
4956
4957
/* This routine creates a Manip AD and can return in "p_AdNewPtr"
4958
* either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
4959
ASSERT_COND(p_Manip);
4960
4961
FmPcdManipUpdateOwner(h_Manip, TRUE);
4962
4963
switch (p_Manip->opcode)
4964
{
4965
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
4966
case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
4967
WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
4968
((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
4969
WRITE_UINT32(
4970
((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
4971
((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
4972
WRITE_UINT32(
4973
((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
4974
((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
4975
WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
4976
((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
4977
WRITE_UINT32(
4978
((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
4979
(GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
4980
*p_AdNewPtr = NULL;
4981
break;
4982
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
4983
case (HMAN_OC):
4984
/* Initialize HMTD within the match table*/
4985
MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
4986
/* copy the existing HMTD *//* ask Alla - memcpy??? */
4987
memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
4988
/* update NADEN to be "1"*/
4989
WRITE_UINT16(
4990
((t_Hmtd *)p_Ad)->cfg,
4991
(uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
4992
/* update next action descriptor */
4993
WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
4994
(uint16_t)(adTableOffset >> 4));
4995
/* mark that Manip's HMTD is not used */
4996
*p_AdNewPtr = NULL;
4997
break;
4998
4999
default:
5000
break;
5001
}
5002
}
5003
5004
t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
5005
t_Handle h_CcTree, t_Handle h_Manip,
5006
bool isIpv4, uint8_t groupId)
5007
{
5008
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5009
t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
5010
t_Handle h_Scheme;
5011
5012
ASSERT_COND(p_FmPcd);
5013
ASSERT_COND(h_NetEnv);
5014
ASSERT_COND(p_Manip);
5015
5016
/* scheme was already build, no need to check for IPv6 */
5017
if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
5018
return E_OK;
5019
5020
if (isIpv4) {
5021
h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
5022
if (h_Scheme) {
5023
/* scheme was found */
5024
p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
5025
return E_OK;
5026
}
5027
} else {
5028
h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
5029
if (h_Scheme) {
5030
/* scheme was found */
5031
p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
5032
return E_OK;
5033
}
5034
}
5035
5036
p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
5037
if (!p_SchemeParams)
5038
RETURN_ERROR(MAJOR, E_NO_MEMORY,
5039
("Memory allocation failed for scheme"));
5040
5041
/* Configures the IPv4 or IPv6 scheme*/
5042
memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
5043
p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
5044
p_SchemeParams->id.relativeSchemeId = (uint8_t)(
5045
(isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
5046
p_Manip->reassmParams.ip.relativeSchemeId[1]);
5047
p_SchemeParams->schemeCounter.update = TRUE;
5048
#if (DPAA_VERSION >= 11)
5049
p_SchemeParams->alwaysDirect = TRUE;
5050
p_SchemeParams->bypassFqidGeneration = TRUE;
5051
#else
5052
p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
5053
p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
5054
#endif /* (DPAA_VERSION >= 11) */
5055
5056
setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
5057
5058
/* Sets the new scheme */
5059
if (isIpv4)
5060
p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
5061
p_FmPcd, p_SchemeParams);
5062
else
5063
p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
5064
p_FmPcd, p_SchemeParams);
5065
5066
XX_Free(p_SchemeParams);
5067
5068
return E_OK;
5069
}
5070
5071
t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
5072
{
5073
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5074
5075
ASSERT_COND(p_Manip);
5076
5077
if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
5078
!FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
5079
FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
5080
5081
if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
5082
!FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
5083
FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
5084
5085
return E_OK;
5086
}
5087
5088
bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
5089
{
5090
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5091
5092
ASSERT_COND(p_Manip);
5093
5094
return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
5095
}
5096
5097
t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
5098
t_Handle h_CcTree, t_Handle h_Manip,
5099
uint8_t groupId)
5100
{
5101
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5102
t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
5103
5104
ASSERT_COND(p_FmPcd);
5105
ASSERT_COND(h_NetEnv);
5106
ASSERT_COND(p_Manip);
5107
5108
/* scheme was already build, no need to check for IPv6 */
5109
if (p_Manip->reassmParams.capwap.h_Scheme)
5110
return E_OK;
5111
5112
p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
5113
if (!p_SchemeParams)
5114
RETURN_ERROR(MAJOR, E_NO_MEMORY,
5115
("Memory allocation failed for scheme"));
5116
5117
memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
5118
p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
5119
p_SchemeParams->id.relativeSchemeId =
5120
(uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
5121
p_SchemeParams->schemeCounter.update = TRUE;
5122
p_SchemeParams->bypassFqidGeneration = TRUE;
5123
5124
setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
5125
5126
p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
5127
p_SchemeParams);
5128
5129
XX_Free(p_SchemeParams);
5130
5131
return E_OK;
5132
}
5133
5134
t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
5135
{
5136
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5137
5138
ASSERT_COND(p_Manip);
5139
5140
if (p_Manip->reassmParams.capwap.h_Scheme)
5141
FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
5142
5143
return E_OK;
5144
}
5145
5146
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
5147
t_Handle FmPcdManipApplSpecificBuild(void)
5148
{
5149
t_FmPcdManip *p_Manip;
5150
5151
p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
5152
if (!p_Manip)
5153
{
5154
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
5155
return NULL;
5156
}
5157
memset(p_Manip, 0, sizeof(t_FmPcdManip));
5158
5159
p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
5160
p_Manip->muramAllocate = FALSE;
5161
5162
p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
5163
if (!p_Manip->h_Ad)
5164
{
5165
REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
5166
XX_Free(p_Manip);
5167
return NULL;
5168
}
5169
5170
memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
5171
5172
/*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
5173
/*Application specific = type of flowId index, move internal frame header from data to IC,
5174
SEC errors check*/
5175
if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
5176
{
5177
XX_Free(p_Manip->h_Ad);
5178
XX_Free(p_Manip);
5179
return NULL;
5180
}
5181
return p_Manip;
5182
}
5183
5184
bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
5185
{
5186
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
5187
ASSERT_COND(h_Manip);
5188
5189
return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
5190
}
5191
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
5192
/*********************** End of inter-module routines ************************/
5193
5194
/****************************************/
5195
/* API Init unit functions */
5196
/****************************************/
5197
5198
t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
5199
t_FmPcdManipParams *p_ManipParams)
5200
{
5201
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
5202
t_FmPcdManip *p_Manip;
5203
t_Error err;
5204
5205
SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
5206
SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
5207
5208
p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
5209
if (!p_Manip)
5210
return NULL;
5211
5212
if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
5213
|| (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
5214
|| (p_Manip->opcode == HMAN_OC)
5215
|| (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
5216
#if (DPAA_VERSION >= 11)
5217
|| (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
5218
|| (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
5219
|| (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
5220
#endif /* (DPAA_VERSION >= 11) */
5221
) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
5222
{
5223
REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
5224
XX_Free(p_Manip);
5225
return NULL;
5226
}
5227
p_Manip->h_Spinlock = XX_InitSpinlock();
5228
if (!p_Manip->h_Spinlock)
5229
{
5230
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5231
ReleaseManipHandler(p_Manip, p_FmPcd);
5232
XX_Free(p_Manip);
5233
return NULL;
5234
}INIT_LIST(&p_Manip->nodesLst);
5235
5236
switch (p_Manip->opcode)
5237
{
5238
case (HMAN_OC_IP_REASSEMBLY):
5239
/* IpReassembly */
5240
err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
5241
break;
5242
case (HMAN_OC_IP_FRAGMENTATION):
5243
/* IpFragmentation */
5244
err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
5245
if (err)
5246
break;
5247
err = IPManip(p_Manip);
5248
break;
5249
case (HMAN_OC_IPSEC_MANIP):
5250
err = IPSecManip(p_ManipParams, p_Manip);
5251
break;
5252
#if (DPAA_VERSION >= 11)
5253
case (HMAN_OC_CAPWAP_REASSEMBLY):
5254
/* CapwapReassembly */
5255
err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
5256
break;
5257
case (HMAN_OC_CAPWAP_FRAGMENTATION):
5258
/* CapwapFragmentation */
5259
err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
5260
p_Manip);
5261
break;
5262
case (HMAN_OC_CAPWAP_MANIP):
5263
err = CapwapManip(p_ManipParams, p_Manip);
5264
break;
5265
#endif /* (DPAA_VERSION >= 11) */
5266
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
5267
case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
5268
/* HmanType1 */
5269
err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
5270
break;
5271
case (HMAN_OC_CAPWAP_FRAGMENTATION):
5272
err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
5273
p_Manip,
5274
p_FmPcd,
5275
p_ManipParams->fragOrReasmParams.sgBpid);
5276
if (err)
5277
{
5278
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5279
ReleaseManipHandler(p_Manip, p_FmPcd);
5280
XX_Free(p_Manip);
5281
return NULL;
5282
}
5283
if (p_Manip->insrt)
5284
p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
5285
case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
5286
/* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
5287
err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
5288
break;
5289
case (HMAN_OC_CAPWAP_REASSEMBLY):
5290
err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
5291
p_Manip,
5292
p_FmPcd,
5293
p_ManipParams->fragOrReasmParams.sgBpid);
5294
if (err)
5295
{
5296
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5297
ReleaseManipHandler(p_Manip, p_FmPcd);
5298
XX_Free(p_Manip);
5299
return NULL;
5300
}
5301
if (p_Manip->rmv)
5302
p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
5303
case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
5304
/*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
5305
err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
5306
break;
5307
case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
5308
/*Application Specific type 1*/
5309
err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
5310
break;
5311
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
5312
case (HMAN_OC):
5313
/* New Manip */
5314
err = CreateManipActionNew(p_Manip, p_ManipParams);
5315
break;
5316
default:
5317
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
5318
ReleaseManipHandler(p_Manip, p_FmPcd);
5319
XX_Free(p_Manip);
5320
return NULL;
5321
}
5322
5323
if (err)
5324
{
5325
REPORT_ERROR(MAJOR, err, NO_MSG);
5326
ReleaseManipHandler(p_Manip, p_FmPcd);
5327
XX_Free(p_Manip);
5328
return NULL;
5329
}
5330
5331
if (p_ManipParams->h_NextManip)
5332
{
5333
/* in the check routine we've verified that h_NextManip has no owners
5334
* and that only supported types are allowed. */
5335
p_Manip->h_NextManip = p_ManipParams->h_NextManip;
5336
/* save a "prev" pointer in h_NextManip */
5337
MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
5338
FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
5339
}
5340
5341
return p_Manip;
5342
}
5343
5344
t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
5345
t_FmPcdManipParams *p_ManipParams)
5346
{
5347
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
5348
t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
5349
t_Error err;
5350
uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
5351
t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
5352
t_CcNodeInformation *p_CcNodeInfo;
5353
SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
5354
SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
5355
5356
INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
5357
5358
if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
5359
|| (p_Manip->type != e_FM_PCD_MANIP_HDR))
5360
RETURN_ERROR(
5361
MINOR,
5362
E_NOT_SUPPORTED,
5363
("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
5364
5365
ASSERT_COND(p_Manip->opcode == HMAN_OC);
5366
ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
5367
memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
5368
sizeof(p_Manip->manipParams));
5369
p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
5370
5371
/* The replacement of the HdrManip depends on the node type.*/
5372
/*
5373
* (1) If this is an independent node, all its owners should be updated.
5374
*
5375
* (2) If it is the head of a cascaded chain (it does not have a "prev" but
5376
* it has a "next" and it has a "cascaded" indication), the next
5377
* node remains unchanged, and the behavior is as in (1).
5378
*
5379
* (3) If it is not the head, but a part of a cascaded chain, in can be
5380
* also replaced as a regular node with just one owner.
5381
*
5382
* (4) If it is a part of a chain implemented as a unified table, the
5383
* whole table is replaced and the owners of the head node must be updated.
5384
*
5385
*/
5386
/* lock shadow */
5387
if (!p_FmPcd->p_CcShadow)
5388
RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
5389
5390
if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
5391
return ERROR_CODE(E_BUSY);
5392
5393
/* this routine creates a new manip action in the CC Shadow. */
5394
err = CreateManipActionShadow(p_Manip, p_ManipParams);
5395
if (err)
5396
RETURN_ERROR(MINOR, err, NO_MSG);
5397
5398
/* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
5399
* replace only HMTD and no lcok is required. Otherwise
5400
* lock the whole PCD
5401
* In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
5402
if (!FmPcdLockTryLockAll(p_FmPcd))
5403
{
5404
DBG(TRACE, ("FmPcdLockTryLockAll failed"));
5405
return ERROR_CODE(E_BUSY);
5406
}
5407
5408
p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
5409
5410
p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
5411
e_MANIP_HANDLER_TABLE_OWNER);
5412
ASSERT_COND(p_FirstManip);
5413
5414
if (!NCSW_LIST_IsEmpty(&p_FirstManip->nodesLst))
5415
UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
5416
p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
5417
5418
p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
5419
ASSERT_COND(p_Hmtd);
5420
BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
5421
((t_FmPcd*)(p_Manip->h_FmPcd)));
5422
5423
NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
5424
{
5425
p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
5426
BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
5427
p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
5428
}
5429
5430
p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
5431
ASSERT_COND(p_WholeHmct);
5432
5433
/* re-build the HMCT n the original location */
5434
err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
5435
if (err)
5436
{
5437
RELEASE_LOCK(p_FmPcd->shadowLock);
5438
RETURN_ERROR(MINOR, err, NO_MSG);
5439
}
5440
5441
p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
5442
ASSERT_COND(p_Hmtd);
5443
BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
5444
((t_FmPcd*)p_Manip->h_FmPcd));
5445
5446
/* If NCSW_LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
5447
* For each p_Hmct (from list+fixed):
5448
* call Host Command to replace HMTD by a new one */NCSW_LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
5449
{
5450
p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
5451
BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
5452
p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
5453
}
5454
5455
5456
ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
5457
5458
FmPcdLockUnlockAll(p_FmPcd);
5459
5460
/* unlock shadow */
5461
RELEASE_LOCK(p_FmPcd->shadowLock);
5462
5463
return E_OK;
5464
}
5465
5466
t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
5467
{
5468
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
5469
5470
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
5471
5472
if (p_Manip->owner)
5473
RETURN_ERROR(
5474
MAJOR,
5475
E_INVALID_STATE,
5476
("This manipulation node not be removed because this node is occupied, first - unbind this node "));
5477
5478
if (p_Manip->h_NextManip)
5479
{
5480
MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
5481
FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
5482
}
5483
5484
if (p_Manip->p_Hmct
5485
&& (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
5486
FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
5487
p_Manip->p_Hmct);
5488
5489
if (p_Manip->h_Spinlock)
5490
{
5491
XX_FreeSpinlock(p_Manip->h_Spinlock);
5492
p_Manip->h_Spinlock = NULL;
5493
}
5494
5495
ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
5496
5497
XX_Free(h_ManipNode);
5498
5499
return E_OK;
5500
}
5501
5502
t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
5503
t_FmPcdManipStats *p_FmPcdManipStats)
5504
{
5505
t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
5506
5507
SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
5508
SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
5509
5510
switch (p_Manip->opcode)
5511
{
5512
case (HMAN_OC_IP_REASSEMBLY):
5513
return IpReassemblyStats(p_Manip,
5514
&p_FmPcdManipStats->u.reassem.u.ipReassem);
5515
case (HMAN_OC_IP_FRAGMENTATION):
5516
return IpFragmentationStats(p_Manip,
5517
&p_FmPcdManipStats->u.frag.u.ipFrag);
5518
#if (DPAA_VERSION >= 11)
5519
case (HMAN_OC_CAPWAP_REASSEMBLY):
5520
return CapwapReassemblyStats(
5521
p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
5522
case (HMAN_OC_CAPWAP_FRAGMENTATION):
5523
return CapwapFragmentationStats(
5524
p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
5525
#endif /* (DPAA_VERSION >= 11) */
5526
default:
5527
RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5528
("no statistics to this type of manip"));
5529
}
5530
5531
return E_OK;
5532
}
5533
5534
#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
5535
t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
5536
{
5537
t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
5538
t_FmPcdManip *p_Manip;
5539
t_Error err;
5540
5541
SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
5542
SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
5543
5544
p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
5545
if (!p_Manip)
5546
return NULL;
5547
5548
switch (p_Manip->opcode)
5549
{
5550
case (HMAN_OC_CAPWAP_INDEXED_STATS):
5551
/* Indexed statistics */
5552
err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
5553
break;
5554
default:
5555
REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
5556
ReleaseManipHandler(p_Manip, p_FmPcd);
5557
XX_Free(p_Manip);
5558
return NULL;
5559
}
5560
5561
if (err)
5562
{
5563
REPORT_ERROR(MAJOR, err, NO_MSG);
5564
ReleaseManipHandler(p_Manip, p_FmPcd);
5565
XX_Free(p_Manip);
5566
return NULL;
5567
}
5568
5569
return p_Manip;
5570
}
5571
#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
5572
5573