xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c (revision d93a896ef95946b0bf1219866fcb324b78543444)
1 /* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
2  * All rights reserved.
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  @File          fm_manip.c
35 
36  @Description   FM PCD manip ...
37 *//***************************************************************************/
38 #ifdef CONFIG_FMAN_P1023
39 #ifdef FM_CAPWAP_SUPPORT
40 #include "std_ext.h"
41 #include "error_ext.h"
42 #include "string_ext.h"
43 #include "debug_ext.h"
44 #include "fm_pcd_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 #ifdef CORE_8BIT_ACCESS_ERRATA
54 #undef WRITE_UINT16
55 #undef GET_UINT16
56 #undef WRITE_UINT8
57 #undef GET_UINT8
58 
59 #define WRITE_UINT16(addr, val)  \
60     do{                             \
61             if((int)&(addr) % 4)    \
62                 WRITE_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L),                                           \
63                         ((GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L)) & 0xffff0000) | (uint32_t)val));  \
64             else                    \
65                 WRITE_UINT32(*(uint32_t*)&addr,                                                                         \
66                         ((GET_UINT32(*(uint32_t*)&addr) & 0x0000ffff) | (uint32_t)val<<16));                            \
67       }while(0);
68 #define GET_UINT16(addr) (((uint32_t)&addr%4) ?           \
69        ((uint16_t)GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L))):  \
70        ((uint16_t)(GET_UINT32(*(uint32_t*)(uint32_t)&addr) >> 16)))
71 
72 #define WRITE_UINT8(addr,val) WRITE_UINT8_ERRATA(&addr,val)
73 #define GET_UINT8(addr) GET_UINT8_ERRATA(&addr)
74 #endif /* CORE_8BIT_ACCESS_ERRATA */
75 
76 
77 static void WRITE_UINT8_ERRATA(uint8_t *addr, uint8_t val)
78 {
79     uint32_t newAddr, newVal;
80     newAddr = (uint32_t)addr & ~0x3L;
81     switch ((uint32_t)addr%4)
82     {
83     case (0):
84         newVal = GET_UINT32(*(uint32_t*)newAddr);
85         newVal = (newVal & 0x00ffffff) | (((uint32_t)val)<<24);
86         WRITE_UINT32(*(uint32_t*)newAddr, newVal);
87         break;
88     case (1):
89          newVal = GET_UINT32(*(uint32_t*)newAddr);
90         newVal = (newVal & 0xff00ffff) | (((uint32_t)val)<<16);
91         WRITE_UINT32(*(uint32_t*)newAddr, newVal);
92         break;
93     case (2):
94         newVal = GET_UINT32(*(uint32_t*)newAddr);
95         newVal = (newVal & 0xffff00ff) | (((uint32_t)val)<<8);
96         WRITE_UINT32(*(uint32_t*)newAddr, newVal);
97         break;
98     case (3):
99         newVal = GET_UINT32(*(uint32_t*)newAddr);
100         newVal = (newVal & 0xffffff00) | val;
101         WRITE_UINT32(*(uint32_t*)newAddr, newVal);
102         break;
103     }
104 }
105 
106 static uint8_t GET_UINT8_ERRATA(uint8_t *addr)
107 {
108     uint32_t newAddr, newVal=0;
109     newAddr = (uint32_t)addr & ~0x3L;
110     switch ((uint32_t)addr%4)
111     {
112     case (0):
113         newVal = GET_UINT32(*(uint32_t*)newAddr);
114         newVal = (newVal & 0xff000000)>>24;
115         break;
116     case (1):
117         newVal = GET_UINT32(*(uint32_t*)newAddr);
118         newVal = (newVal & 0x00ff0000)>>16;
119         break;
120     case (2):
121         newVal = GET_UINT32(*(uint32_t*)newAddr);
122         newVal = (newVal & 0x0000ff00)>>8;
123         break;
124     case (3):
125         newVal = GET_UINT32(*(uint32_t*)newAddr);
126         newVal = (newVal & 0x000000ff);
127         break;
128     }
129 
130     return (uint8_t)newVal;
131 }
132 
133 static t_Error GetPrOffsetByNonHeader(uint8_t *parseArrayOffset)
134 {
135     /*For now - the only field in the Parse Array from the NON_BY_TYPE can be e_FM_PCD_KG_EXTRACT_FROM_CURR_END_OF_PARSE*/
136     /*Maybe extended in the future*/
137 
138     *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
139 
140     return E_OK;
141 }
142 
143 static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
144 {
145     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
146     t_Handle      p_Ad;
147     uint32_t      tmpReg32 = 0;
148     SANITY_CHECK_RETURN_ERROR(h_Manip,E_INVALID_HANDLE);
149     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
150 
151     switch(p_Manip->type)
152     {
153         case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
154             p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
155            if(p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
156             {
157                 tmpReg32 = *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
158                 tmpReg32 |=  (uint32_t)((uint32_t)icOffset << 16);
159                 *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets = tmpReg32;
160                 p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
161                 p_Manip->icOffset = icOffset;
162             }
163             else
164             {
165                 if(p_Manip->icOffset != icOffset)
166                         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
167             }
168             break;
169 #ifdef FM_CAPWAP_SUPPORT
170         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
171             if(p_Manip->h_Frag)
172             {
173                 if(p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
174                 {
175                     p_Ad     = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
176                     tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
177                     tmpReg32 |=  (uint32_t)((uint32_t)icOffset << 16);
178                     WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
179                     p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
180                     p_Manip->icOffset = icOffset;
181                 }
182                 else
183                 {
184                     if(p_Manip->icOffset != icOffset)
185                             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
186                 }
187             }
188             break;
189 #endif /* FM_CAPWAP_SUPPORT */
190     }
191 
192     return E_OK;
193 }
194 
195 static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
196 {
197 
198     t_AdOfTypeContLookup    *p_Ad         = (t_AdOfTypeContLookup *)h_Ad;
199     t_FmPortGetSetCcParams  fmPortGetSetCcParams;
200     t_Error                 err;
201     uint32_t                tmpReg32;
202 
203     memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
204 
205     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
206     SANITY_CHECK_RETURN_ERROR((p_Manip->type & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX), E_INVALID_STATE);
207     SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
208 
209     if(p_Manip->updateParams)
210     {
211         if((!(p_Manip->updateParams & OFFSET_OF_PR)) ||
212            (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
213             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
214 
215         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
216         fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
217         fmPortGetSetCcParams.setCcParams.psoSize = 16;
218 
219         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
220         if(err)
221             RETURN_ERROR(MAJOR, err, NO_MSG);
222         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
223             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Parser result offset wasn't configured previousely"));
224 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
225         ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
226 #endif
227     }
228     else if (validate)
229     {
230          if((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) ||
231            (p_Manip->updateParams & OFFSET_OF_PR))
232             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
233         fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
234         fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
235         fmPortGetSetCcParams.setCcParams.psoSize = 16;
236 
237         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
238         if(err)
239             RETURN_ERROR(MAJOR, err, NO_MSG);
240         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
241             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Parser result offset wasn't configured previousely"));
242 
243     }
244 
245    if(p_Manip->updateParams & OFFSET_OF_PR)
246    {
247         tmpReg32 = 0;
248         tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
249         WRITE_UINT32(p_Ad->matchTblPtr, (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
250         p_Manip->updateParams &= ~OFFSET_OF_PR;
251         p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
252    }
253    else if (validate)
254    {
255         tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
256         if((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
257             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"););
258    }
259 
260     return E_OK;
261 }
262 
263 #ifdef FM_CAPWAP_SUPPORT
264 static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
265 {
266     t_AdOfTypeContLookup            *p_Ad         = (t_AdOfTypeContLookup *)h_Ad;
267     t_FmPcdCcSavedManipParams       *p_SavedManipParams = NULL;
268     uint32_t                        tmpReg32 = 0;
269 
270     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
271     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
272     SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
273     SANITY_CHECK_RETURN_ERROR(((p_Manip->type == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->type == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
274 
275     p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
276 
277     if(p_Manip->updateParams)
278     {
279 
280         if((!(p_Manip->updateParams & OFFSET_OF_DATA) &&
281            !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)) ||
282            ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)))
283             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
284         p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree, e_FM_MANIP_CAPWAP_INDX);
285         if(!p_SavedManipParams)
286             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
287         p_Manip->fragParams.poolId = p_SavedManipParams->capwapParams.poolId;
288         p_Manip->fragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
289 
290         tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
291         tmpReg32 |= ((uint32_t)p_Manip->fragParams.poolId << 8);
292         tmpReg32 |= ((uint32_t)p_Manip->fragParams.dataOffset<< 16);
293         WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
294 
295         p_Manip->updateParams &= ~OFFSET_OF_DATA;
296         p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP;
297         p_Manip->shadowUpdateParams |= (OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP);
298     }
299    else if (validate)
300    {
301 
302         p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree, e_FM_MANIP_CAPWAP_INDX);
303         if(!p_SavedManipParams)
304             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
305         if((p_Manip->fragParams.poolId != p_SavedManipParams->capwapParams.poolId) ||
306            (p_Manip->fragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset))
307             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
308    }
309 
310     return E_OK;
311 }
312 
313 static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate, t_Handle h_FmTree)
314 {
315     t_AdOfTypeContLookup        *p_Ad;
316     t_FmPortGetSetCcParams      fmPortGetSetCcParams;
317     t_Error                     err;
318     uint32_t                    tmpReg32 = 0;
319     t_FmPcdCcSavedManipParams   *p_SavedManipParams;
320 
321     UNUSED(h_Ad);
322 
323     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
324     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
325     SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
326     SANITY_CHECK_RETURN_ERROR(((p_Manip->type == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->type == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
327 
328     p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
329 
330     if(p_Manip->updateParams)
331     {
332         if((!(p_Manip->updateParams & OFFSET_OF_DATA) &&
333            !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)) ||
334            ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)))
335             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
336         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
337         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
338         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
339         fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
340         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
341         if(err)
342             RETURN_ERROR(MAJOR, err, NO_MSG);
343 
344         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
345             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
346         if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
347             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool doe header manipulation wasn't configured previousely"));
348 
349         p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
350         p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
351         p_SavedManipParams->capwapParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip;
352 
353 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
354         ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
355 #endif
356 
357         FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams, e_FM_MANIP_CAPWAP_INDX);
358     }
359     else if (validate)
360     {
361         if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
362             !(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)) ||
363             ((p_Manip->updateParams & OFFSET_OF_DATA) ||
364             (p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)))
365             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
366         fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
367         fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
368         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
369         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
370         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
371         if(err)
372             RETURN_ERROR(MAJOR, err, NO_MSG);
373 
374         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
375             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
376         if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
377             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool doe header manipulation wasn't configured previousely"));
378     }
379 
380     if(p_Manip->updateParams)
381     {
382         tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
383         tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.poolIdForManip << 8);
384         tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
385         WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
386 
387         p_Manip->updateParams &= ~OFFSET_OF_DATA;
388         p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP;
389         p_Manip->shadowUpdateParams |= (OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP);
390         p_Manip->fragParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip;
391         p_Manip->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
392     }
393     else if (validate)
394     {
395         if((p_Manip->fragParams.poolId != fmPortGetSetCcParams.getCcParams.poolIdForManip) ||
396            (p_Manip->fragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset))
397             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
398     }
399 
400     return E_OK;
401 }
402 
403 static t_Error UpdateInitCapwapReasm(t_Handle                   h_FmPcd,
404                                      t_Handle                       h_FmPort,
405                                      t_FmPcdManip                   *p_Manip,
406                                      t_Handle                       h_Ad,
407                                      bool                           validate)
408 {
409     t_CapwapReasmPram  *p_ReassmTbl;
410     t_Error             err;
411     t_FmPortGetSetCcParams  fmPortGetSetCcParams;
412     uint8_t             i = 0;
413     uint16_t            size;
414     uint32_t            tmpReg32;
415     t_FmPcd             *p_FmPcd = (t_FmPcd *)h_FmPcd;
416     t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
417 
418     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
419     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
420     SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
421     SANITY_CHECK_RETURN_ERROR((p_Manip->type == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
422     SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
423     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
424 
425     if(p_Manip->h_FmPcd != h_FmPcd)
426         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("handler of PCD previously was initiated by different value"));
427 
428     UNUSED(h_Ad);
429 
430     memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
431     p_ReassmTbl  = (t_CapwapReasmPram *)p_Manip->h_Frag;
432 
433     if(p_Manip->updateParams)
434     {
435         if((!(p_Manip->updateParams & NUM_OF_TASKS) && !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP) &&
436         !(p_Manip->updateParams & OFFSET_OF_DATA) && !(p_Manip->updateParams & OFFSET_OF_PR) &&
437         !(p_Manip->updateParams & HW_PORT_ID)) ||
438            ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) ||
439            (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR)
440            ||(p_Manip->shadowUpdateParams & HW_PORT_ID)))
441             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
442 
443         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
444         fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
445         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
446         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
447         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
448         if(err)
449             RETURN_ERROR(MAJOR, err, NO_MSG);
450         if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
451             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
452         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
453             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data  wasn't configured previousely"));
454         if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
455             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("buffser pool id  wasn't configured previousely"));
456         if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
457             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
458 #ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
459         ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
460 #endif
461     }
462     else if (validate)
463     {
464          if((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && (!(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)) &&
465          (!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) && (!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) &&
466          (!(p_Manip->shadowUpdateParams & HW_PORT_ID))) &&
467            ((p_Manip->updateParams & NUM_OF_TASKS) ||
468            (p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP) ||
469            (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR)||
470             (p_Manip->updateParams & HW_PORT_ID)))
471 
472             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
473         fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
474         fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
475         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
476         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
477         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
478         if(err)
479             RETURN_ERROR(MAJOR, err, NO_MSG);
480         if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
481             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previousely"));
482         if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
483             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool for header manipulation wasn't configured previousely"));
484         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
485             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data  wasn't configured previousely"));
486         if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
487             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
488     }
489 
490     if(p_Manip->updateParams)
491     {
492         if(p_Manip->updateParams & NUM_OF_TASKS)
493         {
494             size = (uint16_t)(p_Manip->fragParams.maxNumFramesInProcess + fmPortGetSetCcParams.getCcParams.numOfTasks);
495             if(size  > 255)
496                 RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
497 
498             p_Manip->fragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
499 
500             /*p_ReassmFrmDescrIndxPoolTbl*/
501             p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
502                                               (uint32_t)(size + 1),
503                                               4);
504             if(!p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl)
505                 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
506 
507             IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, 0,  (uint32_t)(size + 1));
508 
509             for( i = 0; i < size; i++)
510                 WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
511 
512             tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
513 
514             WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
515 
516             /*p_ReassmFrmDescrPoolTbl*/
517             p_Manip->fragParams.p_ReassmFrmDescrPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
518                                               (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
519                                               4);
520 
521            if(!p_Manip->fragParams.p_ReassmFrmDescrPoolTbl)
522                 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
523 
524             IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl, 0,  (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
525 
526             tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
527 
528             WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
529 
530             /*p_TimeOutTbl*/
531 
532             p_Manip->fragParams.p_TimeOutTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
533                                               (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
534                                               4);
535 
536             if(!p_Manip->fragParams.p_TimeOutTbl)
537                 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
538 
539             IOMemSet32(p_Manip->fragParams.p_TimeOutTbl, 0,  (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
540 
541             tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
542             WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
543 
544 
545             p_Manip->updateParams &= ~NUM_OF_TASKS;
546             p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
547        }
548 
549        if(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)
550        {
551 
552             p_Manip->fragParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip;
553 
554             tmpReg32 = GET_UINT32(p_ReassmTbl->bufferPoolIdAndRisc1SetIndexes);
555             tmpReg32 |= (uint32_t)p_Manip->fragParams.poolId << 16;
556             WRITE_UINT32(p_ReassmTbl->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
557 
558             p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP;
559             p_Manip->shadowUpdateParams |= BUFFER_POOL_ID_FOR_MANIP;
560        }
561 
562         if(p_Manip->updateParams & OFFSET_OF_DATA)
563         {
564             p_Manip->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
565             tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
566             tmpReg32|= p_Manip->fragParams.dataOffset;
567             WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
568             p_Manip->updateParams &= ~OFFSET_OF_DATA;
569             p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
570         }
571         if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
572         {
573             p_Manip->fragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
574 
575             tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
576             tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
577             WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
578 
579             tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
580             tmpReg32 |= (uint32_t)p_Manip->fragParams.prOffset << 24;
581             WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
582            p_Manip->updateParams &= ~OFFSET_OF_PR;
583            p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
584        }
585        else
586        {
587            p_Manip->fragParams.prOffset = 0xff;
588            p_Manip->updateParams &= ~OFFSET_OF_PR;
589            p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
590 
591        }
592 
593         p_Manip->fragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
594         p_Manip->updateParams &= ~HW_PORT_ID;
595         p_Manip->shadowUpdateParams |= HW_PORT_ID;
596 
597         /*timeout hc */
598        ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->fragParams.fqidForTimeOutFrames;
599        ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->fragParams.hwPortId << 24;
600        ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
601        ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->fragParams.bitFor1Micro) * p_Manip->fragParams.timeoutRoutineRequestTime)/2;
602        return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
603 
604     }
605     else if(validate)
606     {
607         if(fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->fragParams.hwPortId)
608             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
609         if(fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->fragParams.numOfTasks)
610             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
611 
612         if(fmPortGetSetCcParams.getCcParams.poolIdForManip != p_Manip->fragParams.poolId)
613             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("poolId for this manipulation previously was defined by another value "));
614 
615         if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
616         {
617             if(p_Manip->fragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
618                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
619         }
620         else
621         {
622             if(p_Manip->fragParams.prOffset != 0xff)
623                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
624         }
625         if(fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->fragParams.dataOffset)
626                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
627     }
628 
629     return E_OK;
630 }
631 #endif /* FM_CAPWAP_SUPPORT */
632 
633 #if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
634 static t_Error UpdateInitIPSec(t_Handle h_FmPort, t_FmPcdManip *p_Manip)
635 {
636     SANITY_CHECK_RETURN_ERROR(h_FmPort,E_INVALID_HANDLE);
637     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
638     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
639     SANITY_CHECK_RETURN_ERROR(p_Manip->type == HMAN_OC_IPSEC, E_INVALID_STATE);
640 
641     /*
642     if(p_Manip->cnia)
643     {
644         p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
645 
646         WRITE_UINT32(p_Ad->ccAdBase, GET_UINT32(p_Ad->ccAdBase) | FM_PCD_MANIP_IPSEC_CNIA);
647     }
648 */
649     return E_OK;
650 }
651 #endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))*/
652 
653 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
654 static t_Error UpdateInitIpFragmentation(t_Handle h_FmPort, t_FmPcdManip *p_Manip)
655 {
656     t_FmPortGetSetCcParams      fmPortGetSetCcParams;
657     t_Error                     err;
658     uint32_t                    tmpReg32 = 0;
659 
660     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
661     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
662     SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
663     SANITY_CHECK_RETURN_ERROR(p_Manip->type == HMAN_OC_IP_FRAGMENTATION, E_INVALID_STATE);
664 
665     fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
666     fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
667     err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
668     if(err)
669         RETURN_ERROR(MAJOR, err, NO_MSG);
670 
671     return E_OK;
672 }
673 
674 static t_Error CreateIpReassCommonParamTable(t_FmPcdManip *p_Manip,
675                                              t_FmPcd *p_FmPcd ,
676                                              t_IpReasmCommonTbl *p_IpReasmCommonPramTbl)
677 {
678     uint32_t    tmpReg32 = 0, i;
679     uint64_t    tmpReg64, size;
680 
681     p_Manip->ipReassmParams.h_IpReassCommonParamsTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
682                                                        FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE,
683                                                        FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_ALIGN);
684 
685     if(!p_Manip->ipReassmParams.h_IpReassCommonParamsTbl)
686         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
687 
688     p_IpReasmCommonPramTbl = (t_IpReasmCommonTbl *)(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl);
689 
690     IOMemSet32(p_IpReasmCommonPramTbl, 0,  FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE);
691 
692     tmpReg32 = 0;
693     if(p_Manip->ipReassmParams.timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
694         tmpReg32 |= FM_PCD_MANIP_IP_REASM_TIME_OUT_BETWEEN_FRAMES;
695 
696     tmpReg32 |= p_Manip->ipReassmParams.fqidForTimeOutFrames;
697     WRITE_UINT32(p_IpReasmCommonPramTbl->timeoutModeAndFqid, tmpReg32);
698 
699 
700     size = p_Manip->ipReassmParams.maxNumFramesInProcess + 129;
701 
702     /*p_ReassmFrmDescrIndxPoolTbl */
703     p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
704                                       (uint32_t)(size * 2),
705                                       256);
706     if(!p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl)
707         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
708 
709     IOMemSet32(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl, 0,  (uint32_t)(size * 2));
710 
711     for( i = 0; i < size - 1; i++)
712         WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
713 
714     tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
715 
716     WRITE_UINT32(p_IpReasmCommonPramTbl->reassFrmDescIndexPoolTblPtr, tmpReg32);
717 
718     /*p_ReassmFrmDescrPoolTbl*/
719     p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl = (t_Handle)XX_MallocSmart((uint32_t)(size * 32), p_Manip->ipReassmParams.dataMemId, 32);
720 
721     if(!p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl)
722         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
723 
724     IOMemSet32(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl, 0,  (uint32_t)(size * 32));
725 
726     tmpReg64 = (uint64_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl));
727     tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT);
728     tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT);
729     WRITE_UINT32(p_IpReasmCommonPramTbl->liodnAndReassFrmDescPoolPtrHi, (uint32_t)(tmpReg64 >> 32));
730     WRITE_UINT32(p_IpReasmCommonPramTbl->reassFrmDescPoolPtrLow, (uint32_t)tmpReg64);
731 
732     /*p_TimeOutTbl*/
733     p_Manip->ipReassmParams.h_TimeOutTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
734                                            (uint32_t)(size  * 8),8);
735 
736     if(!p_Manip->ipReassmParams.h_TimeOutTbl)
737         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
738 
739     IOMemSet32(p_Manip->ipReassmParams.h_TimeOutTbl, 0,  (uint16_t)(size * 8));
740 
741     tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_TimeOutTbl) - p_FmPcd->physicalMuramBase);
742     WRITE_UINT32(p_IpReasmCommonPramTbl->timeOutTblPtr, tmpReg32);
743 
744     /* Expiration Delay */
745     tmpReg32 = 0;
746     tmpReg32 |= p_Manip->ipReassmParams.timeoutThresholdForReassmProcess;
747     WRITE_UINT32(p_IpReasmCommonPramTbl->expirationDelay, tmpReg32);
748 
749     /* Counts the number of TimeOut occurrences - Must be initialized to zero.*/
750     WRITE_UINT32(p_IpReasmCommonPramTbl->totalTimeOutCounter, 0);
751     /* Counts the number of failed attempts to allocate a Reassembly Frame Descriptor - Must be initialized to zero.*/
752     WRITE_UINT32(p_IpReasmCommonPramTbl->totalRfdPoolBusyCounter, 0);
753     /* Counts the number of times an internal buffer busy occured.*/
754     WRITE_UINT32(p_IpReasmCommonPramTbl->totalInternalBufferBusy, 0);
755     /* Counts the number of times external buffer busy occured. */
756     WRITE_UINT32(p_IpReasmCommonPramTbl->totalExternalBufferBusy, 0);
757 
758     return E_OK;
759 }
760 
761 static t_Error CreateIpReassParamTable(t_FmPcdManip *p_Manip, t_Handle h_IpReassParamsTblPtr, bool ipv4)
762 {
763     t_IpReasmPram           *p_Table;
764     t_AdOfTypeContLookup    *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
765     t_FmPcd                 *p_FmPcd = p_Manip->h_FmPcd;
766     uint32_t                tmpReg32, autoLearnHashTblSize;
767     uint32_t                numOfWays, setSize, setSizeCode, tmpSetSize;
768     uint32_t                waySize, numOfSets, tmpNumOfSets, numOfEntries;
769     uint64_t                tmpReg64;
770     t_Handle                h_AutoLearnHashTbl, h_AutoLearnSetLockTblPtr;
771 
772     /*Pointer to fragment ID*/
773     h_IpReassParamsTblPtr = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
774                                                         FM_PCD_MANIP_IP_REASM_TABLE_SIZE,
775                                                         FM_PCD_MANIP_IP_REASM_TABLE_ALIGN);
776 
777     if(!h_IpReassParamsTblPtr)
778         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
779 
780     IOMemSet32(h_IpReassParamsTblPtr, 0, FM_PCD_MANIP_IP_REASM_TABLE_SIZE);
781 
782     p_Table = (t_IpReasmPram *)h_IpReassParamsTblPtr;
783 
784     tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl) - p_FmPcd->physicalMuramBase);
785     WRITE_UINT32(((t_IpReasmPram *)h_IpReassParamsTblPtr)->ipReassCommonPrmTblPtr, tmpReg32);
786 
787     /* waysNumAndSetSize calculation */
788     numOfWays = p_Manip->ipReassmParams.numOfFramesPerHashEntry;
789 
790     /*It is recommended that the total number of entries in this table
791     (number of sets * number of ways) will be twice the number of frames that
792      are expected to be reassembled simultaneously.*/
793     numOfEntries = (uint32_t)(p_Manip->ipReassmParams.maxNumFramesInProcess * 2);
794 
795     /* sets number calculation - number of entries = number of sets * number of ways */
796     numOfSets = numOfEntries / numOfWays;
797 
798     /*TODO - Handle way size*/
799     switch(p_Manip->ipReassmParams.hdr)
800     {
801         case(HEADER_TYPE_IPv6):
802             /* WaySize is rounded-up to next multiple of 8 */
803             waySize = ROUND_UP(((16 + 16 + 4 + 2) /* * numOfWays*/),8);
804             break;
805         case(HEADER_TYPE_IPv4):
806             break;
807         default:
808             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
809     }
810     /* Set size is rounded-up to next power of 2 */
811     LOG2(numOfWays * waySize, tmpSetSize);
812     setSize =  (uint32_t)(1 << (tmpSetSize + (POWER_OF_2(numOfWays * waySize) ? 0 : 1)));
813 
814     LOG2(setSize, setSizeCode);
815     WRITE_UINT16(((t_IpReasmPram *)p_Table)->waysNumAndSetSize, (uint16_t)((numOfWays << 8) | setSizeCode));
816 
817     LOG2(numOfSets, tmpNumOfSets);
818     numOfSets = (uint32_t)(1 << (tmpNumOfSets + (POWER_OF_2(numOfSets) ? 0 : 1)));
819 
820     WRITE_UINT16(((t_IpReasmPram *)p_Table)->autoLearnHashKeyMask, (uint16_t)(numOfSets - 1));
821 
822     /*autoLearnHashTbl allocation
823     Table size = set size * number of sets
824     This table�s base address should be aligned to SetSize.*/
825     autoLearnHashTblSize = numOfSets * setSize;
826 
827     if (ipv4)
828         h_AutoLearnHashTbl = p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl;
829     else
830         h_AutoLearnHashTbl = p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl;
831 
832     h_AutoLearnHashTbl = (t_Handle)XX_MallocSmart(autoLearnHashTblSize, p_Manip->ipReassmParams.dataMemId, setSizeCode);
833 
834     if(!h_AutoLearnHashTbl)
835         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
836 
837     IOMemSet32(h_AutoLearnHashTbl, 0,  autoLearnHashTblSize);
838 
839     tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT);
840     tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT);
841     tmpReg64 |= XX_VirtToPhys(h_AutoLearnHashTbl);
842     WRITE_UINT32(((t_IpReasmPram *)p_Table)->liodnAlAndAutoLearnHashTblPtrHi, (uint32_t)(tmpReg64 >> 32));
843     WRITE_UINT32(((t_IpReasmPram *)p_Table)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
844 
845     /* AutoLearnSetLockTbl allocation - The size of this table is (number of sets in the IP
846     Reassembly Automatic Learning Hash table)*4 bytes. This table resides in external memory
847     and its base address should be 4-byte aligned */
848     if (ipv4)
849         h_AutoLearnSetLockTblPtr = p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr;
850     else
851         h_AutoLearnSetLockTblPtr = p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr;
852 
853     h_AutoLearnSetLockTblPtr = (t_Handle)XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->ipReassmParams.dataMemId, 4);
854 
855     if(!h_AutoLearnSetLockTblPtr)
856         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
857 
858     IOMemSet32(h_AutoLearnSetLockTblPtr, 0,  (numOfSets * 4));
859 
860     tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT);
861     tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT);
862     tmpReg64 |= XX_VirtToPhys(h_AutoLearnSetLockTblPtr);
863     WRITE_UINT32(((t_IpReasmPram *)p_Table)->liodnSlAndAutoLearnSetLockTblPtrHi, (uint32_t)(tmpReg64 >> 32));
864     WRITE_UINT32(((t_IpReasmPram *)p_Table)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
865 
866     /* Setting the First/Middle fragment minimum size in Bytes */
867     WRITE_UINT32(((t_IpReasmPram *)p_Table)->minFragSize, p_Manip->ipReassmParams.minFragSize);
868 
869     /* Zeroes all counters */
870     WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalSuccessfullyReasmFramesCounter, 0);
871     WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalValidFragmentCounter, 0);
872     WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalProcessedFragCounter, 0);
873     WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalMalformdFragCounter, 0);
874     WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalSetBusyCounter, 0);
875     WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalDiscardedFragsCounter, 0);
876     WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalMoreThan16FramesCounter, 0);
877 
878     return E_OK;
879 }
880 
881 static t_Error UpdateInitIpReasm(t_Handle       h_FmPcd,
882                                  t_Handle       h_FmPort,
883                                  t_FmPcdManip   *p_Manip,
884                                  t_Handle       h_Ad,
885                                  bool           validate)
886 {
887     t_AdOfTypeContLookup        *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
888     t_IpReasmCommonTbl          *p_ReassmCommonTbl = NULL;
889     t_FmPortGetSetCcParams      fmPortGetSetCcParams;
890     uint8_t                     i = 0;
891     uint32_t                    tmpReg32;
892     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
893     t_Error                     err;
894 
895     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
896     SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
897     SANITY_CHECK_RETURN_ERROR((p_Manip->type == HMAN_OC_IP_REASSEMBLY), E_INVALID_STATE);
898     SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
899     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
900 
901     UNUSED(h_Ad);
902 
903     if(p_Manip->h_FmPcd != h_FmPcd)
904         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("handler of PCD previously was initiated by different value"));
905 
906     memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
907 
908 
909     if(p_Manip->updateParams)
910     {
911         if((!(p_Manip->updateParams & OFFSET_OF_DATA) && !(p_Manip->updateParams & OFFSET_OF_PR) &&
912         !(p_Manip->updateParams & HW_PORT_ID)) ||
913            ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) ||
914            (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR)
915            ||(p_Manip->shadowUpdateParams & HW_PORT_ID)))
916             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
917 
918         fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
919         fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
920         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
921         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
922         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_RFENE;
923         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CLOSING_FRAG_CHECK;
924         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
925         if(err)
926             RETURN_ERROR(MAJOR, err, NO_MSG);
927         if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
928             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
929         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
930             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data  wasn't configured previousely"));
931         if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
932             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
933 
934     }
935     else if (validate)
936     {
937          if((!(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) &&
938          (!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) && (!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) &&
939          (!(p_Manip->shadowUpdateParams & HW_PORT_ID))) &&
940            ((p_Manip->updateParams & NUM_OF_TASKS) ||
941            (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR)||
942             (p_Manip->updateParams & HW_PORT_ID)))
943             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
944 
945         fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
946         fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
947         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
948         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
949         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_RFENE;
950         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CLOSING_FRAG_CHECK;
951         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
952         if(err)
953             RETURN_ERROR(MAJOR, err, NO_MSG);
954         if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
955             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previousely"));
956         if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
957             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data  wasn't configured previousely"));
958         if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
959             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
960     }
961 
962     if(p_Manip->updateParams)
963     {
964         if(p_Manip->updateParams & OFFSET_OF_DATA)
965         {
966             p_Manip->ipReassmParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
967             tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
968             tmpReg32 |= p_Manip->ipReassmParams.dataOffset;
969             WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
970 
971             p_Manip->updateParams &= ~OFFSET_OF_DATA;
972             p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
973         }
974 
975         p_Manip->updateParams &= ~HW_PORT_ID;
976         p_Manip->shadowUpdateParams |= HW_PORT_ID;
977     }
978     else
979     {
980         if(validate)
981         {
982             /* TODO - Handle validate..*/
983             /*if(fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->fragParams.hwPortId)
984                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
985             if(fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->fragParams.numOfTasks)
986                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
987 
988             if(fmPortGetSetCcParams.getCcParams.poolIdForManip != p_Manip->fragParams.poolId)
989                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("poolId for this manipulation previously was defined by another value "));
990 
991             if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
992             {
993                 if(p_Manip->fragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
994                     RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
995             }
996             else
997             {
998                 if(p_Manip->fragParams.prOffset != 0xff)
999                     RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
1000             }
1001             if(fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->fragParams.dataOffset)
1002                     RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));*/
1003 
1004         }
1005     }
1006 
1007     return E_OK;
1008 }
1009 #endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
1010 
1011 static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
1012 {
1013     if(p_Manip->h_Ad)
1014     {
1015         if(p_Manip->muramAllocate)
1016             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
1017         else
1018             XX_Free(p_Manip->h_Ad);
1019         p_Manip->h_Ad = NULL;
1020     }
1021     if(p_Manip->p_Template)
1022     {
1023         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
1024         p_Manip->p_Template = NULL;
1025     }
1026     if(p_Manip->h_Frag)
1027     {
1028         if(p_Manip->fragParams.p_AutoLearnHashTbl)
1029             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_AutoLearnHashTbl);
1030         if(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl)
1031             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrPoolTbl);
1032         if(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl)
1033             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl);
1034         if(p_Manip->fragParams.p_TimeOutTbl)
1035             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_TimeOutTbl);
1036         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
1037 
1038     }
1039 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
1040     if (p_Manip->ipFragParams.h_Frag)
1041     {
1042         if(p_Manip->ipFragParams.h_FragId)
1043             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipFragParams.h_FragId);
1044         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipFragParams.h_Frag);
1045     }
1046     if (p_Manip->reassm)
1047     {
1048         if(p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl)
1049             XX_Free(p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl);
1050         if(p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl)
1051             XX_Free(p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl);
1052         if(p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr)
1053             XX_Free(p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr);
1054         if(p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr)
1055             XX_Free(p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr);
1056         if(p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr)
1057             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr);
1058         if(p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr)
1059             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr);
1060         if(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl)
1061             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_IpReassCommonParamsTbl);
1062         if(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl)
1063             FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl);
1064         if(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl)
1065             XX_Free(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl);
1066     }
1067 #endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
1068     if(p_Manip->p_StatsTbl)
1069         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
1070 }
1071 
1072 static t_Error CheckManipParamsAndSetType(t_FmPcdManip  *p_Manip, t_FmPcdManipParams *p_ManipParams)
1073 {
1074 
1075     if(p_ManipParams->rmv)
1076     {
1077         switch(p_ManipParams->rmvParams.type)
1078         {
1079             case(e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION):
1080                 switch(p_ManipParams->rmvParams.rmvSpecificLocationParams.type)
1081                 {
1082                     case(e_FM_PCD_MANIP_LOC_BY_HDR) :
1083                         switch(p_ManipParams->rmvParams.rmvSpecificLocationParams.manipByHdr.hdr)
1084                         {
1085                             case(HEADER_TYPE_CAPWAP_DTLS) :
1086 
1087                                 p_Manip->type = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
1088                                 p_Manip->muramAllocate = TRUE;
1089 
1090                                 if(p_ManipParams->insrt)
1091                                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for  CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
1092 
1093                                 if(p_ManipParams->fragOrReasm)
1094                                 {
1095                                     if(!p_ManipParams->fragOrReasmParams.frag)
1096                                     {
1097                                         switch(p_ManipParams->fragOrReasmParams.hdr)
1098                                         {
1099                                             case(HEADER_TYPE_CAPWAP):
1100                                                 p_Manip->type = HMAN_OC_CAPWAP_REASSEMBLY;
1101                                                 break;
1102                                             default:
1103                                                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
1104                                         }
1105                                     }
1106                                     else
1107                                         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
1108                                 }
1109                             break;
1110                             default:
1111                                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
1112 
1113                         }
1114                         break;
1115                         default:
1116                             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid type of remove location"));
1117 
1118                 }
1119             break;
1120             case(e_FM_PCD_MANIP_RMV_INT_FRAME_HDR) :
1121                 if(p_ManipParams->insrt || p_ManipParams->fragOrReasm)
1122                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For the type of remove e_FM_PCD_MANIP_RMV_INT_FRAME_HDR the only valid option rmv = TRUE, insrt = FALSE, fragOrReasm = FALSE"));
1123                 p_Manip->type = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
1124                 p_Manip->muramAllocate = FALSE;
1125             break;
1126             case(e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION) :
1127                 if  (p_ManipParams->fragOrReasm ||
1128                     ((p_ManipParams->insrt) && p_ManipParams->insrtParams.type != e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR))
1129                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION the only allowed insertion type is e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR"));
1130                 p_Manip->type = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
1131                 p_Manip->muramAllocate = TRUE;
1132            break;
1133            default:
1134                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
1135         }
1136     }
1137     else if(p_ManipParams->insrt)
1138     {
1139         switch(p_ManipParams->insrtParams.type)
1140         {
1141             case(e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE) :
1142 
1143                 p_Manip->type = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
1144                 p_Manip->muramAllocate = FALSE;
1145 
1146                 if(p_ManipParams->fragOrReasm)
1147                 {
1148                     if(p_ManipParams->fragOrReasmParams.frag)
1149                     {
1150                            switch(p_ManipParams->fragOrReasmParams.hdr)
1151                            {
1152                                 case(HEADER_TYPE_CAPWAP):
1153                                     p_Manip->type = HMAN_OC_CAPWAP_FRAGMENTATION;
1154                                     break;
1155                                 break;
1156                                 default:
1157                                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
1158                            }
1159                     }
1160                     else
1161                         RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
1162                 }
1163             break;
1164             case(e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR) :
1165                 if(p_ManipParams->fragOrReasm)
1166                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of insert can not be fragOrReasm = TRUE"));
1167                 p_Manip->type = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
1168                 p_Manip->muramAllocate = TRUE;
1169             break;
1170             default:
1171                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
1172         }
1173     }
1174     else if(p_ManipParams->fragOrReasm)
1175     {
1176         if(p_ManipParams->fragOrReasmParams.frag)
1177         {
1178             switch(p_ManipParams->fragOrReasmParams.hdr)
1179              {
1180                  case(HEADER_TYPE_CAPWAP):
1181                      p_Manip->type = HMAN_OC_CAPWAP_FRAGMENTATION;
1182                      p_Manip->muramAllocate = FALSE;
1183                  break;
1184 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
1185                  case(HEADER_TYPE_IPv4):
1186                      p_Manip->type = HMAN_OC_IP_FRAGMENTATION;
1187                      p_Manip->muramAllocate = TRUE;
1188                  break;
1189 #endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
1190                  default:
1191                      RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
1192              }
1193         }
1194         else
1195         {
1196             switch (p_ManipParams->fragOrReasmParams.hdr)
1197             {
1198                 case(HEADER_TYPE_CAPWAP):
1199                     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"));
1200 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
1201                 case(HEADER_TYPE_IPv4):
1202                     p_Manip->type = HMAN_OC_IP_REASSEMBLY;
1203                     p_Manip->muramAllocate = TRUE;
1204                     p_Manip->ipReassmParams.hdr = HEADER_TYPE_IPv4;
1205                     break;
1206                 case(HEADER_TYPE_IPv6):
1207                     p_Manip->type = HMAN_OC_IP_REASSEMBLY;
1208                     p_Manip->muramAllocate = TRUE;
1209                     p_Manip->ipReassmParams.hdr = HEADER_TYPE_IPv6;
1210                     break;
1211 #endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
1212                 default:
1213                      RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
1214 
1215             }
1216         }
1217 
1218     }
1219     else
1220         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
1221 
1222     p_Manip->insrt = p_ManipParams->insrt;
1223     p_Manip->rmv   = p_ManipParams->rmv;
1224 
1225     return E_OK;
1226 }
1227 static t_Error UpdateIndxStats(  t_Handle                       h_FmPcd,
1228                                  t_Handle                       h_FmPort,
1229                                  t_FmPcdManip                   *p_Manip)
1230 {
1231     t_FmPcd                 *p_FmPcd = (t_FmPcd *)h_FmPcd;
1232     uint32_t                tmpReg32 = 0;
1233     t_AdOfTypeContLookup    *p_Ad;
1234     t_FmPortGetSetCcParams  fmPortGetSetCcParams;
1235     t_Error                 err;
1236 
1237     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
1238     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1239 
1240     p_Ad    = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1241     if(p_Manip->h_FmPcd != h_FmPcd)
1242         RETURN_ERROR(MAJOR, E_INVALID_STATE,
1243                      ("handler of PCD previously was initiated by different value"));
1244 
1245     memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
1246 
1247     if(!p_Manip->p_StatsTbl)
1248     {
1249 
1250         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
1251         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
1252         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1253         if(err)
1254             RETURN_ERROR(MAJOR, err, NO_MSG);
1255 
1256         tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
1257 
1258         p_Manip->p_StatsTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1259                                           (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
1260                                           4);
1261         if(!p_Manip->p_StatsTbl)
1262             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1263 
1264         IOMemSet32(p_Manip->p_StatsTbl, 0,  (uint32_t)(p_Manip->owner * 4));
1265 
1266         tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
1267 
1268         if(p_Manip->cnia)
1269             tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
1270 
1271         tmpReg32 |=  FM_PCD_MANIP_INDEXED_STATS_DPD;
1272         WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
1273 
1274     }
1275     else
1276     {
1277         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
1278         fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
1279         err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
1280         if(err)
1281             RETURN_ERROR(MAJOR, err, NO_MSG);
1282     }
1283     return E_OK;
1284 }
1285 
1286 static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree)
1287 {
1288     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
1289     t_Error      err = E_OK;
1290 
1291     SANITY_CHECK_RETURN_ERROR(h_Manip,E_INVALID_HANDLE);
1292     UNUSED(h_FmPcd);
1293     UNUSED(h_FmTree);
1294 
1295     switch(p_Manip->type)
1296     {
1297         case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
1298         if(level != 1)
1299             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree"));
1300         err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort, p_Manip, h_Ad, validate);
1301         break;
1302 #ifdef FM_CAPWAP_SUPPORT
1303         case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
1304             if(!p_Manip->h_Frag)
1305                 break;
1306         case(HMAN_OC_CAPWAP_FRAGMENTATION):
1307             if(level != 2)
1308                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP fragmentation the manipulation has to be in the first level of the tree"));
1309             err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
1310         break;
1311         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
1312             if(p_Manip->h_Frag)
1313             {
1314                 if(level != 2)
1315                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree"));
1316                 err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
1317             }
1318             break;
1319 #endif /* FM_CAPWAP_SUPPORT */
1320 #if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
1321         case(HMAN_OC_IPSEC):
1322             err = UpdateInitIPSec(h_FmPort, p_Manip);
1323             if (err != E_OK)
1324                 RETURN_ERROR(MAJOR, err, ("UpdateInitIPSec failed"));
1325             if(!p_Manip->h_Frag)
1326                 break;
1327 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
1328         case(HMAN_OC_IP_FRAGMENTATION):
1329             err = UpdateInitIpFragmentation(h_FmPort, p_Manip);
1330             break;
1331         case(HMAN_OC_IP_REASSEMBLY):
1332             err = UpdateInitIpReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
1333             break;
1334 #endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
1335 #endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))*/
1336         case(HMAN_OC_CAPWAP_INDEXED_STATS):
1337             if(level != 2)
1338                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For index statistics the manipulation has to be in the first level of the tree"));
1339             err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
1340             break;
1341         default:
1342             return E_OK;
1343     }
1344     return err;
1345 }
1346 
1347 static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree)
1348 {
1349 
1350     t_FmPcdManip    *p_Manip = (t_FmPcdManip *)h_Manip;
1351     t_Error         err = E_OK;
1352 
1353     switch(p_Manip->type)
1354     {
1355         case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
1356             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("modify node with this type of manipulation  is not suppported"));
1357         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
1358 
1359            if(p_Manip->h_Frag)
1360            {
1361                if(!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && !(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) &&
1362                !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
1363                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("modify node with this type of manipulation requires manipulation be updated previousely in SetPcd function"));
1364                 if(level != 2)
1365                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree"));
1366            }
1367            break;
1368 #ifdef FM_CAPWAP_SUPPORT
1369         case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
1370             if(p_Manip->h_Frag)
1371             {
1372                 if(level != 2)
1373                     RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP fragmentation the manipulation has to be in the first level of the tree"));
1374                 err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
1375             }
1376             break;
1377 #endif /* FM_CAPWAP_SUPPORT */
1378         default:
1379             return E_OK;
1380 
1381     }
1382     return err;
1383 
1384 }
1385 
1386 static t_Error GetPrOffsetByHeaderOrField(t_FmPcdManipLocationParams *p_ManipParams, uint8_t *parseArrayOffset)
1387 {
1388     e_NetHeaderType hdr         = p_ManipParams->manipByHdr.hdr;
1389     e_FmPcdHdrIndex hdrIndex    = p_ManipParams->manipByHdr.hdrIndex;
1390     bool            byField     = p_ManipParams->manipByHdr.byField;
1391     t_FmPcdFields   field;
1392 
1393     if(byField)
1394         field = p_ManipParams->manipByHdr.fullField;
1395 
1396     if(byField)
1397     {
1398         switch(hdr)
1399         {
1400             case(HEADER_TYPE_ETH):
1401                 switch(field.eth)
1402                 {
1403                     case(NET_HEADER_FIELD_ETH_TYPE):
1404                         *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
1405                         break;
1406                     default:
1407                         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of the type Ethernet with this field not supported"));
1408                 }
1409                 break;
1410             case(HEADER_TYPE_VLAN):
1411                 switch(field.vlan)
1412                 {
1413                     case(NET_HEADER_FIELD_VLAN_TCI) :
1414                         if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
1415                             *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
1416                         else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
1417                              *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
1418                         break;
1419                     default:
1420                        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of the type VLAN with this field not supported"));
1421                 }
1422                 break;
1423            default:
1424                RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of this header by field not supported"));
1425         }
1426     }
1427     else
1428     {
1429         switch(hdr){
1430              case(HEADER_TYPE_ETH):
1431                  *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
1432                 break;
1433             case(HEADER_TYPE_USER_DEFINED_SHIM1):
1434                 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
1435                 break;
1436             case(HEADER_TYPE_USER_DEFINED_SHIM2):
1437                 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
1438                 break;
1439             /* TODO - to take care about SHIM3
1440             case(HEADER_TYPE_USER_DEFINED_SHIM3):
1441                 *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM3_OFFSET;
1442                 break;
1443             */
1444             case(HEADER_TYPE_LLC_SNAP):
1445                 *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
1446                 break;
1447             case(HEADER_TYPE_PPPoE):
1448                 *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
1449                 break;
1450             case(HEADER_TYPE_MPLS):
1451                  if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
1452                         *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
1453                 else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
1454                         *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
1455                 break;
1456             case(HEADER_TYPE_IPv4):
1457             case(HEADER_TYPE_IPv6):
1458               if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
1459                     *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
1460               else if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
1461                     *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
1462                 break;
1463             case(HEADER_TYPE_MINENCAP):
1464                 *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
1465                 break;
1466             case(HEADER_TYPE_GRE):
1467                 *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
1468                 break;
1469             case(HEADER_TYPE_TCP):
1470             case(HEADER_TYPE_UDP):
1471             case(HEADER_TYPE_IPSEC_AH):
1472             case(HEADER_TYPE_IPSEC_ESP):
1473             case(HEADER_TYPE_DCCP):
1474             case(HEADER_TYPE_SCTP):
1475                 *parseArrayOffset = CC_PC_PR_L4_OFFSET;
1476                 break;
1477             default:
1478                 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of this header is not supported"));
1479      }
1480     }
1481     return E_OK;
1482 }
1483 
1484 static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipRmvParams  *p_ManipParams, t_FmPcdManip *p_Manip)
1485 {
1486     t_AdOfTypeContLookup    *p_Ad;
1487     uint32_t                tmpReg32 = 0;
1488     uint8_t                 prsArrayOffset = 0;
1489     t_Error                 err;
1490 
1491     SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
1492     SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
1493     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1494 
1495     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1496     if(p_Manip->rmv)
1497     {
1498         switch(p_ManipParams->rmvSpecificLocationParams.type)
1499         {
1500             case(e_FM_PCD_MANIP_LOC_BY_HDR) :
1501                 err = GetPrOffsetByHeaderOrField(&p_ManipParams->rmvSpecificLocationParams, &prsArrayOffset);
1502                 break;
1503             case(e_FM_PCD_MANIP_LOC_NON_HDR) :
1504                 err = GetPrOffsetByNonHeader(&prsArrayOffset);
1505                 break;
1506             default :
1507                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid type of location header manipulation of type Remove"));
1508         }
1509         if(err)
1510             RETURN_ERROR(MAJOR, err, NO_MSG);
1511 
1512         tmpReg32 |= (uint32_t)prsArrayOffset << 24;
1513         tmpReg32 |= HMAN_RMV_HDR;
1514     }
1515 
1516     if(p_Manip->insrt)
1517         tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
1518 
1519     tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
1520 
1521     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
1522 
1523     tmpReg32 = 0;
1524     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1525     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
1526 
1527     return E_OK;
1528 }
1529 
1530 static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip, bool caamUsed)
1531 {
1532     t_AdOfTypeContLookup    *p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1533     uint32_t                tmpReg32 = 0;
1534 
1535     SANITY_CHECK_RETURN_ERROR(p_Ad,E_INVALID_HANDLE);
1536 
1537     p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
1538 
1539     tmpReg32 = 0;
1540     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1541     *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
1542 
1543     /*TODO - update offsetInBufferPrefixForIntFrameHdr when port connected to tree
1544     tmpReg32 = 0;
1545     tmpReg32 |= offsetInBufferPrefixForIntFrameHdr;
1546     *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;*/
1547 
1548     tmpReg32 = 0;
1549     tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
1550     tmpReg32 |= (uint32_t)0x16 << 16;
1551     *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
1552 
1553     if (caamUsed)
1554         *(uint32_t *)&p_Ad->gmask = 0xf0000000;
1555 
1556     return E_OK;
1557 }
1558 
1559 #ifdef FM_CAPWAP_SUPPORT
1560 static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
1561 {
1562     t_AdOfTypeContLookup    *p_Ad;
1563     uint32_t                tmpReg32 = 0;
1564     t_Error                 err = E_OK;
1565 
1566     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1567 
1568     p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1569 
1570     tmpReg32 = 0;
1571     tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
1572     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
1573 
1574     tmpReg32 = 0;
1575     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1576 
1577 
1578     if(p_Manip->h_Frag)
1579     {
1580         p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
1581         tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
1582     }
1583 
1584     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
1585 
1586     return err;
1587 }
1588 
1589 static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd, uint8_t poolIndex)
1590 {
1591     t_Handle    p_Table;
1592     uint32_t    tmpReg32 = 0;
1593     int         i = 0;
1594     uint8_t     log2Num;
1595     uint8_t     numOfSets;
1596     uint32_t    j = 0;
1597 
1598     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1599     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
1600 
1601     if(!p_FmPcd->h_Hc)
1602         RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
1603     if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
1604         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
1605     if(!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
1606         RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
1607     if(!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
1608         DBG(WARNING, ("if timeoutRoutineRequestTime 0,  timeoutThresholdForReassmProcess is uselessly"));
1609     if(p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
1610     {
1611         if((p_ManipParams->maxNumFramesInProcess < 4) ||
1612             (p_ManipParams->maxNumFramesInProcess > 512))
1613             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"));
1614     }
1615     else
1616     {
1617         if((p_ManipParams->maxNumFramesInProcess < 8) ||
1618             (p_ManipParams->maxNumFramesInProcess > 2048))
1619             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"));
1620     }
1621 
1622     p_Manip->updateParams |= (NUM_OF_TASKS | BUFFER_POOL_ID_FOR_MANIP | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
1623 
1624     p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1625                                           FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
1626                                           FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
1627     if(!p_Manip->h_Frag)
1628          RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1629 
1630     IOMemSet32(p_Manip->h_Frag, 0,  FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
1631 
1632     p_Table         = (t_CapwapReasmPram *)p_Manip->h_Frag;
1633 
1634     p_Manip->fragParams.p_AutoLearnHashTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1635                                           (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
1636                                           FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
1637 
1638     IOMemSet32(p_Manip->fragParams.p_AutoLearnHashTbl, 0,  (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
1639 
1640 
1641     tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
1642 
1643     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
1644 
1645     tmpReg32 = 0;
1646     if(p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
1647         tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
1648     if(p_ManipParams->haltOnDuplicationFrag)
1649         tmpReg32  |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
1650     if(p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
1651     {
1652         i = 8;
1653         tmpReg32  |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
1654     }
1655     else
1656         i = 4;
1657 
1658     numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
1659     LOG2(numOfSets, log2Num);
1660     tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
1661 
1662     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
1663 
1664     for(j = 0; j < p_ManipParams->maxNumFramesInProcess * 2; j++)
1665     {
1666         if(((j / i)  % 2)== 0)
1667         {
1668             WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->fragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
1669         }
1670     }
1671 
1672     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, 0x00008000);
1673     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
1674     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
1675 
1676     p_Manip->fragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
1677 
1678     p_Manip->fragParams.poolIndx =  poolIndex;
1679 
1680     p_Manip->fragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
1681     p_Manip->fragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
1682     /*TODO  - to take care about this function FmGetTimeStampScale - it return t_Error
1683      now we have problems with all calls to this fucntion*/
1684     p_Manip->fragParams.bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
1685 
1686     tmpReg32 = 0;
1687     tmpReg32 |= (((uint32_t)1<<p_Manip->fragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
1688     WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
1689 
1690     return E_OK;
1691 
1692 }
1693 
1694 static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd, uint8_t poolIndex)
1695 {
1696     t_AdOfTypeContLookup    *p_Ad;
1697     uint32_t                tmpReg32 = 0;
1698 
1699     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1700 
1701     p_Manip->updateParams |= OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP;
1702 
1703     p_Manip->frag = TRUE;
1704 
1705     p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1706                                           FM_PCD_CC_AD_ENTRY_SIZE,
1707                                           FM_PCD_CC_AD_TABLE_ALIGN);
1708     if(!p_Manip->h_Frag)
1709          RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1710 
1711     IOMemSet32(p_Manip->h_Frag, 0,  FM_PCD_CC_AD_ENTRY_SIZE);
1712 
1713     p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
1714 
1715     tmpReg32 = 0;
1716     tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
1717 
1718     if(p_ManipParams->headerOptionsCompr)
1719         tmpReg32 = FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
1720     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
1721 
1722     tmpReg32 = 0;
1723     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1724     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
1725 
1726 
1727     p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
1728     p_Manip->fragParams.poolIndx = poolIndex;
1729 
1730     return E_OK;
1731 }
1732 #endif /* FM_CAPWAP_SUPPORT */
1733 
1734 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
1735 static t_Error IpFragmentation(t_IpFragmentationParams *p_ManipParams,t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd, uint8_t poolIndex)
1736 {
1737     t_AdOfTypeContLookup    *p_Ad;
1738     uint32_t                tmpReg32 = 0;
1739 
1740     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1741 
1742     p_Manip->ipFragParams.h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1743                                            FM_PCD_CC_AD_ENTRY_SIZE,
1744                                            FM_PCD_CC_AD_TABLE_ALIGN);
1745 
1746     if( !p_Manip->ipFragParams.h_Frag)
1747          RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1748 
1749     IOMemSet32( p_Manip->ipFragParams.h_Frag, 0,  FM_PCD_CC_AD_ENTRY_SIZE);
1750 
1751     p_Ad = (t_AdOfTypeContLookup *)p_Manip->ipFragParams.h_Frag;
1752 
1753     tmpReg32 = 0;
1754     tmpReg32 |= (uint32_t)HMAN_OC_IP_FRAGMENTATION;
1755     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
1756 
1757     tmpReg32 = 0;
1758     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1759     tmpReg32 |= (p_ManipParams->dontFragAction << 30);
1760     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
1761 
1762     p_Manip->frag = TRUE;
1763 
1764     p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
1765     p_Manip->ipFragParams.poolIndx = poolIndex;
1766 
1767     /*Pointer to fragment ID*/
1768     p_Manip->ipFragParams.h_FragId= (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,4, 4);
1769 
1770     if(!p_Manip->ipFragParams.h_FragId)
1771          RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1772 
1773     IOMemSet32(p_Manip->ipFragParams.h_FragId, 0, 4);
1774 
1775     tmpReg32 = 0;
1776     tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->ipFragParams.h_FragId) - (p_FmPcd->physicalMuramBase));
1777     tmpReg32 |= p_ManipParams->scratchBpid << 24;
1778     WRITE_UINT32(p_Ad->gmask, tmpReg32);
1779 
1780     return E_OK;
1781 }
1782 
1783 static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool ipv4)
1784 {
1785     t_AdOfTypeContLookup *p_Ad      = (t_AdOfTypeContLookup *)h_Ad;
1786     t_FmPcd              *p_FmPcd   = (t_FmPcd *)p_Manip->h_FmPcd;
1787     uint32_t             tmpReg32;
1788     t_Error              err;
1789     t_Handle             h_IpReassParamsTblPtr;
1790 
1791     /* First Ad register */
1792     tmpReg32 = 0;
1793     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1794 
1795     if (ipv4)
1796         h_IpReassParamsTblPtr = p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr;
1797     else
1798         h_IpReassParamsTblPtr = p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr;
1799 
1800     err = CreateIpReassParamTable(p_Manip, h_IpReassParamsTblPtr, ipv4);
1801 
1802     if (err == E_OK)
1803         tmpReg32 |= (uint32_t)(XX_VirtToPhys(h_IpReassParamsTblPtr) - (p_FmPcd->physicalMuramBase));
1804     else
1805         return err;
1806 
1807     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
1808 
1809     /* Second Ad register */
1810     tmpReg32 = (uint32_t)(p_Manip->ipReassmParams.bpid << 8);
1811     WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
1812 
1813     p_Manip->updateParams = OFFSET_OF_DATA;
1814 
1815     /* Third Ad register */
1816     tmpReg32 = 0;
1817     tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
1818     tmpReg32 |= (uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT;
1819     tmpReg32 |= (uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT;
1820     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
1821 
1822     p_Manip->reassm = TRUE;
1823 
1824     return E_OK;
1825 }
1826 
1827 static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
1828 {
1829     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
1830 
1831     if(p_Manip->muramAllocate)
1832     {
1833         p_Manip->ipReassmParams.h_Ipv4Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1834                                              FM_PCD_CC_AD_ENTRY_SIZE,
1835                                              FM_PCD_CC_AD_TABLE_ALIGN);
1836         if(!p_Manip->ipReassmParams.h_Ipv4Ad)
1837         {
1838            ReleaseManipHandler(p_Manip, p_FmPcd);
1839            RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1840         }
1841 
1842         IOMemSet32(p_Manip->ipReassmParams.h_Ipv4Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE);
1843     }
1844     else
1845     {
1846          p_Manip->ipReassmParams.h_Ipv4Ad = (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t), p_Manip->ipReassmParams.dataMemId, 0);
1847          if(!p_Manip->ipReassmParams.h_Ipv4Ad)
1848          {
1849             ReleaseManipHandler(p_Manip, p_FmPcd);
1850             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1851          }
1852 
1853         memset(p_Manip->ipReassmParams.h_Ipv4Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
1854     }
1855 
1856     FillReassmManipParams(p_Manip, p_Manip->ipReassmParams.h_Ipv6Ad, TRUE);
1857 
1858     return E_OK;
1859 }
1860 
1861 static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
1862 {
1863     t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
1864 
1865     if(p_Manip->muramAllocate)
1866     {
1867         p_Manip->ipReassmParams.h_Ipv6Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
1868                                              FM_PCD_CC_AD_ENTRY_SIZE,
1869                                              FM_PCD_CC_AD_TABLE_ALIGN);
1870         if(!p_Manip->ipReassmParams.h_Ipv6Ad)
1871         {
1872            ReleaseManipHandler(p_Manip, p_FmPcd);
1873            RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1874         }
1875 
1876         IOMemSet32(p_Manip->ipReassmParams.h_Ipv6Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE);
1877     }
1878     else
1879     {
1880          p_Manip->ipReassmParams.h_Ipv6Ad = (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t), p_Manip->ipReassmParams.dataMemId, 0);
1881          if(!p_Manip->ipReassmParams.h_Ipv6Ad)
1882          {
1883             ReleaseManipHandler(p_Manip, p_FmPcd);
1884             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
1885          }
1886 
1887         memset(p_Manip->ipReassmParams.h_Ipv6Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
1888     }
1889 
1890     FillReassmManipParams(p_Manip, p_Manip->ipReassmParams.h_Ipv6Ad, FALSE);
1891 
1892     return E_OK;
1893 }
1894 
1895 
1896 static t_Error IpReassembly(t_FmPcdManipFragOrReasmParams *p_ManipParams,t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
1897 {
1898     uint32_t                    tmpReg32 = 0, maxSetNumber = 10000;
1899     t_IpReasmCommonTbl          *p_IpReasmCommonPramTbl = NULL;
1900     t_IpReassemblyParams        reassmManipParams = p_ManipParams->ipReasmParams;
1901     t_Error                     err;
1902 
1903     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1904     SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
1905 
1906     if (!p_FmPcd->h_Hc)
1907         RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
1908     if (!POWER_OF_2(reassmManipParams.maxNumFramesInProcess))
1909         RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
1910 
1911     if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) && (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
1912         RETURN_ERROR(MAJOR, E_INVALID_VALUE,("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
1913 
1914     /*It is recommended that the total number of entries in this table (number of sets * number of ways)
1915     will be twice the number of frames that are expected to be reassembled simultaneously.*/
1916     if (reassmManipParams.maxNumFramesInProcess > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
1917         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
1918 
1919     p_Manip->ipReassmParams.maxNumFramesInProcess = reassmManipParams.maxNumFramesInProcess;
1920     p_Manip->ipReassmParams.timeOutMode = reassmManipParams.timeOutMode;
1921     p_Manip->ipReassmParams.fqidForTimeOutFrames = reassmManipParams.fqidForTimeOutFrames;
1922     p_Manip->ipReassmParams.numOfFramesPerHashEntry = reassmManipParams.numOfFramesPerHashEntry;
1923     p_Manip->ipReassmParams.timeoutThresholdForReassmProcess = reassmManipParams.timeoutThresholdForReassmProcess;
1924     p_Manip->ipReassmParams.liodnOffset = reassmManipParams.liodnOffset;
1925     p_Manip->ipReassmParams.minFragSize = reassmManipParams.minFragSize;
1926     p_Manip->ipReassmParams.dataMemId = reassmManipParams.dataMemId;
1927     p_Manip->ipReassmParams.bpid = p_ManipParams->extBufPoolIndx;
1928 
1929     CreateIpReassCommonParamTable(p_Manip, p_FmPcd, p_IpReasmCommonPramTbl);
1930 
1931     if ((p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4_AND_IPv6) || (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4))
1932         return SetIpv4ReassmManip(p_Manip);
1933 
1934     if ((p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4_AND_IPv6) || (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv6))
1935         return SetIpv6ReassmManip(p_Manip);
1936 
1937     err = FM_PCD_RegisterReassmPort(p_FmPcd, p_IpReasmCommonPramTbl);
1938     if (err != E_OK)
1939     {
1940         FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_IpReasmCommonPramTbl);
1941         RETURN_ERROR(MAJOR, err, ("port registration"));
1942     }
1943 
1944     return E_OK;
1945 }
1946 #endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
1947 
1948 static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
1949 {
1950     t_AdOfTypeContLookup    *p_Ad;
1951     uint32_t                tmpReg32 = 0;
1952 
1953     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1954 
1955     UNUSED(p_FmPcd);
1956 
1957     p_Ad         = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1958 
1959     tmpReg32 = 0;
1960     tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
1961     if(p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
1962         tmpReg32 |= (uint32_t)0x16 << 16;
1963     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
1964 
1965     tmpReg32 = 0;
1966     tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
1967     WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
1968 
1969     return E_OK;
1970 }
1971 
1972 static t_Error InsrtHdrByTempl(t_FmPcdManipInsrtParams  *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
1973 {
1974     t_FmPcdManipInsrtByTemplateParams   *p_InsrtByTemplate = &p_ManipParams->insrtByTemplateParams;
1975     uint8_t                             tmpReg8 = 0xff;
1976     t_AdOfTypeContLookup                *p_Ad;
1977     bool                                ipModify = FALSE;
1978     uint32_t                            tmpReg32 = 0, tmpRegNia = 0;
1979     uint16_t                            tmpReg16 = 0;
1980     t_Error                             err = E_OK;
1981     uint8_t                             extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0;
1982     uint8_t                             *p_Template = NULL;
1983 
1984     SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
1985     SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
1986     SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
1987     SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
1988 
1989     p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
1990     if(p_Manip->insrt)
1991     {
1992         if((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
1993              (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
1994              RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
1995 
1996          if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
1997              RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
1998 
1999          if(p_InsrtByTemplate->size > 128)
2000              RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
2001 
2002          if(p_InsrtByTemplate->size)
2003          {
2004              p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2005                                                 p_InsrtByTemplate->size,
2006                                                 FM_PCD_CC_AD_TABLE_ALIGN);
2007              if(!p_Manip->p_Template)
2008                  RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
2009 
2010              tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
2011              tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
2012              *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
2013          }
2014 
2015          tmpReg32 = 0;
2016 
2017         p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
2018 
2019         if(!p_Template)
2020             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
2021 
2022         memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
2023 
2024 
2025          if(p_InsrtByTemplate->modifyOuterIp)
2026          {
2027              ipModify = TRUE;
2028 
2029              tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
2030 
2031              if((tmpReg8 & 0xf0) == 0x40)
2032                  tmpReg8 = 4;
2033              else if((tmpReg8 & 0xf0) == 0x60)
2034                  tmpReg8 = 6;
2035              else
2036                  tmpReg8 = 0xff;
2037 
2038              if(tmpReg8 == 4)
2039              {
2040                  if((IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
2041                      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"));
2042 
2043                  if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
2044                      RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
2045 
2046                  p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
2047 
2048                  if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
2049                  {
2050 
2051                      if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
2052                             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
2053                      extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
2054                      blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
2055                      extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
2056                      /*IP header template - IP totalLength -
2057                      (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
2058                      in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
2059                      second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
2060                  }
2061                  if(blockSize)
2062                  {
2063                      if (!POWER_OF_2(blockSize))
2064                          RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
2065                      blockSize -= 1;
2066                  }
2067 
2068                  if((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
2069                      RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
2070 
2071                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize;
2072                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);
2073 
2074                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_ID_FIELD_OFFSET_FROM_IP] = 0x00;
2075                 p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
2076 
2077 
2078                  /*IP header template - relevant only for ipv4 CheckSum = 0*/
2079                  p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
2080                  p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
2081 
2082 
2083                  /*UDP checksum has to be 0*/
2084                  if(p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
2085                  {
2086                      if((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_UDPCHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
2087                          RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
2088 
2089                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
2090                     p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
2091 
2092                  }
2093 
2094                  if(p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
2095                      RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
2096 
2097                  tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
2098              }
2099              else
2100                  RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
2101          }
2102 
2103          tmpReg32 = tmpReg16 = tmpReg8 = 0;
2104          /*TODO - check it*/
2105          if(p_InsrtByTemplate->modifyOuterVlan)
2106          {
2107              if(p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
2108                  RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
2109 
2110              memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
2111              if((tmpReg16  != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
2112                  RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
2113 
2114              memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
2115              tmpReg8 &= 0x1f;
2116              tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
2117 
2118              p_Template[14] = tmpReg8;
2119          }
2120 
2121         Mem2IOCpy32(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
2122 
2123         XX_Free(p_Template);
2124     }
2125 
2126     tmpReg32 = 0;
2127     if(p_Manip->h_Frag)
2128     {
2129         tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
2130         tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
2131     }
2132     else
2133           tmpReg32 = 0xffff0000;
2134 
2135     if(ipModify)
2136         tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
2137     else
2138         tmpReg32 |= (uint32_t)0x0000ff00;
2139 
2140     tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
2141     *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
2142 
2143     tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
2144     *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
2145 
2146     return err;
2147 }
2148 
2149 #if defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)
2150 static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
2151 {
2152 
2153     t_Error                     err = E_OK;
2154     t_AdOfTypeContLookup        *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
2155     uint32_t                    tmpReg32 = 0, tmpRegNia = 0;
2156 
2157     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
2158     SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_INVALID_HANDLE);
2159 
2160     if(p_Manip->frag == TRUE)
2161     {
2162         tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
2163         tmpReg32  |= (uint32_t)p_Manip->sizeForFragmentation << 16;
2164     }
2165     else
2166           tmpReg32 = 0xffff0000;
2167 
2168     tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
2169     tmpReg32  |= HMAN_OC_IPSEC;
2170 
2171     WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
2172     WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
2173     WRITE_UINT32(p_Ad->gmask, 0); /* Total frame counter - MUST be initialized to zero.*/
2174 
2175 /*
2176     TODO - Fill the following:
2177          - Over write OuterTos
2178          - SaveInnerTos
2179          - support in CNIA
2180 */
2181 
2182     return err;
2183 }
2184 #endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
2185 
2186 static t_Error CheckStatsParamsAndSetType(t_FmPcdManip  *p_Manip, t_FmPcdStatsParams *p_StatsParams)
2187 {
2188 
2189     switch(p_StatsParams->type)
2190     {
2191         case(e_FM_PCD_STATS_PER_FLOWID):
2192             p_Manip->type = HMAN_OC_CAPWAP_INDEXED_STATS;
2193             p_Manip->muramAllocate = TRUE;
2194         break;
2195         default:
2196             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
2197     }
2198 
2199     return E_OK;
2200 }
2201 
2202 static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params, bool stats)
2203 {
2204     t_FmPcdManip                *p_Manip;
2205     t_Error                     err;
2206     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
2207 
2208     p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
2209     if(!p_Manip)
2210     {
2211         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
2212         return NULL;
2213     }
2214     memset(p_Manip, 0, sizeof(t_FmPcdManip));
2215 
2216     if(!stats)
2217     {
2218         err = CheckManipParamsAndSetType(p_Manip, (t_FmPcdManipParams *)p_Params);
2219     }
2220     else
2221     {
2222         err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
2223     }
2224 
2225     if(err)
2226     {
2227         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("INVALID HEADER MANIPULATION TYPE"));
2228         ReleaseManipHandler(p_Manip, p_FmPcd);
2229         XX_Free(p_Manip);
2230         return NULL;
2231     }
2232 
2233 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
2234     if(p_Manip->type != HMAN_OC_IP_REASSEMBLY)
2235     {
2236 #endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
2237     if(p_Manip->muramAllocate)
2238     {
2239         p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
2240                                              FM_PCD_CC_AD_ENTRY_SIZE,
2241                                              FM_PCD_CC_AD_TABLE_ALIGN);
2242          if(!p_Manip->h_Ad)
2243          {
2244             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
2245             ReleaseManipHandler(p_Manip, p_FmPcd);
2246             XX_Free(p_Manip);
2247             return NULL;
2248          }
2249 
2250         IOMemSet32(p_Manip->h_Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE);
2251     }
2252     else
2253     {
2254         p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
2255          if(!p_Manip->h_Ad)
2256          {
2257             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
2258             ReleaseManipHandler(p_Manip, p_FmPcd);
2259             XX_Free(p_Manip);
2260             return NULL;
2261          }
2262 
2263         memset(p_Manip->h_Ad, 0,  FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
2264     }
2265 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
2266     }
2267 #endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
2268     p_Manip->h_FmPcd = h_FmPcd;
2269 
2270     return p_Manip;
2271 }
2272 
2273 
2274 t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify)
2275 {
2276     t_Error err;
2277 
2278     if(!modify)
2279     {
2280         err = FmPcdManipInitUpdate(h_FmPcd, h_FmPort, h_Manip, h_Ad, validate, level, h_FmTree);
2281     }
2282     else
2283     {
2284         err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
2285     }
2286     return err;
2287 }
2288 
2289 uint32_t FmPcdManipGetRequiredAction (t_Handle h_Manip)
2290 {
2291     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
2292 
2293     ASSERT_COND(h_Manip);
2294 
2295     switch(p_Manip->type)
2296     {
2297         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
2298         case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
2299             return UPDATE_NIA_ENQ_WITHOUT_DMA;
2300         default:
2301             return 0;
2302     }
2303 }
2304 
2305 void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
2306 {
2307 
2308     if(add)
2309         ((t_FmPcdManip *)h_Manip)->owner++;
2310     else
2311     {
2312         ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
2313         ((t_FmPcdManip *)h_Manip)->owner--;
2314     }
2315 }
2316 
2317 t_Error FmPcdManipCheckParamsForCcNextEgine(t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, uint32_t *requiredAction)
2318 {
2319     t_FmPcdManip             *p_Manip;
2320     t_Error                   err;
2321 
2322 
2323     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
2324     SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip, E_NULL_POINTER);
2325 
2326     p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
2327     *requiredAction = 0;
2328     switch(p_Manip->type)
2329     {
2330         case(HMAN_OC_CAPWAP_INDEXED_STATS):
2331             if(p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
2332                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
2333             if(p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
2334                p_Manip->cnia = TRUE;
2335         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
2336             *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
2337         case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
2338             p_Manip->ownerTmp++;
2339         break;
2340         case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
2341             if((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
2342                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
2343             p_Manip->ownerTmp++;
2344         break;
2345         case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
2346             if((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)  &&
2347                (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) != CC_PC_GENERIC_IC_HASH_INDEXED))
2348                 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"));
2349             err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip, FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
2350             if(err)
2351                 RETURN_ERROR(MAJOR, err, NO_MSG);
2352             *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
2353         break;
2354 #if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
2355         case(HMAN_OC_IPSEC):
2356 
2357             if((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_DONE) &&
2358                !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
2359                p_Manip->cnia = FALSE;
2360             else
2361                p_Manip->cnia = TRUE;
2362             if(!p_Manip->h_Frag)
2363             {
2364                 p_Manip->ownerTmp++;
2365                 break;
2366             }
2367 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
2368         case(HMAN_OC_IP_FRAGMENTATION):
2369             if(p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
2370                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
2371             p_Manip->ownerTmp++;
2372         break;
2373 #endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
2374             break;
2375 #endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
2376         default:
2377             RETURN_ERROR(MAJOR, E_INVALID_STATE,("invalid type of header manipulation for this state"));
2378     }
2379 
2380     return E_OK;
2381 }
2382 
2383 t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode)
2384 {
2385     t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
2386     t_Error         err = E_OK;
2387 
2388     SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
2389     SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
2390 
2391     switch(p_Manip->type)
2392     {
2393         case(HMAN_OC_CAPWAP_INDEXED_STATS):
2394             if(p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
2395                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
2396         break;
2397         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
2398             if(p_Manip->h_Frag)
2399             {
2400                 if(p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
2401                     RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
2402                 err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
2403                 if(err)
2404                     RETURN_ERROR(MAJOR, err, NO_MSG);
2405             }
2406             break;
2407         default:
2408             break;
2409     }
2410     return err;
2411 }
2412 
2413 void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew)
2414 {
2415     t_FmPcdManip             *p_Manip = (t_FmPcdManip *)h_Manip;
2416 
2417     ASSERT_COND(p_Manip);
2418 
2419     FmPcdManipUpdateOwner(h_Manip, TRUE);
2420 
2421     switch(p_Manip->type)
2422     {
2423         case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
2424         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
2425         case(HMAN_OC_CAPWAP_INDEXED_STATS):
2426 #if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
2427         case(HMAN_OC_IP_FRAGMENTATION):
2428         case(HMAN_OC_IP_REASSEMBLY):
2429 #endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
2430             *p_AdNew = p_Manip->h_Ad;
2431             break;
2432         case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
2433         case(HMAN_OC_CAPWAP_FRAGMENTATION):
2434             WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,         ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
2435             WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,  ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
2436             WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,          ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
2437             *p_AdNew = NULL;
2438             break;
2439 #if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
2440         case(HMAN_OC_IPSEC):
2441             if (p_Manip->cnia)
2442                 *p_AdNew = p_Manip->h_Ad;
2443             else
2444             {
2445                 WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,         ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
2446                 WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,  ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
2447                 WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,          ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
2448                 *p_AdNew = NULL;
2449             }
2450             break;
2451 #endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
2452         default:
2453             break;
2454     }
2455 }
2456 
2457 void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset)
2458 {
2459     t_FmPcdManip             *p_Manip = (t_FmPcdManip *)h_Manip;
2460 
2461     ASSERT_COND(p_Manip);
2462 
2463     FmPcdManipUpdateOwner(h_Manip, TRUE);
2464 
2465     switch(p_Manip->type)
2466     {
2467         case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
2468             WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,      ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
2469             WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,   ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
2470             WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,  ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
2471             WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,         ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
2472             WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,      (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
2473             *p_AdNew = NULL;
2474             break;
2475         default:
2476             break;
2477     }
2478 }
2479 
2480 t_Handle FM_PCD_ManipSetNode(t_Handle h_FmPcd, t_FmPcdManipParams *p_ManipParams)
2481 {
2482     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
2483     t_FmPcdManip                *p_Manip;
2484     t_Error                     err;
2485 
2486     SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
2487     SANITY_CHECK_RETURN_VALUE(p_ManipParams,E_INVALID_HANDLE,NULL);
2488 
2489 
2490     p_Manip =  ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
2491     if(!p_Manip)
2492         return NULL;
2493 
2494     switch(p_Manip->type)
2495     {
2496         case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
2497             /* HmanType1 */
2498             err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->rmvParams, p_Manip);
2499             break;
2500 #ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
2501         case(HMAN_OC_IP_REASSEMBLY):
2502             /* IpReassembly */
2503             err = IpReassembly(&p_ManipParams->fragOrReasmParams, p_Manip, p_FmPcd);
2504             if(err)
2505             {
2506                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
2507                 ReleaseManipHandler(p_Manip, p_FmPcd);
2508                 XX_Free(p_Manip);
2509                 return NULL;
2510             }
2511             break;
2512        case(HMAN_OC_IP_FRAGMENTATION):
2513             /* IpFragmentation */
2514             err = IpFragmentation(&p_ManipParams->fragOrReasmParams.ipFragParams ,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx);
2515             if(err)
2516             {
2517                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
2518                 ReleaseManipHandler(p_Manip, p_FmPcd);
2519                 XX_Free(p_Manip);
2520                 return NULL;
2521             }
2522 #endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
2523 #if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
2524         case(HMAN_OC_IPSEC) :
2525             err = IPSecManip(p_ManipParams, p_Manip, p_FmPcd);
2526             break;
2527 #endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
2528 #ifdef FM_CAPWAP_SUPPORT
2529         case(HMAN_OC_CAPWAP_FRAGMENTATION):
2530             /* CapwapFragmentation */
2531             err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.capwapFragParams ,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx);
2532             if(err)
2533             {
2534                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
2535                 ReleaseManipHandler(p_Manip, p_FmPcd);
2536                 XX_Free(p_Manip);
2537                 return NULL;
2538             }
2539             if(p_Manip->insrt)
2540                 p_Manip->type = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
2541         case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
2542             /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
2543             err = InsrtHdrByTempl(&p_ManipParams->insrtParams, p_Manip, p_FmPcd);
2544             break;
2545         case(HMAN_OC_CAPWAP_REASSEMBLY) :
2546             /*CAPWAP Reassembly*/
2547             err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.capwapReasmParams,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx);
2548             if(err)
2549             {
2550                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
2551                 ReleaseManipHandler(p_Manip, p_FmPcd);
2552                 XX_Free(p_Manip);
2553                 return NULL;
2554             }
2555             if(p_Manip->rmv)
2556                 p_Manip->type = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
2557         case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
2558             /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
2559             err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
2560             break;
2561 #endif /* FM_CAPWAP_SUPPORT */
2562        case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
2563             /*Application Specific type 1*/
2564             err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, (bool)(p_ManipParams->treatFdStatusFieldsAsErrors ? TRUE : FALSE));
2565             break;
2566        default:
2567                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
2568                 ReleaseManipHandler(p_Manip, p_FmPcd);
2569                 XX_Free(p_Manip);
2570                 return NULL;
2571     }
2572     if(err)
2573      {
2574          REPORT_ERROR(MAJOR, err, NO_MSG);
2575          ReleaseManipHandler(p_Manip, p_FmPcd);
2576          XX_Free(p_Manip);
2577          return NULL;
2578      }
2579      return p_Manip;
2580 }
2581 
2582 t_Error FM_PCD_ManipDeleteNode(t_Handle h_FmPcd, t_Handle h_ManipNode)
2583 {
2584     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
2585     t_FmPcdManip                *p_Manip = (t_FmPcdManip *)h_ManipNode;
2586 
2587     SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
2588     SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
2589 
2590     if(p_Manip->owner)
2591         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
2592 
2593     ReleaseManipHandler(p_Manip,p_FmPcd);
2594 
2595     XX_Free(h_ManipNode);
2596 
2597     return E_OK;
2598 }
2599 
2600 t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
2601 {
2602     t_FmPcd                     *p_FmPcd = (t_FmPcd *)h_FmPcd;
2603     t_FmPcdManip                *p_Manip;
2604     t_Error                     err;
2605 
2606     SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
2607     SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
2608 
2609     p_Manip =  ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
2610     if(!p_Manip)
2611         return NULL;
2612 
2613      switch(p_Manip->type)
2614     {
2615         case(HMAN_OC_CAPWAP_INDEXED_STATS):
2616             /* Indexed statistics */
2617             err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
2618             break;
2619        default:
2620                 REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
2621                 ReleaseManipHandler(p_Manip, p_FmPcd);
2622                 XX_Free(p_Manip);
2623                 return NULL;
2624 
2625     }
2626      if(err)
2627      {
2628          REPORT_ERROR(MAJOR, err, NO_MSG);
2629          ReleaseManipHandler(p_Manip, p_FmPcd);
2630          XX_Free(p_Manip);
2631          return NULL;
2632      }
2633      return p_Manip;
2634 }
2635 
2636 #endif /* FM_CAPWAP_SUPPORT */
2637 #endif /* CONFIG_FMAN_P1023 */
2638