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 /****************************************/
GetManipInfo(t_FmPcdManip * p_Manip,e_ManipInfo manipInfo)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
GetHmctSize(t_FmPcdManip * p_Manip)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
GetDataSize(t_FmPcdManip * p_Manip)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
CalculateTableSize(t_FmPcdManipParams * p_FmPcdManipParams,uint16_t * p_TableSize,uint8_t * p_DataSize)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
GetPrOffsetByHeaderOrField(t_FmManipHdrInfo * p_HdrInfo,uint8_t * parseArrayOffset)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
BuildHmct(t_FmPcdManip * p_Manip,t_FmPcdManipParams * p_FmPcdManipParams,uint8_t * p_DestHmct,uint8_t * p_DestData,bool new)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
CreateManipActionNew(t_FmPcdManip * p_Manip,t_FmPcdManipParams * p_FmPcdManipParams)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
CreateManipActionShadow(t_FmPcdManip * p_Manip,t_FmPcdManipParams * p_FmPcdManipParams)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
CreateManipActionBackToOrig(t_FmPcdManip * p_Manip,t_FmPcdManipParams * p_FmPcdManipParams)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))
UpdateManipIc(t_Handle h_Manip,uint8_t icOffset)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
UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(t_Handle h_FmPort,t_FmPcdManip * p_Manip,t_Handle h_Ad,bool validate)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
UpdateModifyCapwapFragmenation(t_FmPcdManip * p_Manip,t_Handle h_Ad,bool validate,t_Handle h_FmTree)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
UpdateInitCapwapFragmentation(t_Handle h_FmPort,t_FmPcdManip * p_Manip,t_Handle h_Ad,bool validate,t_Handle h_FmTree)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
UpdateInitCapwapReasm(t_Handle h_FmPcd,t_Handle h_FmPort,t_FmPcdManip * p_Manip,t_Handle h_Ad,bool validate)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
FmPcdRegisterReassmPort(t_Handle h_FmPcd,t_Handle h_ReasmCommonPramTbl)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
CreateReassCommonTable(t_FmPcdManip * p_Manip)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
CreateReassTable(t_FmPcdManip * p_Manip,e_NetHeaderType hdr)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
UpdateInitReasm(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPort,t_FmPcdManip * p_Manip,t_Handle h_Ad,bool validate)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)
FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd,uint8_t scratchBpid)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
FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd,uint8_t scratchBpid)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
ReleaseManipHandler(t_FmPcdManip * p_Manip,t_FmPcd * p_FmPcd)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))
CheckManipParamsAndSetType(t_FmPcdManip * p_Manip,t_FmPcdManipParams * p_ManipParams)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)) */
CheckManipParamsAndSetType(t_FmPcdManip * p_Manip,t_FmPcdManipParams * p_ManipParams)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
UpdateIndxStats(t_Handle h_FmPcd,t_Handle h_FmPort,t_FmPcdManip * p_Manip)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
RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams * p_ManipParams,t_FmPcdManip * p_Manip)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
MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip * p_Manip,bool caamUsed)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
CapwapRmvDtlsHdr(t_FmPcd * p_FmPcd,t_FmPcdManip * p_Manip)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
CapwapReassembly(t_CapwapReassemblyParams * p_ManipParams,t_FmPcdManip * p_Manip,t_FmPcd * p_FmPcd,uint8_t poolId)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
CapwapFragmentation(t_CapwapFragmentationParams * p_ManipParams,t_FmPcdManip * p_Manip,t_FmPcd * p_FmPcd,uint8_t poolId)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
IndxStats(t_FmPcdStatsParams * p_StatsParams,t_FmPcdManip * p_Manip,t_FmPcd * p_FmPcd)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
InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams * p_ManipParams,t_FmPcdManip * p_Manip,t_FmPcd * p_FmPcd)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
CheckStatsParamsAndSetType(t_FmPcdManip * p_Manip,t_FmPcdStatsParams * p_StatsParams)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
FillReassmManipParams(t_FmPcdManip * p_Manip,e_NetHeaderType hdr)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
SetIpv4ReassmManip(t_FmPcdManip * p_Manip)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
SetIpv6ReassmManip(t_FmPcdManip * p_Manip)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
IpReassembly(t_FmPcdManipReassemParams * p_ManipReassmParams,t_FmPcdManip * p_Manip)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
setIpReassmSchemeParams(t_FmPcd * p_FmPcd,t_FmPcdKgSchemeParams * p_Scheme,t_Handle h_CcTree,bool ipv4,uint8_t groupId)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
IpReassemblyStats(t_FmPcdManip * p_Manip,t_FmPcdManipReassemIpStats * p_Stats)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
IpFragmentationStats(t_FmPcdManip * p_Manip,t_FmPcdManipFragIpStats * p_Stats)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
IpFragmentation(t_FmPcdManipFragIpParams * p_ManipParams,t_FmPcdManip * p_Manip)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
IPManip(t_FmPcdManip * p_Manip)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
UpdateInitIpFrag(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPort,t_FmPcdManip * p_Manip,t_Handle h_Ad,bool validate)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
IPSecManip(t_FmPcdManipParams * p_ManipParams,t_FmPcdManip * p_Manip)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
SetCapwapReassmManip(t_FmPcdManip * p_Manip)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
setCapwapReassmSchemeParams(t_FmPcd * p_FmPcd,t_FmPcdKgSchemeParams * p_Scheme,t_Handle h_CcTree,uint8_t groupId)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)
CapwapReassemblyStats(t_FmPcdManip * p_Manip,t_FmPcdManipReassemCapwapStats * p_Stats)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
CapwapFragmentationStats(t_FmPcdManip * p_Manip,t_FmPcdManipFragCapwapStats * p_Stats)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
CapwapReassembly(t_FmPcdManipReassemParams * p_ManipReassmParams,t_FmPcdManip * p_Manip)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
CapwapFragmentation(t_FmPcdManipFragCapwapParams * p_ManipParams,t_FmPcdManip * p_Manip)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
UpdateInitCapwapFrag(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPort,t_FmPcdManip * p_Manip,t_Handle h_Ad,bool validate)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
CapwapManip(t_FmPcdManipParams * p_ManipParams,t_FmPcdManip * p_Manip)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
ManipOrStatsSetNode(t_Handle h_FmPcd,t_Handle * p_Params,bool stats)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
UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(t_FmPcdManip * p_CrntMdfManip,t_List * h_NodesLst)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
BuildHmtd(uint8_t * p_Dest,uint8_t * p_Src,uint8_t * p_Hmcd,t_FmPcd * p_FmPcd)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
FmPcdManipInitUpdate(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPort,t_Handle h_Manip,t_Handle h_Ad,bool validate,int level,t_Handle h_FmTree)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
FmPcdManipModifyUpdate(t_Handle h_Manip,t_Handle h_Ad,bool validate,int level,t_Handle h_FmTree)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
FmPcdManipUpdate(t_Handle h_FmPcd,t_Handle h_PcdParams,t_Handle h_FmPort,t_Handle h_Manip,t_Handle h_Ad,bool validate,int level,t_Handle h_FmTree,bool modify)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
FmPcdManipUpdateOwner(t_Handle h_Manip,bool add)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
FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)4702 t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
4703 {
4704 ASSERT_COND(h_Manip);
4705 return &((t_FmPcdManip *)h_Manip)->nodesLst;
4706 }
4707
FmPcdManipGetSpinlock(t_Handle h_Manip)4708 t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
4709 {
4710 ASSERT_COND(h_Manip);
4711 return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
4712 }
4713
FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams * p_FmPcdCcNextEngineParams,uint32_t * requiredAction)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
FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,t_Handle h_FmPcdCcNode)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
FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,t_FmPcdCcNextEngineParams * p_CcNextEngineParams,t_Handle p_Ad,t_Handle * p_AdNewPtr)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
FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip,t_Handle p_Ad,t_Handle * p_AdNewPtr,uint32_t adTableOffset)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
FmPcdManipBuildIpReassmScheme(t_FmPcd * p_FmPcd,t_Handle h_NetEnv,t_Handle h_CcTree,t_Handle h_Manip,bool isIpv4,uint8_t groupId)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
FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)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
FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)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
FmPcdManipBuildCapwapReassmScheme(t_FmPcd * p_FmPcd,t_Handle h_NetEnv,t_Handle h_CcTree,t_Handle h_Manip,uint8_t groupId)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
FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)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))
FmPcdManipApplSpecificBuild(void)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
FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)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
FM_PCD_ManipNodeSet(t_Handle h_FmPcd,t_FmPcdManipParams * p_ManipParams)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
FM_PCD_ManipNodeReplace(t_Handle h_Manip,t_FmPcdManipParams * p_ManipParams)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
FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)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
FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,t_FmPcdManipStats * p_FmPcdManipStats)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))
FM_PCD_StatisticsSetNode(t_Handle h_FmPcd,t_FmPcdStatsParams * p_StatsParams)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