1 /*
2  * Copyright 2008-2012 Freescale Semiconductor Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of Freescale Semiconductor nor the
12  *       names of its contributors may be used to endorse or promote products
13  *       derived from this software without specific prior written permission.
14  *
15  *
16  * ALTERNATIVELY, this software may be distributed under the terms of the
17  * GNU General Public License ("GPL") as published by the Free Software
18  * Foundation, either version 2 of that License or (at your option) any
19  * later version.
20  *
21  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 
34 /******************************************************************************
35  @File          fm_port.c
36 
37  @Description   FM driver routines implementation.
38  *//***************************************************************************/
39 #include "error_ext.h"
40 #include "std_ext.h"
41 #include "string_ext.h"
42 #include "sprint_ext.h"
43 #include "debug_ext.h"
44 #include "fm_muram_ext.h"
45 
46 #include "fman_common.h"
47 #include "fm_port.h"
48 #include "fm_port_dsar.h"
49 #include "common/general.h"
50 
51 /****************************************/
52 /*       static functions               */
53 /****************************************/
54 static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
55 
56 static t_Error CheckInitParameters(t_FmPort *p_FmPort)
57 {
58     t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
59     struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
60     t_Error ans = E_OK;
61     uint32_t unusedMask;
62 
63     if (p_FmPort->imEn)
64     {
65         if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
66             if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
67                     > 2)
68                 RETURN_ERROR(
69                         MAJOR,
70                         E_INVALID_VALUE,
71                         ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
72 
73         if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
74             return ERROR_CODE(ans);
75     }
76     else
77     {
78         /****************************************/
79         /*   Rx only                            */
80         /****************************************/
81         if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
82                 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
83         {
84             /* external buffer pools */
85             if (!p_Params->extBufPools.numOfPoolsUsed)
86                 RETURN_ERROR(
87                         MAJOR,
88                         E_INVALID_VALUE,
89                         ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
90 
91             if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
92                                         p_Params->p_BackupBmPools,
93                                         &p_Params->bufPoolDepletion) != E_OK)
94                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
95 
96             /* Check that part of IC that needs copying is small enough to enter start margin */
97             if (p_Params->intContext.size
98                     && (p_Params->intContext.size
99                             + p_Params->intContext.extBufOffset
100                             > p_Params->bufMargins.startMargins))
101                 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
102                              ("intContext.size is larger than start margins"));
103 
104             if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
105                     && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
106                 RETURN_ERROR(
107                         MAJOR,
108                         E_INVALID_VALUE,
109                         ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
110 
111 #ifdef FM_NO_BACKUP_POOLS
112             if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
113             if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
114             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
115 #endif /* FM_NO_BACKUP_POOLS */
116         }
117 
118         /****************************************/
119         /*   Non Rx ports                       */
120         /****************************************/
121         else
122         {
123             if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
124                 RETURN_ERROR(
125                         MAJOR,
126                         E_INVALID_VALUE,
127                         (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
128 
129             /* to protect HW internal-context from overwrite */
130             if ((p_Params->intContext.size)
131                     && (p_Params->intContext.intContextOffset
132                             < MIN_TX_INT_OFFSET))
133                 RETURN_ERROR(
134                         MAJOR,
135                         E_INVALID_VALUE,
136                         ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
137 
138             if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
139                     || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
140                     /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
141                     || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
142                             != DEFAULT_notSupported))
143             {
144                 /* Check that not larger than 8 */
145                 if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
146                         || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
147                                 > MAX_FIFO_PIPELINE_DEPTH))
148                     RETURN_ERROR(
149                             MAJOR,
150                             E_INVALID_VALUE,
151                             ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
152             }
153         }
154 
155         /****************************************/
156         /*   Rx Or Offline Parsing              */
157         /****************************************/
158         if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
159                 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
160                 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
161         {
162             if (!p_Params->dfltFqid)
163                 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
164                              ("dfltFqid must be between 1 and 2^24-1"));
165 #if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
166             if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
167             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
168 #endif /* defined(FM_CAPWAP_SUPPORT) && ... */
169         }
170 
171         /****************************************/
172         /*   All ports                          */
173         /****************************************/
174         /* common BMI registers values */
175         /* Check that Queue Id is not larger than 2^24, and is not 0 */
176         if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
177             RETURN_ERROR(MAJOR, E_INVALID_VALUE,
178                          ("errFqid must be between 1 and 2^24-1"));
179         if (p_Params->dfltFqid & ~0x00FFFFFF)
180             RETURN_ERROR(MAJOR, E_INVALID_VALUE,
181                          ("dfltFqid must be between 1 and 2^24-1"));
182     }
183 
184     /****************************************/
185     /*   Rx only                            */
186     /****************************************/
187     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
188             || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
189     {
190         if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
191             RETURN_ERROR(
192                     MAJOR,
193                     E_INVALID_VALUE,
194                     ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
195         if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
196                 || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
197             RETURN_ERROR(
198                     MAJOR,
199                     E_INVALID_VALUE,
200                     ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
201         if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
202             RETURN_ERROR(
203                     MAJOR,
204                     E_INVALID_VALUE,
205                     ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
206         if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
207                 || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
208             RETURN_ERROR(
209                     MAJOR,
210                     E_INVALID_VALUE,
211                     ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
212 
213         /* Check that not larger than 16 */
214         if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
215             RETURN_ERROR(
216                     MAJOR,
217                     E_INVALID_VALUE,
218                     ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
219 
220         if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
221             RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
222 
223         /* extra FIFO size (allowed only to Rx ports) */
224         if (p_Params->setSizeOfFifo
225                 && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
226             RETURN_ERROR(
227                     MAJOR,
228                     E_INVALID_VALUE,
229                     ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
230 
231         if (p_Params->bufPoolDepletion.poolsGrpModeEnable
232                 && !p_Params->bufPoolDepletion.numOfPools)
233             RETURN_ERROR(
234                     MAJOR,
235                     E_INVALID_VALUE,
236                     ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
237 #ifdef FM_CSI_CFED_LIMIT
238         if (p_FmPort->fmRevInfo.majorRev == 4)
239         {
240             /* Check that not larger than 16 */
241             if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
242             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
243         }
244 #endif /* FM_CSI_CFED_LIMIT */
245     }
246 
247     /****************************************/
248     /*   Non Rx ports                       */
249     /****************************************/
250     /* extra FIFO size (allowed only to Rx ports) */
251     else
252         if (p_FmPort->fifoBufs.extra)
253             RETURN_ERROR(MAJOR, E_INVALID_VALUE,
254                          (" No fifoBufs.extra for non Rx ports"));
255 
256     /****************************************/
257     /*   Tx only                            */
258     /****************************************/
259     if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
260             || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
261     {
262         if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
263             RETURN_ERROR(
264                     MAJOR,
265                     E_INVALID_VALUE,
266                     ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
267         if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
268             RETURN_ERROR(
269                     MAJOR,
270                     E_INVALID_VALUE,
271                     ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
272         if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
273             RETURN_ERROR(
274                     MAJOR,
275                     E_INVALID_VALUE,
276                     ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
277         if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
278                 || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
279             RETURN_ERROR(
280                     MAJOR,
281                     E_INVALID_VALUE,
282                     ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
283 
284         if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
285             if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
286                     > 2)
287                 RETURN_ERROR(
288                         MAJOR, E_INVALID_VALUE,
289                         ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
290     }
291 
292     /****************************************/
293     /*   Non Tx Ports                       */
294     /****************************************/
295     /* If discard override was selected , no frames may be discarded. */
296     else
297         if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
298             RETURN_ERROR(
299                     MAJOR,
300                     E_CONFLICT,
301                     ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
302 
303     /****************************************/
304     /*   Rx and Offline parsing             */
305     /****************************************/
306     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
307             || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
308             || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
309     {
310         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
311             unusedMask = BMI_STATUS_OP_MASK_UNUSED;
312         else
313             unusedMask = BMI_STATUS_RX_MASK_UNUSED;
314 
315         /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
316         if (p_Params->errorsToDiscard & unusedMask)
317             RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
318                          ("errorsToDiscard contains undefined bits"));
319     }
320 
321     /****************************************/
322     /*   Offline Ports                      */
323     /****************************************/
324 #ifdef FM_OP_OPEN_DMA_MIN_LIMIT
325     if ((p_FmPort->fmRevInfo.majorRev >= 6)
326             && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
327             && p_Params->setNumOfOpenDmas
328             && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
329         RETURN_ERROR(
330                 MAJOR,
331                 E_INVALID_VALUE,
332                 ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
333 #endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
334 
335     /****************************************/
336     /*   Offline & HC Ports                 */
337     /****************************************/
338     if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
339             || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
340     {
341 #ifndef FM_FRAME_END_PARAMS_FOR_OP
342         if ((p_FmPort->fmRevInfo.majorRev < 6) &&
343                 (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
344         /* this is an indication that user called config for this mode which is not supported in this integration */
345         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
346 #endif /* !FM_FRAME_END_PARAMS_FOR_OP */
347 
348 #ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
349         if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
350                                 (p_FmPort->fmRevInfo.majorRev >= 6))) &&
351                 (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
352         /* this is an indication that user called config for this mode which is not supported in this integration */
353         RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
354 #endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
355     }
356 
357     /****************************************/
358     /*   All ports                          */
359     /****************************************/
360     /* Check that not larger than 16 */
361     if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
362             && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
363         RETURN_ERROR(
364                 MAJOR,
365                 E_INVALID_VALUE,
366                 ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
367 
368     if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
369         RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
370 
371     /* common BMI registers values */
372     if (p_Params->setNumOfTasks
373             && ((!p_FmPort->tasks.num)
374                     || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
375         RETURN_ERROR(MAJOR, E_INVALID_VALUE,
376                      ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
377     if (p_Params->setNumOfTasks
378             && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
379         RETURN_ERROR(
380                 MAJOR,
381                 E_INVALID_VALUE,
382                 ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
383     if (p_Params->setNumOfOpenDmas
384             && ((!p_FmPort->openDmas.num)
385                     || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
386         RETURN_ERROR(MAJOR, E_INVALID_VALUE,
387                      ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
388     if (p_Params->setNumOfOpenDmas
389             && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
390         RETURN_ERROR(
391                 MAJOR,
392                 E_INVALID_VALUE,
393                 ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
394     if (p_Params->setSizeOfFifo
395             && (!p_FmPort->fifoBufs.num
396                     || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
397         RETURN_ERROR(
398                 MAJOR,
399                 E_INVALID_VALUE,
400                 ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
401     if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
402         RETURN_ERROR(
403                 MAJOR, E_INVALID_VALUE,
404                 ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
405 
406 #ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
407     if (p_FmPort->fmRevInfo.majorRev == 4)
408     if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
409     /* this is an indication that user called config for this mode which is not supported in this integration */
410     RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
411 #endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
412 
413     return E_OK;
414 }
415 
416 static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
417 {
418     uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
419 
420     /*************************/
421     /*    TX PORTS           */
422     /*************************/
423     if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
424             || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
425     {
426         minFifoSizeRequired =
427                 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
428                         + (3 * BMI_FIFO_UNITS));
429         if (!p_FmPort->imEn)
430             minFifoSizeRequired +=
431                     p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
432                             * BMI_FIFO_UNITS;
433 
434         optFifoSizeForB2B = minFifoSizeRequired;
435 
436         /* Add some margin for back-to-back capability to improve performance,
437          allows the hardware to pipeline new frame dma while the previous
438          frame not yet transmitted. */
439         if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
440             optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
441         else
442             optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
443     }
444 
445     /*************************/
446     /*    RX IM PORTS        */
447     /*************************/
448     else
449         if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
450                 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
451                 && p_FmPort->imEn)
452         {
453             optFifoSizeForB2B =
454                     minFifoSizeRequired =
455                             (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
456                                     + (4 * BMI_FIFO_UNITS));
457         }
458 
459         /*************************/
460         /*    RX non-IM PORTS    */
461         /*************************/
462         else
463             if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
464                     || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
465                     && !p_FmPort->imEn)
466             {
467                 if (p_FmPort->fmRevInfo.majorRev == 4)
468                 {
469                     if (p_FmPort->rxPoolsParams.numOfPools == 1)
470                         minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
471                     else
472                         minFifoSizeRequired =
473                                 (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
474                                         + (7 * BMI_FIFO_UNITS));
475                 }
476                 else
477                 {
478 #if (DPAA_VERSION >= 11)
479                     minFifoSizeRequired =
480                             (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
481                                     + (5 * BMI_FIFO_UNITS));
482                     /* 4 according to spec + 1 for FOF>0 */
483 #else
484                     minFifoSizeRequired = (uint32_t)
485                     (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
486                             + (7*BMI_FIFO_UNITS));
487 #endif /* (DPAA_VERSION >= 11) */
488                 }
489 
490                 optFifoSizeForB2B = minFifoSizeRequired;
491 
492                 /* Add some margin for back-to-back capability to improve performance,
493                  allows the hardware to pipeline new frame dma while the previous
494                  frame not yet transmitted. */
495                 if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
496                     optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
497                 else
498                     optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
499             }
500 
501             /* For O/H ports, check fifo size and update if necessary */
502             else
503                 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
504                         || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
505                 {
506 #if (DPAA_VERSION >= 11)
507                     optFifoSizeForB2B =
508                             minFifoSizeRequired =
509                                     (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
510                                             + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
511                                                     + 5) * BMI_FIFO_UNITS));
512                     /* 4 according to spec + 1 for FOF>0 */
513 #else
514                     optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
515 #endif /* (DPAA_VERSION >= 11) */
516                 }
517 
518     ASSERT_COND(minFifoSizeRequired > 0);
519     ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
520 
521     /* Verify the size  */
522     if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
523         DBG(INFO,
524            ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
525     else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
526         DBG(INFO,
527 	    ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
528 
529     return E_OK;
530 }
531 
532 static void FmPortDriverParamFree(t_FmPort *p_FmPort)
533 {
534     if (p_FmPort->p_FmPortDriverParam)
535     {
536         XX_Free(p_FmPort->p_FmPortDriverParam);
537         p_FmPort->p_FmPortDriverParam = NULL;
538     }
539 }
540 
541 static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
542 {
543     t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
544     t_FmBufPoolDepletion *p_BufPoolDepletion =
545             &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
546     uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
547     uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
548     int i = 0, j = 0, err;
549     struct fman_port_bpools bpools;
550 
551     memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
552     memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
553     memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
554 
555     FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
556                                         sizesArray);
557 
558     /* Prepare flibs bpools structure */
559     memset(&bpools, 0, sizeof(struct fman_port_bpools));
560     bpools.count = p_ExtBufPools->numOfPoolsUsed;
561     bpools.counters_enable = TRUE;
562     for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
563     {
564         bpools.bpool[i].bpid = orderedArray[i];
565         bpools.bpool[i].size = sizesArray[orderedArray[i]];
566         /* functionality available only for some derivatives (limited by config) */
567         if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
568             for (j = 0;
569                     j
570                             < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
571                     j++)
572                 if (orderedArray[i]
573                         == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
574                 {
575                     bpools.bpool[i].is_backup = TRUE;
576                     break;
577                 }
578     }
579 
580     /* save pools parameters for later use */
581     p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
582     p_FmPort->rxPoolsParams.largestBufSize =
583             sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
584     p_FmPort->rxPoolsParams.secondLargestBufSize =
585             sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
586 
587     /* FMBM_RMPD reg. - pool depletion */
588     if (p_BufPoolDepletion->poolsGrpModeEnable)
589     {
590         bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
591         for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
592         {
593             if (p_BufPoolDepletion->poolsToConsider[i])
594             {
595                 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
596                 {
597                     if (i == orderedArray[j])
598                     {
599                         bpools.bpool[j].grp_bp_depleted = TRUE;
600                         break;
601                     }
602                 }
603             }
604         }
605     }
606 
607     if (p_BufPoolDepletion->singlePoolModeEnable)
608     {
609         for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
610         {
611             if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
612             {
613                 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
614                 {
615                     if (i == orderedArray[j])
616                     {
617                         bpools.bpool[j].single_bp_depleted = TRUE;
618                         break;
619                     }
620                 }
621             }
622         }
623     }
624 
625 #if (DPAA_VERSION >= 11)
626     /* fill QbbPEV */
627     if (p_BufPoolDepletion->poolsGrpModeEnable
628             || p_BufPoolDepletion->singlePoolModeEnable)
629     {
630         for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
631         {
632             if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
633             {
634                 bpools.bpool[i].pfc_priorities_en = TRUE;
635             }
636         }
637     }
638 #endif /* (DPAA_VERSION >= 11) */
639 
640     /* Issue flibs function */
641     err = fman_port_set_bpools(&p_FmPort->port, &bpools);
642     if (err != 0)
643         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
644 
645     if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
646         XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
647 
648     return E_OK;
649 }
650 
651 static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
652 {
653     if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
654         FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
655     FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
656     FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
657     FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
658     return E_OK;
659 }
660 
661 static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
662 {
663     t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
664     struct fman_port_params portParams;
665     uint32_t tmpVal;
666     t_Error err;
667 
668     /* Set up flibs parameters and issue init function */
669 
670     memset(&portParams, 0, sizeof(struct fman_port_params));
671     portParams.discard_mask = p_DriverParams->errorsToDiscard;
672     portParams.dflt_fqid = p_DriverParams->dfltFqid;
673     portParams.err_fqid = p_DriverParams->errFqid;
674     portParams.deq_sp = p_DriverParams->deqSubPortal;
675     portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
676     switch (p_FmPort->portType)
677     {
678         case (e_FM_PORT_TYPE_RX_10G):
679         case (e_FM_PORT_TYPE_RX):
680             portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
681             if (!p_FmPort->imEn)
682             {
683                 if (p_DriverParams->forwardReuseIntContext)
684                     p_DriverParams->dfltCfg.rx_fd_bits =
685                             (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
686             }
687             break;
688 
689         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
690             portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
691             break;
692             break;
693 
694         default:
695             break;
696     }
697 
698     tmpVal =
699             (uint32_t)(
700                     (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
701                             / OFFSET_UNITS + 1) :
702                             (p_FmPort->internalBufferOffset / OFFSET_UNITS));
703     p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
704     p_DriverParams->dfltCfg.int_buf_start_margin =
705             p_FmPort->internalBufferOffset;
706 
707     p_DriverParams->dfltCfg.ext_buf_start_margin =
708             p_DriverParams->bufMargins.startMargins;
709     p_DriverParams->dfltCfg.ext_buf_end_margin =
710             p_DriverParams->bufMargins.endMargins;
711 
712     p_DriverParams->dfltCfg.ic_ext_offset =
713             p_DriverParams->intContext.extBufOffset;
714     p_DriverParams->dfltCfg.ic_int_offset =
715             p_DriverParams->intContext.intContextOffset;
716     p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
717 
718     p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
719     p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
720     p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
721 
722     p_DriverParams->dfltCfg.perf_cnt_params.task_val =
723             (uint8_t)p_FmPort->tasks.num;
724     if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
725     p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
726     else
727     p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
728     p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
729             (uint8_t)p_FmPort->openDmas.num;
730     p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
731 
732     if (0
733             != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
734                               &portParams))
735         RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
736 
737     if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
738         RETURN_ERROR(MAJOR, err, NO_MSG);
739     else
740     {
741         //  from QMIInit
742         if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
743                 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
744         {
745             if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
746                 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
747                                                FALSE);
748             else
749                 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
750                                                TRUE);
751         }
752     }
753     /* The code bellow is a trick so the FM will not release the buffer
754      to BM nor will try to enqueue the frame to QM */
755     if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
756             || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
757     {
758         if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
759         {
760             /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
761              * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
762              * buffers to BM regardless of fmbm_tfene
763              */
764             WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
765             WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
766                          NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
767         }
768     }
769 
770     return E_OK;
771 }
772 
773 static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
774 {
775     UNUSED(p_FmPort);
776 
777     switch (counter)
778     {
779         case (e_FM_PORT_COUNTERS_CYCLE):
780         case (e_FM_PORT_COUNTERS_TASK_UTIL):
781         case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
782         case (e_FM_PORT_COUNTERS_DMA_UTIL):
783         case (e_FM_PORT_COUNTERS_FIFO_UTIL):
784         case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
785         case (e_FM_PORT_COUNTERS_FRAME):
786         case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
787         case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
788         case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
789         case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
790         case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
791         case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
792         case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
793         case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
794             return TRUE;
795         default:
796             return FALSE;
797     }
798 }
799 
800 static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
801 {
802     UNUSED(p_FmPort);
803 
804     switch (counter)
805     {
806         case (e_FM_PORT_COUNTERS_CYCLE):
807         case (e_FM_PORT_COUNTERS_TASK_UTIL):
808         case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
809         case (e_FM_PORT_COUNTERS_DMA_UTIL):
810         case (e_FM_PORT_COUNTERS_FIFO_UTIL):
811         case (e_FM_PORT_COUNTERS_FRAME):
812         case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
813         case (e_FM_PORT_COUNTERS_LENGTH_ERR):
814         case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
815         case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
816             return TRUE;
817         default:
818             return FALSE;
819     }
820 }
821 
822 static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
823 {
824     switch (counter)
825     {
826         case (e_FM_PORT_COUNTERS_CYCLE):
827         case (e_FM_PORT_COUNTERS_TASK_UTIL):
828         case (e_FM_PORT_COUNTERS_DMA_UTIL):
829         case (e_FM_PORT_COUNTERS_FIFO_UTIL):
830         case (e_FM_PORT_COUNTERS_FRAME):
831         case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
832         case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
833         case (e_FM_PORT_COUNTERS_WRED_DISCARD):
834         case (e_FM_PORT_COUNTERS_LENGTH_ERR):
835         case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
836         case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
837             return TRUE;
838         case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
839             if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
840                 return FALSE;
841             else
842                 return TRUE;
843         default:
844             return FALSE;
845     }
846 }
847 
848 static t_Error BmiPortCheckAndGetCounterType(
849         t_FmPort *p_FmPort, e_FmPortCounters counter,
850         enum fman_port_stats_counters *p_StatsType,
851         enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
852 {
853     volatile uint32_t *p_Reg;
854     bool isValid;
855 
856     switch (p_FmPort->portType)
857     {
858         case (e_FM_PORT_TYPE_RX_10G):
859         case (e_FM_PORT_TYPE_RX):
860             p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
861             isValid = CheckRxBmiCounter(p_FmPort, counter);
862             break;
863         case (e_FM_PORT_TYPE_TX_10G):
864         case (e_FM_PORT_TYPE_TX):
865             p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
866             isValid = CheckTxBmiCounter(p_FmPort, counter);
867             break;
868         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
869         case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
870             p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
871             isValid = CheckOhBmiCounter(p_FmPort, counter);
872             break;
873         default:
874             RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
875     }
876 
877     if (!isValid)
878         RETURN_ERROR(MINOR, E_INVALID_STATE,
879                      ("Requested counter is not available for this port type"));
880 
881     /* check that counters are enabled */
882     switch (counter)
883     {
884         case (e_FM_PORT_COUNTERS_CYCLE):
885         case (e_FM_PORT_COUNTERS_TASK_UTIL):
886         case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
887         case (e_FM_PORT_COUNTERS_DMA_UTIL):
888         case (e_FM_PORT_COUNTERS_FIFO_UTIL):
889         case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
890             /* performance counters - may be read when disabled */
891             *p_IsStats = FALSE;
892             break;
893         case (e_FM_PORT_COUNTERS_FRAME):
894         case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
895         case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
896         case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
897         case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
898         case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
899         case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
900         case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
901         case (e_FM_PORT_COUNTERS_LENGTH_ERR):
902         case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
903         case (e_FM_PORT_COUNTERS_WRED_DISCARD):
904             *p_IsStats = TRUE;
905             if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
906                 RETURN_ERROR(MINOR, E_INVALID_STATE,
907                              ("Requested counter was not enabled"));
908             break;
909         default:
910             break;
911     }
912 
913     /* Set counter */
914     switch (counter)
915     {
916         case (e_FM_PORT_COUNTERS_CYCLE):
917             *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
918             break;
919         case (e_FM_PORT_COUNTERS_TASK_UTIL):
920             *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
921             break;
922         case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
923             *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
924             break;
925         case (e_FM_PORT_COUNTERS_DMA_UTIL):
926             *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
927             break;
928         case (e_FM_PORT_COUNTERS_FIFO_UTIL):
929             *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
930             break;
931         case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
932             *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
933             break;
934         case (e_FM_PORT_COUNTERS_FRAME):
935             *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
936             break;
937         case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
938             *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
939             break;
940         case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
941             *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
942             break;
943         case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
944             *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
945             break;
946         case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
947             *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
948             break;
949         case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
950             *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
951             break;
952         case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
953             *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
954             break;
955         case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
956             *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
957             break;
958         case (e_FM_PORT_COUNTERS_WRED_DISCARD):
959             *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
960             break;
961         case (e_FM_PORT_COUNTERS_LENGTH_ERR):
962             *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
963             break;
964         case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
965             *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
966             break;
967         default:
968             break;
969     }
970 
971     return E_OK;
972 }
973 
974 static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
975                                    t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
976                                    uint32_t *p_SoftSeqAttachReg)
977 {
978     uint8_t hdrNum, Ipv4HdrNum;
979     u_FmPcdHdrPrsOpts *p_prsOpts;
980     uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
981 
982     if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
983             || IS_SPECIAL_HEADER(p_HdrParams->hdr))
984         RETURN_ERROR(
985                 MAJOR, E_NOT_SUPPORTED,
986                 ("No additional parameters for private or special headers."));
987 
988     if (p_HdrParams->errDisable)
989         tmpReg |= PRS_HDR_ERROR_DIS;
990 
991     /* Set parser options */
992     if (p_HdrParams->usePrsOpts)
993     {
994         p_prsOpts = &p_HdrParams->prsOpts;
995         switch (p_HdrParams->hdr)
996         {
997             case (HEADER_TYPE_MPLS):
998                 if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
999                     tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
1000                 hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
1001                 if (hdrNum == ILLEGAL_HDR_NUM)
1002                     RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1003                 Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1004                 if (hdrNum < Ipv4HdrNum)
1005                     RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1006                                  ("Header must be equal or higher than IPv4"));
1007                 tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
1008                         << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1009                 break;
1010             case (HEADER_TYPE_PPPoE):
1011                 if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
1012                     tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
1013                 break;
1014             case (HEADER_TYPE_IPv6):
1015                 if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
1016                     tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
1017                 break;
1018             case (HEADER_TYPE_TCP):
1019                 if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
1020                     tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
1021                 else
1022                     tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
1023                 break;
1024             case (HEADER_TYPE_UDP):
1025                 if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
1026                     tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
1027                 else
1028                     tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
1029                 break;
1030             default:
1031                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
1032         }
1033     }
1034 
1035     /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
1036     if (p_HdrParams->swPrsEnable)
1037     {
1038         tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
1039                                            p_HdrParams->indexPerHdr);
1040         if (tmpPrsOffset == ILLEGAL_BASE)
1041             RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1042         tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
1043     }
1044     *p_SoftSeqAttachReg = tmpReg;
1045 
1046     return E_OK;
1047 }
1048 
1049 static uint32_t GetPortSchemeBindParams(
1050         t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
1051 {
1052     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1053     uint32_t walking1Mask = 0x80000000, tmp;
1054     uint8_t idx = 0;
1055 
1056     p_SchemeBind->netEnvId = p_FmPort->netEnvId;
1057     p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
1058     p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
1059     p_SchemeBind->numOfSchemes = 0;
1060     tmp = p_FmPort->schemesPerPortVector;
1061     if (tmp)
1062     {
1063         while (tmp)
1064         {
1065             if (tmp & walking1Mask)
1066             {
1067                 p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
1068                 p_SchemeBind->numOfSchemes++;
1069                 tmp &= ~walking1Mask;
1070             }
1071             walking1Mask >>= 1;
1072             idx++;
1073         }
1074     }
1075 
1076     return tmp;
1077 }
1078 
1079 static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
1080 {
1081     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1082     volatile uint32_t *p_BmiCfgReg = NULL;
1083     uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
1084     uint32_t lcv, walking1Mask = 0x80000000;
1085     uint8_t cnt = 0;
1086 
1087     ASSERT_COND(p_FmPort);
1088     ASSERT_COND(p_FmPort->h_FmPcd);
1089     ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
1090 
1091     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1092             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
1093         return;
1094 
1095     p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
1096     /* get LCV for MACSEC */
1097     if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
1098                     != 0)
1099     {
1100         while (!(lcv & walking1Mask))
1101         {
1102             cnt++;
1103             walking1Mask >>= 1;
1104         }
1105 
1106         macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
1107         WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
1108     }
1109 }
1110 
1111 static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
1112 {
1113     t_Error err = E_OK;
1114     uint32_t tmpReg;
1115     volatile uint32_t *p_BmiNia = NULL;
1116     volatile uint32_t *p_BmiPrsNia = NULL;
1117     volatile uint32_t *p_BmiPrsStartOffset = NULL;
1118     volatile uint32_t *p_BmiInitPrsResult = NULL;
1119     volatile uint32_t *p_BmiCcBase = NULL;
1120     uint16_t hdrNum, L3HdrNum, greHdrNum;
1121     int i;
1122     bool isEmptyClsPlanGrp;
1123     uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
1124     uint16_t absoluteProfileId;
1125     uint8_t physicalSchemeId;
1126     uint32_t ccTreePhysOffset;
1127     t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1128     uint32_t initialSwPrs = 0;
1129 
1130     ASSERT_COND(p_FmPort);
1131     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1132 
1133     if (p_FmPort->imEn)
1134         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1135                      ("available for non-independant mode ports only"));
1136 
1137     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1138             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1139             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1140         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1141                      ("available for Rx and offline parsing ports only"));
1142 
1143     p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
1144 
1145     p_FmPort->pcdEngines = 0;
1146 
1147     /* initialize p_FmPort->pcdEngines field in port's structure */
1148     switch (p_PcdParams->pcdSupport)
1149     {
1150         case (e_FM_PORT_PCD_SUPPORT_NONE):
1151             RETURN_ERROR(
1152                     MAJOR,
1153                     E_INVALID_STATE,
1154                     ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
1155         case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1156             p_FmPort->pcdEngines |= FM_PCD_PRS;
1157             break;
1158         case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
1159             p_FmPort->pcdEngines |= FM_PCD_PLCR;
1160             break;
1161         case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1162             p_FmPort->pcdEngines |= FM_PCD_PRS;
1163             p_FmPort->pcdEngines |= FM_PCD_PLCR;
1164             break;
1165         case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1166             p_FmPort->pcdEngines |= FM_PCD_PRS;
1167             p_FmPort->pcdEngines |= FM_PCD_KG;
1168             break;
1169         case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1170             p_FmPort->pcdEngines |= FM_PCD_PRS;
1171             p_FmPort->pcdEngines |= FM_PCD_CC;
1172             p_FmPort->pcdEngines |= FM_PCD_KG;
1173             break;
1174         case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1175             p_FmPort->pcdEngines |= FM_PCD_PRS;
1176             p_FmPort->pcdEngines |= FM_PCD_KG;
1177             p_FmPort->pcdEngines |= FM_PCD_CC;
1178             p_FmPort->pcdEngines |= FM_PCD_PLCR;
1179             break;
1180         case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1181             p_FmPort->pcdEngines |= FM_PCD_PRS;
1182             p_FmPort->pcdEngines |= FM_PCD_CC;
1183             break;
1184         case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1185             p_FmPort->pcdEngines |= FM_PCD_PRS;
1186             p_FmPort->pcdEngines |= FM_PCD_CC;
1187             p_FmPort->pcdEngines |= FM_PCD_PLCR;
1188             break;
1189         case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1190             p_FmPort->pcdEngines |= FM_PCD_PRS;
1191             p_FmPort->pcdEngines |= FM_PCD_KG;
1192             p_FmPort->pcdEngines |= FM_PCD_PLCR;
1193             break;
1194         case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
1195             p_FmPort->pcdEngines |= FM_PCD_CC;
1196             break;
1197 #ifdef FM_CAPWAP_SUPPORT
1198             case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
1199             p_FmPort->pcdEngines |= FM_PCD_CC;
1200             p_FmPort->pcdEngines |= FM_PCD_KG;
1201             break;
1202             case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
1203             p_FmPort->pcdEngines |= FM_PCD_CC;
1204             p_FmPort->pcdEngines |= FM_PCD_KG;
1205             p_FmPort->pcdEngines |= FM_PCD_PLCR;
1206             break;
1207 #endif /* FM_CAPWAP_SUPPORT */
1208 
1209         default:
1210             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
1211     }
1212 
1213     if ((p_FmPort->pcdEngines & FM_PCD_PRS)
1214             && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
1215                     > FM_PCD_PRS_NUM_OF_HDRS))
1216         RETURN_ERROR(
1217                 MAJOR,
1218                 E_INVALID_VALUE,
1219                 ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
1220 
1221     /* check that parameters exist for each and only each defined engine */
1222     if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
1223             || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
1224                     != !!p_PcdParams->p_KgParams)
1225             || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
1226                     != !!p_PcdParams->p_CcParams))
1227         RETURN_ERROR(
1228                 MAJOR,
1229                 E_INVALID_STATE,
1230                 ("PCD initialization structure is not consistent with pcdSupport"));
1231 
1232     /* get PCD registers pointers */
1233     switch (p_FmPort->portType)
1234     {
1235         case (e_FM_PORT_TYPE_RX_10G):
1236         case (e_FM_PORT_TYPE_RX):
1237             p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1238             p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
1239             p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1240             p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
1241             p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
1242             break;
1243         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1244             p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1245             p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
1246             p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1247             p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
1248             p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
1249             break;
1250         default:
1251             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1252     }
1253 
1254     /* set PCD port parameter */
1255     if (p_FmPort->pcdEngines & FM_PCD_CC)
1256     {
1257         err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
1258                               p_PcdParams->p_CcParams->h_CcTree,
1259                               &ccTreePhysOffset, p_FmPort);
1260         if (err)
1261             RETURN_ERROR(MAJOR, err, NO_MSG);
1262 
1263         WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
1264         p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
1265     }
1266 
1267     if (p_FmPort->pcdEngines & FM_PCD_KG)
1268     {
1269         if (p_PcdParams->p_KgParams->numOfSchemes == 0)
1270             RETURN_ERROR(
1271                     MAJOR,
1272                     E_INVALID_VALUE,
1273                     ("For ports using Keygen, at least one scheme must be bound. "));
1274 
1275         err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
1276                                            p_FmPort->hardwarePortId,
1277                                            p_FmPort->netEnvId,
1278                                            p_FmPort->optArray,
1279                                            &p_FmPort->clsPlanGrpId,
1280                                            &isEmptyClsPlanGrp);
1281         if (err)
1282             RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1283                          ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
1284 
1285         p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
1286 
1287         schemeBind.netEnvId = p_FmPort->netEnvId;
1288         schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
1289         schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
1290         schemeBind.useClsPlan = p_FmPort->useClsPlan;
1291 
1292         /* for each scheme */
1293         for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1294         {
1295             ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
1296             physicalSchemeId = FmPcdKgGetSchemeId(
1297                     p_PcdParams->p_KgParams->h_Schemes[i]);
1298             schemeBind.schemesIds[i] = physicalSchemeId;
1299             /* build vector */
1300             p_FmPort->schemesPerPortVector |= 1
1301                     << (31 - (uint32_t)physicalSchemeId);
1302 #if (DPAA_VERSION >= 11)
1303             /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
1304              if !VSPE - in port, for relevant scheme VSPE can not be set*/
1305             if (!p_FmPort->vspe
1306                     && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
1307                 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1308                              ("VSPE is not at port level"));
1309 #endif /* (DPAA_VERSION >= 11) */
1310         }
1311 
1312         err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1313         if (err)
1314             RETURN_ERROR(MAJOR, err, NO_MSG);
1315     }
1316 
1317     /***************************/
1318     /* configure NIA after BMI */
1319     /***************************/
1320     /* rfne may contain FDCS bits, so first we read them. */
1321     p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
1322 
1323     /* If policer is used directly after BMI or PRS */
1324     if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
1325             && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
1326                     || (p_PcdParams->pcdSupport
1327                             == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
1328     {
1329         if (!p_PcdParams->p_PlcrParams->h_Profile)
1330             RETURN_ERROR(MAJOR, E_INVALID_STATE,
1331                          ("Profile should be initialized"));
1332 
1333         absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
1334                 p_PcdParams->p_PlcrParams->h_Profile);
1335 
1336         if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
1337             RETURN_ERROR(MAJOR, E_INVALID_STATE,
1338                          ("Private port profile not valid."));
1339 
1340         tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
1341 
1342         if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
1343             /* update BMI HPNIA */
1344             WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
1345         else
1346             /* e_FM_PCD_SUPPORT_PLCR_ONLY */
1347             /* update BMI NIA */
1348             p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
1349     }
1350 
1351     /* if CC is used directly after BMI */
1352     if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
1353 #ifdef FM_CAPWAP_SUPPORT
1354     || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
1355     || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
1356 #endif /* FM_CAPWAP_SUPPORT */
1357     )
1358     {
1359         if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1360             RETURN_ERROR(
1361                     MAJOR,
1362                     E_INVALID_OPERATION,
1363                     ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
1364         p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
1365         /* check that prs start offset == RIM[FOF] */
1366     }
1367 
1368     if (p_FmPort->pcdEngines & FM_PCD_PRS)
1369     {
1370         ASSERT_COND(p_PcdParams->p_PrsParams);
1371 #if (DPAA_VERSION >= 11)
1372         if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
1373             hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
1374         else
1375         {
1376 #endif /* (DPAA_VERSION >= 11) */
1377             /* if PRS is used it is always first */
1378                 hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
1379             if (hdrNum == ILLEGAL_HDR_NUM)
1380                 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
1381 #if (DPAA_VERSION >= 11)
1382         }
1383 #endif /* (DPAA_VERSION >= 11) */
1384         p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
1385         /* set after parser NIA */
1386         tmpReg = 0;
1387         switch (p_PcdParams->pcdSupport)
1388         {
1389             case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1390                 WRITE_UINT32(*p_BmiPrsNia,
1391                              GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
1392                 break;
1393             case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1394             case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1395                 tmpReg = NIA_KG_CC_EN;
1396             case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1397             case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1398                 if (p_PcdParams->p_KgParams->directScheme)
1399                 {
1400                     physicalSchemeId = FmPcdKgGetSchemeId(
1401                             p_PcdParams->p_KgParams->h_DirectScheme);
1402                     /* check that this scheme was bound to this port */
1403                     for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1404                         if (p_PcdParams->p_KgParams->h_DirectScheme
1405                                 == p_PcdParams->p_KgParams->h_Schemes[i])
1406                             break;
1407                     if (i == p_PcdParams->p_KgParams->numOfSchemes)
1408                         RETURN_ERROR(
1409                                 MAJOR,
1410                                 E_INVALID_VALUE,
1411                                 ("Direct scheme is not one of the port selected schemes."));
1412                     tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
1413                 }
1414                 WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
1415                 break;
1416             case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1417             case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1418                 WRITE_UINT32(*p_BmiPrsNia,
1419                              (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
1420                 break;
1421             case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1422                 break;
1423             default:
1424                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
1425         }
1426 
1427         /* set start parsing offset */
1428         WRITE_UINT32(*p_BmiPrsStartOffset,
1429                      p_PcdParams->p_PrsParams->parsingOffset);
1430 
1431         /************************************/
1432         /* Parser port parameters           */
1433         /************************************/
1434         /* stop before configuring */
1435         WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1436         /* wait for parser to be in idle state */
1437         while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1438             ;
1439 
1440         /* set soft seq attachment register */
1441         memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
1442 
1443         /* set protocol options */
1444         for (i = 0; p_FmPort->optArray[i]; i++)
1445             switch (p_FmPort->optArray[i])
1446             {
1447                 case (ETH_BROADCAST):
1448                     hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1449                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
1450                     break;
1451                 case (ETH_MULTICAST):
1452                     hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1453                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
1454                     break;
1455                 case (VLAN_STACKED):
1456                     hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
1457                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
1458                     break;
1459                 case (MPLS_STACKED):
1460                     hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1461                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
1462                     break;
1463                 case (IPV4_BROADCAST_1):
1464                     hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1465                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
1466                     break;
1467                 case (IPV4_MULTICAST_1):
1468                     hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1469                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
1470                     break;
1471                 case (IPV4_UNICAST_2):
1472 					hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1473                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
1474                     break;
1475                 case (IPV4_MULTICAST_BROADCAST_2):
1476 					hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1477                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
1478                     break;
1479                 case (IPV6_MULTICAST_1):
1480                     hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1481                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
1482                     break;
1483                 case (IPV6_UNICAST_2):
1484                     hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1485                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
1486                     break;
1487                 case (IPV6_MULTICAST_2):
1488                     hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1489                     tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
1490                     break;
1491             }
1492 
1493         if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1494                                   HEADER_TYPE_UDP_ENCAP_ESP))
1495         {
1496             if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
1497                 RETURN_ERROR(
1498                          MINOR, E_INVALID_VALUE,
1499                          ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
1500 
1501             p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
1502                     HEADER_TYPE_UDP;
1503             p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
1504                     TRUE;
1505             p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
1506         }
1507 
1508         /* set MPLS default next header - HW reset workaround  */
1509         hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1510         tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
1511         L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
1512         tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1513 
1514         /* for GRE, disable errors */
1515         greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
1516         tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
1517 
1518         /* For UDP remove PAD from L4 checksum calculation */
1519         hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
1520         tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
1521         /* For TCP remove PAD from L4 checksum calculation */
1522         hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
1523         tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
1524 
1525         /* config additional params for specific headers */
1526         for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
1527                 i++)
1528         {
1529             /* case for using sw parser as the initial NIA address, before
1530                * HW parsing
1531                */
1532             if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
1533                     p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
1534             {
1535                 initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
1536                                p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
1537                 if (initialSwPrs == ILLEGAL_BASE)
1538                     RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1539 
1540                 /* clear parser first HXS */
1541                 p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
1542                 /* rewrite with soft parser start */
1543                 p_FmPort->savedBmiNia |= initialSwPrs;
1544                 continue;
1545             }
1546 
1547             hdrNum =
1548                 GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
1549             if (hdrNum == ILLEGAL_HDR_NUM)
1550                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1551             if (hdrNum == NO_HDR_NUM)
1552                 RETURN_ERROR(
1553                         MAJOR, E_INVALID_VALUE,
1554                         ("Private headers may not use additional parameters"));
1555 
1556             err = AdditionalPrsParams(
1557                     p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
1558                     &tmpHxs[hdrNum]);
1559             if (err)
1560                 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1561         }
1562 
1563         /* Check if ip-reassembly port - need to link sw-parser code */
1564         if (p_FmPort->h_IpReassemblyManip)
1565         {
1566            /* link to sw parser code for IP Frag - only if no other code is applied. */
1567             hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1568             if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1569                 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
1570             hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1571             if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1572                 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
1573         } else {
1574             if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
1575             {
1576                 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1577                 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1578                     tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1579             } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1580                        && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
1581                 {
1582                     hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1583                     if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1584                         tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1585                 }
1586             }
1587 
1588 #if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
1589         if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1590                         HEADER_TYPE_UDP_LITE))
1591         {
1592             /* link to sw parser code for udp lite - only if no other code is applied. */
1593             hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1594             if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1595             tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
1596         }
1597 #endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
1598         for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
1599         {
1600             /* For all header set LCV as taken from netEnv*/
1601             WRITE_UINT32(
1602                     p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
1603                     FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
1604             /* set HXS register according to default+Additional params+protocol options */
1605             WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
1606                          tmpHxs[i]);
1607         }
1608 
1609         /* set tpid. */
1610         tmpReg = PRS_TPID_DFLT;
1611         if (p_PcdParams->p_PrsParams->setVlanTpid1)
1612         {
1613             tmpReg &= PRS_TPID2_MASK;
1614             tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
1615                     << PRS_PCTPID_SHIFT;
1616         }
1617         if (p_PcdParams->p_PrsParams->setVlanTpid2)
1618         {
1619             tmpReg &= PRS_TPID1_MASK;
1620             tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
1621         }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
1622 
1623         /* enable parser */
1624         WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
1625 
1626         if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
1627             p_FmPort->privateInfo =
1628                     p_PcdParams->p_PrsParams->prsResultPrivateInfo;
1629 
1630     } /* end parser */
1631     else {
1632         if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1633             && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1634         {
1635             hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1636             WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
1637                          (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
1638         }
1639 
1640         WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1641 
1642         p_FmPort->privateInfo = 0;
1643     }
1644 
1645     FmPortCheckNApplyMacsec(p_FmPort);
1646 
1647     WRITE_UINT32(
1648             *p_BmiPrsStartOffset,
1649             GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
1650 
1651     /* set initial parser result - used for all engines */
1652     for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
1653     {
1654         if (!i)
1655             WRITE_UINT32(
1656                     *(p_BmiInitPrsResult),
1657                     (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
1658         else
1659         {
1660             if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
1661                 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
1662             else
1663                 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
1664         }
1665     }
1666 
1667     return E_OK;
1668 }
1669 
1670 static t_Error DeletePcd(t_FmPort *p_FmPort)
1671 {
1672     t_Error err = E_OK;
1673     volatile uint32_t *p_BmiNia = NULL;
1674     volatile uint32_t *p_BmiPrsStartOffset = NULL;
1675 
1676     ASSERT_COND(p_FmPort);
1677     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1678 
1679     if (p_FmPort->imEn)
1680         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1681                      ("available for non-independant mode ports only"));
1682 
1683     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1684             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1685             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1686         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1687                      ("available for Rx and offline parsing ports only"));
1688 
1689     if (!p_FmPort->pcdEngines)
1690         RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
1691 
1692     /* get PCD registers pointers */
1693     switch (p_FmPort->portType)
1694     {
1695         case (e_FM_PORT_TYPE_RX_10G):
1696         case (e_FM_PORT_TYPE_RX):
1697             p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1698             p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1699             break;
1700         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1701             p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1702             p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1703             break;
1704         default:
1705             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1706     }
1707 
1708     if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1709             != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1710         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1711                      ("port has to be detached previousely"));
1712 
1713     WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1714 
1715     /* "cut" PCD out of the port's flow - go to BMI */
1716     /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
1717 
1718     if (p_FmPort->pcdEngines & FM_PCD_PRS)
1719     {
1720         /* stop parser */
1721         WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1722         /* wait for parser to be in idle state */
1723         while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1724             ;
1725     }
1726 
1727     if (p_FmPort->pcdEngines & FM_PCD_KG)
1728     {
1729         t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1730 
1731         /* unbind all schemes */
1732         p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
1733                                                                  &schemeBind);
1734 
1735         err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1736         if (err)
1737             RETURN_ERROR(MAJOR, err, NO_MSG);
1738 
1739         err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
1740                                                     p_FmPort->hardwarePortId,
1741                                                     p_FmPort->clsPlanGrpId);
1742         if (err)
1743             RETURN_ERROR(MAJOR, err, NO_MSG);
1744         p_FmPort->useClsPlan = FALSE;
1745     }
1746 
1747     if (p_FmPort->pcdEngines & FM_PCD_CC)
1748     {
1749         /* unbind - we need to get the treeId too */
1750         err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
1751         if (err)
1752             RETURN_ERROR(MAJOR, err, NO_MSG);
1753     }
1754 
1755     p_FmPort->pcdEngines = 0;
1756 
1757     return E_OK;
1758 }
1759 
1760 static t_Error AttachPCD(t_FmPort *p_FmPort)
1761 {
1762     volatile uint32_t *p_BmiNia = NULL;
1763 
1764     ASSERT_COND(p_FmPort);
1765 
1766     /* get PCD registers pointers */
1767     if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1768         p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1769     else
1770         p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1771 
1772     /* check that current NIA is BMI to BMI */
1773     if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
1774             != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1775         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1776                      ("may be called only for ports in BMI-to-BMI state."));
1777 
1778     if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1779         if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
1780                                    p_FmPort->orFmanCtrl) != E_OK)
1781             RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1782 
1783     if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
1784     {
1785         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1786             WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
1787                          p_FmPort->savedBmiCmne);
1788         else
1789             WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
1790                          p_FmPort->savedBmiCmne);
1791     }
1792 
1793     if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1794         WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
1795                      p_FmPort->savedQmiPnen);
1796 
1797     if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1798     {
1799         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1800             WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1801                          p_FmPort->savedBmiFene);
1802         else
1803             WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1804                          p_FmPort->savedBmiFene);
1805     }
1806 
1807     if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
1808     {
1809         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1810             WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
1811                          p_FmPort->savedBmiFpne);
1812         else
1813             WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
1814                          p_FmPort->savedBmiFpne);
1815     }
1816 
1817     if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
1818     {
1819         ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
1820 
1821         WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
1822                      p_FmPort->savedBmiOfp);
1823     }
1824 
1825     WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
1826 
1827     if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1828     {
1829         p_FmPort->origNonRxQmiRegsPndn =
1830                 GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
1831         WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1832                      p_FmPort->savedNonRxQmiRegsPndn);
1833     }
1834 
1835     return E_OK;
1836 }
1837 
1838 static t_Error DetachPCD(t_FmPort *p_FmPort)
1839 {
1840     volatile uint32_t *p_BmiNia = NULL;
1841 
1842     ASSERT_COND(p_FmPort);
1843 
1844     /* get PCD registers pointers */
1845     if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1846         WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1847                      p_FmPort->origNonRxQmiRegsPndn);
1848 
1849     if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1850         p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1851     else
1852         p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1853 
1854     WRITE_UINT32(
1855             *p_BmiNia,
1856             (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
1857 
1858     if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
1859         FmPcdHcSync(p_FmPort->h_FmPcd);
1860 
1861     if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1862     {
1863         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1864             WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1865                          NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1866         else
1867             WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1868                          NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1869     }
1870 
1871     if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1872         WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
1873                      NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
1874 
1875     if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1876         if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
1877                                    p_FmPort->orFmanCtrl) != E_OK)
1878             RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1879 
1880     p_FmPort->requiredAction = 0;
1881 
1882     return E_OK;
1883 }
1884 
1885 /*****************************************************************************/
1886 /*              Inter-module API routines                                    */
1887 /*****************************************************************************/
1888 void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
1889 {
1890     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1891     volatile uint32_t *p_BmiCfgReg = NULL;
1892     uint32_t tmpReg;
1893 
1894     SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
1895     SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1896 
1897     if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
1898             && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
1899     {
1900         REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
1901         return;
1902     }
1903 
1904     p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
1905     tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
1906     tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
1907     tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
1908             & BMI_CMD_ATTR_MACCMD_SC_MASK);
1909 
1910     WRITE_UINT32(*p_BmiCfgReg, tmpReg);
1911 }
1912 
1913 uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
1914 {
1915     return ((t_FmPort*)h_FmPort)->netEnvId;
1916 }
1917 
1918 uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
1919 {
1920     return ((t_FmPort*)h_FmPort)->hardwarePortId;
1921 }
1922 
1923 uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
1924 {
1925     return ((t_FmPort*)h_FmPort)->pcdEngines;
1926 }
1927 
1928 #if (DPAA_VERSION >= 11)
1929 t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
1930                          void **p_Value)
1931 {
1932     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1933     uint32_t muramPageOffset;
1934 
1935     ASSERT_COND(p_FmPort);
1936     ASSERT_COND(p_Value);
1937 
1938     if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
1939     {
1940         if (p_FmPort->gprFunc != gprFunc)
1941             RETURN_ERROR(MAJOR, E_INVALID_STATE,
1942                          ("gpr was assigned with different func"));
1943     }
1944     else
1945     {
1946         switch (gprFunc)
1947         {
1948             case (e_FM_PORT_GPR_MURAM_PAGE):
1949                 p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
1950                                                            256, 8);
1951                 if (!p_FmPort->p_ParamsPage)
1952                     RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
1953 
1954                 IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
1955                 muramPageOffset =
1956                         (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
1957                                 - p_FmPort->fmMuramPhysBaseAddr);
1958                 switch (p_FmPort->portType)
1959                 {
1960                     case (e_FM_PORT_TYPE_RX_10G):
1961                     case (e_FM_PORT_TYPE_RX):
1962                         WRITE_UINT32(
1963                                 p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
1964                                 muramPageOffset);
1965                         break;
1966                     case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1967                         WRITE_UINT32(
1968                                 p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
1969                                 muramPageOffset);
1970                         break;
1971                     default:
1972                         RETURN_ERROR(MAJOR, E_INVALID_STATE,
1973                                      ("Invalid port type"));
1974                 }
1975                 break;
1976             default:
1977                 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1978         }
1979         p_FmPort->gprFunc = gprFunc;
1980     }
1981 
1982     switch (p_FmPort->gprFunc)
1983     {
1984         case (e_FM_PORT_GPR_MURAM_PAGE):
1985             *p_Value = p_FmPort->p_ParamsPage;
1986             break;
1987         default:
1988             RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1989     }
1990 
1991     return E_OK;
1992 }
1993 #endif /* (DPAA_VERSION >= 11) */
1994 
1995 t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
1996                              t_FmPortGetSetCcParams *p_CcParams)
1997 {
1998     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1999     uint32_t tmpInt;
2000     volatile uint32_t *p_BmiPrsStartOffset = NULL;
2001 
2002     /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
2003 
2004     if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
2005             && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
2006     {
2007         p_CcParams->getCcParams.prOffset =
2008                 (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
2009         p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
2010     }
2011     if (p_CcParams->getCcParams.type & HW_PORT_ID)
2012     {
2013         p_CcParams->getCcParams.hardwarePortId =
2014                 (uint8_t)p_FmPort->hardwarePortId;
2015         p_CcParams->getCcParams.type &= ~HW_PORT_ID;
2016     }
2017     if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
2018             && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
2019     {
2020         p_CcParams->getCcParams.dataOffset =
2021                 (uint16_t)p_FmPort->bufferOffsets.dataOffset;
2022         p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
2023     }
2024     if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
2025     {
2026         p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
2027         p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
2028     }
2029     if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
2030     {
2031         p_CcParams->getCcParams.numOfExtraTasks =
2032                 (uint8_t)p_FmPort->tasks.extra;
2033         p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
2034     }
2035     if (p_CcParams->getCcParams.type & FM_REV)
2036     {
2037         p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
2038         p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
2039         p_CcParams->getCcParams.type &= ~FM_REV;
2040     }
2041     if (p_CcParams->getCcParams.type & DISCARD_MASK)
2042     {
2043         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2044             p_CcParams->getCcParams.discardMask =
2045                     GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
2046         else
2047             p_CcParams->getCcParams.discardMask =
2048                     GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
2049         p_CcParams->getCcParams.type &= ~DISCARD_MASK;
2050     }
2051     if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
2052     {
2053         p_CcParams->getCcParams.internalBufferOffset =
2054                 p_FmPort->internalBufferOffset;
2055         p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
2056     }
2057     if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
2058     {
2059         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2060             p_CcParams->getCcParams.nia =
2061                     GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
2062         else
2063             p_CcParams->getCcParams.nia =
2064                     GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
2065         p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
2066     }
2067     if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
2068     {
2069         if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2070             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2071         p_CcParams->getCcParams.nia =
2072                 GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
2073         p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
2074     }
2075 
2076     if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
2077             && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
2078     {
2079         p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
2080         p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
2081     }
2082 
2083     if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
2084             && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
2085     {
2086         p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
2087         p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
2088     }
2089     else
2090         if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
2091         {
2092             if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
2093                 RETURN_ERROR(MAJOR, E_INVALID_STATE,
2094                              ("PNEN was defined previously different"));
2095         }
2096 
2097     if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
2098             && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
2099     {
2100         p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
2101         p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
2102     }
2103     else
2104         if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
2105         {
2106             if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
2107                 RETURN_ERROR(MAJOR, E_INVALID_STATE,
2108                              ("PNDN was defined previously different"));
2109         }
2110 
2111     if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
2112             && (p_CcParams->setCcParams.overwrite
2113                     || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
2114     {
2115         p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
2116         p_FmPort->requiredAction |= UPDATE_NIA_FENE;
2117     }
2118     else
2119         if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
2120         {
2121             if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
2122                 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2123                              ("xFENE was defined previously different"));
2124         }
2125 
2126     if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
2127             && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
2128     {
2129         p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
2130         p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
2131     }
2132     else
2133         if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
2134         {
2135             if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
2136                 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2137                              ("xFPNE was defined previously different"));
2138         }
2139 
2140     if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
2141             && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
2142     {
2143         p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
2144         p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
2145     }
2146     else
2147         if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
2148         {
2149             if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
2150                 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2151                              ("xCMNE was defined previously different"));
2152         }
2153 
2154     if ((p_CcParams->setCcParams.type & UPDATE_PSO)
2155             && !(p_FmPort->requiredAction & UPDATE_PSO))
2156     {
2157         /* get PCD registers pointers */
2158         switch (p_FmPort->portType)
2159         {
2160             case (e_FM_PORT_TYPE_RX_10G):
2161             case (e_FM_PORT_TYPE_RX):
2162                 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
2163                 break;
2164             case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2165                 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
2166                 break;
2167             default:
2168                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2169         }
2170 
2171         /* set start parsing offset */
2172         tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
2173                 + p_CcParams->setCcParams.psoSize;
2174         if (tmpInt > 0)
2175             WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
2176 
2177         p_FmPort->requiredAction |= UPDATE_PSO;
2178         p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
2179     }
2180     else
2181         if (p_CcParams->setCcParams.type & UPDATE_PSO)
2182         {
2183             if (p_FmPort->savedPrsStartOffset
2184                     != p_CcParams->setCcParams.psoSize)
2185                 RETURN_ERROR(
2186                         MAJOR,
2187                         E_INVALID_STATE,
2188                         ("parser start offset was defoned previousley different"));
2189         }
2190 
2191     if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
2192             && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
2193     {
2194         if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2195             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2196         p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
2197         p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
2198         p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
2199                 << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
2200         p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
2201     }
2202 
2203     return E_OK;
2204 }
2205 /*********************** End of inter-module routines ************************/
2206 
2207 /****************************************/
2208 /*       API Init unit functions        */
2209 /****************************************/
2210 
2211 t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
2212 {
2213     t_FmPort *p_FmPort;
2214     uintptr_t baseAddr = p_FmPortParams->baseAddr;
2215     uint32_t tmpReg;
2216 
2217     /* Allocate FM structure */
2218     p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
2219     if (!p_FmPort)
2220     {
2221         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
2222         return NULL;
2223     }
2224     memset(p_FmPort, 0, sizeof(t_FmPort));
2225 
2226     /* Allocate the FM driver's parameters structure */
2227     p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
2228             sizeof(t_FmPortDriverParam));
2229     if (!p_FmPort->p_FmPortDriverParam)
2230     {
2231         XX_Free(p_FmPort);
2232         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
2233         return NULL;
2234     }
2235     memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
2236 
2237     /* Initialize FM port parameters which will be kept by the driver */
2238     p_FmPort->portType = p_FmPortParams->portType;
2239     p_FmPort->portId = p_FmPortParams->portId;
2240     p_FmPort->pcdEngines = FM_PCD_NONE;
2241     p_FmPort->f_Exception = p_FmPortParams->f_Exception;
2242     p_FmPort->h_App = p_FmPortParams->h_App;
2243     p_FmPort->h_Fm = p_FmPortParams->h_Fm;
2244 
2245     /* get FM revision */
2246     FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
2247 
2248     /* calculate global portId number */
2249     p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
2250                                     p_FmPortParams->portId,
2251                                     p_FmPort->fmRevInfo.majorRev,
2252                                     p_FmPort->fmRevInfo.minorRev);
2253 
2254     if (p_FmPort->fmRevInfo.majorRev >= 6)
2255     {
2256         if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2257                 && (p_FmPortParams->portId != FM_OH_PORT_ID))
2258             DBG(WARNING,
2259                     ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
2260                             FM_OH_PORT_ID));
2261 
2262         if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2263                 && (p_FmPortParams->portId == FM_OH_PORT_ID))
2264             DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
2265     }
2266 
2267     /* Set up FM port parameters for initialization phase only */
2268 
2269     /* First, fill in flibs struct */
2270     fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
2271                         (enum fman_port_type)p_FmPort->portType);
2272     /* Overwrite some integration specific parameters */
2273     p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
2274             DEFAULT_PORT_rxFifoPriElevationLevel;
2275     p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
2276             DEFAULT_PORT_rxFifoThreshold;
2277 
2278 #if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
2279     p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
2280 #else
2281     p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
2282 #endif
2283     if ((p_FmPort->fmRevInfo.majorRev == 6)
2284             && (p_FmPort->fmRevInfo.minorRev == 0))
2285         p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
2286     else
2287         p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
2288 
2289     /* Excessive Threshold register - exists for pre-FMv3 chips only */
2290     if (p_FmPort->fmRevInfo.majorRev < 6)
2291     {
2292 #ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
2293         p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
2294                 TRUE;
2295 #endif
2296         p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
2297         p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
2298     }
2299     else
2300     {
2301         p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
2302                 FALSE;
2303         p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
2304         p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
2305     }
2306     if (p_FmPort->fmRevInfo.majorRev == 4)
2307         p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
2308     else
2309         p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
2310 
2311     /* Continue with other parameters */
2312     p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
2313     /* set memory map pointers */
2314     p_FmPort->p_FmPortQmiRegs =
2315             (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
2316     p_FmPort->p_FmPortBmiRegs =
2317             (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
2318     p_FmPort->p_FmPortPrsRegs =
2319             (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
2320 
2321     p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
2322             DEFAULT_PORT_bufferPrefixContent_privDataSize;
2323     p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
2324             DEFAULT_PORT_bufferPrefixContent_passPrsResult;
2325     p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
2326             DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
2327     p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
2328             DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
2329     p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
2330             DEFAULT_PORT_bufferPrefixContent_dataAlign;
2331     /*    p_FmPort->p_FmPortDriverParam->dmaSwapData                      = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
2332      p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr           = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
2333      p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr               = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
2334      p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr        = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
2335      p_FmPort->p_FmPortDriverParam->dmaWriteOptimize                 = DEFAULT_PORT_dmaWriteOptimize;
2336      */
2337     p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
2338     p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
2339             DEFAULT_PORT_cheksumLastBytesIgnore;
2340 
2341     p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
2342     /* resource distribution. */
2343 	p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
2344 			* BMI_FIFO_UNITS;
2345 	p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
2346 			* BMI_FIFO_UNITS;
2347 	p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
2348 	p_FmPort->openDmas.extra =
2349 			DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
2350 	p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
2351 	p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
2352 
2353 
2354 #ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
2355     if ((p_FmPort->fmRevInfo.majorRev == 6)
2356             && (p_FmPort->fmRevInfo.minorRev == 0)
2357             && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2358                     || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
2359     {
2360         p_FmPort->openDmas.num = 16;
2361         p_FmPort->openDmas.extra = 0;
2362     }
2363 #endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
2364 
2365     /* Port type specific initialization: */
2366     switch (p_FmPort->portType)
2367     {
2368         case (e_FM_PORT_TYPE_RX):
2369         case (e_FM_PORT_TYPE_RX_10G):
2370             /* Initialize FM port parameters for initialization phase only */
2371             p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
2372                     DEFAULT_PORT_cutBytesFromEnd;
2373             p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
2374             p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
2375                     DEFAULT_PORT_frmDiscardOverride;
2376 
2377                 tmpReg =
2378                         GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
2379 			p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
2380                         (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
2381                                 >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
2382                                 * BMI_FIFO_UNITS;
2383                 p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
2384                         & BMI_RX_FIFO_THRESHOLD_MASK)
2385                         >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
2386 
2387             p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
2388                     DEFAULT_PORT_BufMargins_endMargins;
2389             p_FmPort->p_FmPortDriverParam->errorsToDiscard =
2390                     DEFAULT_PORT_errorsToDiscard;
2391             p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
2392                     DEFAULT_PORT_forwardIntContextReuse;
2393 #if (DPAA_VERSION >= 11)
2394             p_FmPort->p_FmPortDriverParam->noScatherGather =
2395                     DEFAULT_PORT_noScatherGather;
2396 #endif /* (DPAA_VERSION >= 11) */
2397             break;
2398 
2399         case (e_FM_PORT_TYPE_TX):
2400             p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
2401 #ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
2402             tmpReg = 0x00001013;
2403             WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
2404                          tmpReg);
2405 #endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
2406         case (e_FM_PORT_TYPE_TX_10G):
2407                 tmpReg =
2408                         GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
2409                 p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
2410                         & BMI_TX_FIFO_MIN_FILL_MASK)
2411                         >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
2412 			p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2413                         (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
2414                                 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
2415                 p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
2416                         & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
2417                         * BMI_FIFO_UNITS;
2418 
2419             p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
2420             p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
2421                     DEFAULT_PORT_deqPrefetchOption;
2422             p_FmPort->p_FmPortDriverParam->deqHighPriority =
2423                     (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
2424                             DEFAULT_PORT_deqHighPriority_10G);
2425             p_FmPort->p_FmPortDriverParam->deqByteCnt =
2426                     (uint16_t)(
2427                             (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
2428                                     DEFAULT_PORT_deqByteCnt_10G);
2429             break;
2430         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2431             p_FmPort->p_FmPortDriverParam->errorsToDiscard =
2432                     DEFAULT_PORT_errorsToDiscard;
2433 #if (DPAA_VERSION >= 11)
2434             p_FmPort->p_FmPortDriverParam->noScatherGather =
2435                     DEFAULT_PORT_noScatherGather;
2436 #endif /* (DPAA_VERSION >= 11) */
2437         case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
2438             p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
2439                     DEFAULT_PORT_deqPrefetchOption_HC;
2440             p_FmPort->p_FmPortDriverParam->deqHighPriority =
2441                     DEFAULT_PORT_deqHighPriority_1G;
2442             p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
2443             p_FmPort->p_FmPortDriverParam->deqByteCnt =
2444                     DEFAULT_PORT_deqByteCnt_1G;
2445 
2446                 tmpReg =
2447                         GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
2448                 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2449                         (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
2450                                 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
2451                 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2452                         && (p_FmPortParams->portId != FM_OH_PORT_ID))
2453                 {
2454                     /* Overwrite HC defaults */
2455 			p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2456 					DEFAULT_PORT_fifoDeqPipelineDepth_OH;
2457                 }
2458 
2459 #ifndef FM_FRAME_END_PARAMS_FOR_OP
2460             if (p_FmPort->fmRevInfo.majorRev < 6)
2461             p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
2462 #endif /* !FM_FRAME_END_PARAMS_FOR_OP */
2463 
2464 #ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
2465             if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
2466                             (p_FmPort->fmRevInfo.majorRev >= 6)))
2467             p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
2468 #endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
2469             break;
2470 
2471         default:
2472             XX_Free(p_FmPort->p_FmPortDriverParam);
2473             XX_Free(p_FmPort);
2474             REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2475             return NULL;
2476     }
2477 #ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
2478     if (p_FmPort->fmRevInfo.majorRev == 4)
2479     p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
2480 #endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
2481 
2482     p_FmPort->imEn = p_FmPortParams->independentModeEnable;
2483 
2484     if (p_FmPort->imEn)
2485     {
2486         if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
2487                 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
2488             p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2489                     DEFAULT_PORT_fifoDeqPipelineDepth_IM;
2490         FmPortConfigIM(p_FmPort, p_FmPortParams);
2491     }
2492     else
2493     {
2494         switch (p_FmPort->portType)
2495         {
2496             case (e_FM_PORT_TYPE_RX):
2497             case (e_FM_PORT_TYPE_RX_10G):
2498                 /* Initialize FM port parameters for initialization phase only */
2499                 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
2500                        &p_FmPortParams->specificParams.rxParams.extBufPools,
2501                        sizeof(t_FmExtPools));
2502                 p_FmPort->p_FmPortDriverParam->errFqid =
2503                         p_FmPortParams->specificParams.rxParams.errFqid;
2504                 p_FmPort->p_FmPortDriverParam->dfltFqid =
2505                         p_FmPortParams->specificParams.rxParams.dfltFqid;
2506                 p_FmPort->p_FmPortDriverParam->liodnOffset =
2507                         p_FmPortParams->specificParams.rxParams.liodnOffset;
2508                 break;
2509             case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2510             case (e_FM_PORT_TYPE_TX):
2511             case (e_FM_PORT_TYPE_TX_10G):
2512             case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
2513                 p_FmPort->p_FmPortDriverParam->errFqid =
2514                         p_FmPortParams->specificParams.nonRxParams.errFqid;
2515                 p_FmPort->p_FmPortDriverParam->deqSubPortal =
2516                         (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
2517                                 & QMI_DEQ_CFG_SUBPORTAL_MASK);
2518                 p_FmPort->p_FmPortDriverParam->dfltFqid =
2519                         p_FmPortParams->specificParams.nonRxParams.dfltFqid;
2520                 break;
2521             default:
2522                 XX_Free(p_FmPort->p_FmPortDriverParam);
2523                 XX_Free(p_FmPort);
2524                 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2525                 return NULL;
2526         }
2527     }
2528 
2529     memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
2530     if (Sprint(
2531             p_FmPort->name,
2532             "FM-%d-port-%s-%d",
2533             FmGetId(p_FmPort->h_Fm),
2534             ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
2535                     || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
2536                     (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
2537                             (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
2538                                     (p_FmPort->portType
2539                                             == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
2540                                             "10g-TX")))),
2541             p_FmPort->portId) == 0)
2542     {
2543         XX_Free(p_FmPort->p_FmPortDriverParam);
2544         XX_Free(p_FmPort);
2545         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2546         return NULL;
2547     }
2548 
2549     p_FmPort->h_Spinlock = XX_InitSpinlock();
2550     if (!p_FmPort->h_Spinlock)
2551     {
2552         XX_Free(p_FmPort->p_FmPortDriverParam);
2553         XX_Free(p_FmPort);
2554         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2555         return NULL;
2556     }
2557 
2558     return p_FmPort;
2559 }
2560 
2561 t_FmPort *rx_port = 0;
2562 t_FmPort *tx_port = 0;
2563 
2564 /**************************************************************************//**
2565  @Function      FM_PORT_Init
2566 
2567  @Description   Initializes the FM module
2568 
2569  @Param[in]     h_FmPort - FM module descriptor
2570 
2571  @Return        E_OK on success; Error code otherwise.
2572  *//***************************************************************************/
2573 t_Error FM_PORT_Init(t_Handle h_FmPort)
2574 {
2575     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2576     t_FmPortDriverParam *p_DriverParams;
2577     t_Error errCode;
2578     t_FmInterModulePortInitParams fmParams;
2579     t_FmRevisionInfo revInfo;
2580 
2581     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
2582     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2583 
2584     errCode = FmSpBuildBufferStructure(
2585             &p_FmPort->p_FmPortDriverParam->intContext,
2586             &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
2587             &p_FmPort->p_FmPortDriverParam->bufMargins,
2588             &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
2589     if (errCode != E_OK)
2590         RETURN_ERROR(MAJOR, errCode, NO_MSG);
2591 #ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
2592     if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
2593             (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2594     {
2595         p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
2596         if (!p_FmPort->fifoBufs.num)
2597         p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
2598         p_FmPort->fifoBufs.num += 4*KILOBYTE;
2599     }
2600 #endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
2601 
2602     CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
2603 
2604     p_DriverParams = p_FmPort->p_FmPortDriverParam;
2605 
2606     /* Set up flibs port structure */
2607     memset(&p_FmPort->port, 0, sizeof(struct fman_port));
2608     p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
2609     FM_GetRevision(p_FmPort->h_Fm, &revInfo);
2610     p_FmPort->port.fm_rev_maj = revInfo.majorRev;
2611     p_FmPort->port.fm_rev_min = revInfo.minorRev;
2612     p_FmPort->port.bmi_regs =
2613             (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
2614     p_FmPort->port.qmi_regs =
2615             (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
2616     p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
2617     p_FmPort->port.im_en = p_FmPort->imEn;
2618     p_FmPort->p_FmPortPrsRegs =
2619             (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
2620 
2621     if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2622             || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
2623     {
2624         /* Call the external Buffer routine which also checks fifo
2625          size and updates it if necessary */
2626         /* define external buffer pools and pool depletion*/
2627         errCode = SetExtBufferPools(p_FmPort);
2628         if (errCode)
2629             RETURN_ERROR(MAJOR, errCode, NO_MSG);
2630         /* check if the largest external buffer pool is large enough */
2631         if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
2632                 + p_DriverParams->bufMargins.endMargins
2633                 > p_FmPort->rxPoolsParams.largestBufSize)
2634             RETURN_ERROR(
2635                     MAJOR,
2636                     E_INVALID_VALUE,
2637                     ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", p_DriverParams->bufMargins.startMargins, p_DriverParams->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize));
2638     }
2639     if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2640     {
2641         {
2642 #ifdef FM_NO_OP_OBSERVED_POOLS
2643             t_FmRevisionInfo revInfo;
2644 
2645             FM_GetRevision(p_FmPort->h_Fm, &revInfo);
2646             if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
2647 #endif /* FM_NO_OP_OBSERVED_POOLS */
2648             {
2649                 /* define external buffer pools */
2650                 errCode = SetExtBufferPools(p_FmPort);
2651                 if (errCode)
2652                     RETURN_ERROR(MAJOR, errCode, NO_MSG);
2653             }
2654         }
2655     }
2656 
2657     /************************************************************/
2658     /* Call FM module routine for communicating parameters      */
2659     /************************************************************/
2660     memset(&fmParams, 0, sizeof(fmParams));
2661     fmParams.hardwarePortId = p_FmPort->hardwarePortId;
2662     fmParams.portType = (e_FmPortType)p_FmPort->portType;
2663     fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
2664     fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
2665     fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
2666     fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
2667 
2668     if (p_FmPort->fifoBufs.num)
2669     {
2670         errCode = VerifySizeOfFifo(p_FmPort);
2671         if (errCode != E_OK)
2672             RETURN_ERROR(MAJOR, errCode, NO_MSG);
2673     }
2674     fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
2675     fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
2676     fmParams.independentMode = p_FmPort->imEn;
2677     fmParams.liodnOffset = p_DriverParams->liodnOffset;
2678     fmParams.liodnBase = p_DriverParams->liodnBase;
2679     fmParams.deqPipelineDepth =
2680             p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
2681     fmParams.maxFrameLength = p_FmPort->maxFrameLength;
2682 #ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
2683     if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
2684             (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
2685     {
2686         if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
2687                         (p_FmPort->fmRevInfo.majorRev >= 6)))
2688         /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
2689          * for deq threshold calculation.
2690          */
2691         fmParams.deqPipelineDepth = 2;
2692     }
2693 #endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
2694 
2695     errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
2696     if (errCode)
2697         RETURN_ERROR(MAJOR, errCode, NO_MSG);
2698 
2699     /* get params for use in init */
2700     p_FmPort->fmMuramPhysBaseAddr =
2701             (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
2702                     | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
2703     p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
2704 
2705     errCode = InitLowLevelDriver(p_FmPort);
2706     if (errCode != E_OK)
2707         RETURN_ERROR(MAJOR, errCode, NO_MSG);
2708 
2709     FmPortDriverParamFree(p_FmPort);
2710 
2711 #if (DPAA_VERSION >= 11)
2712     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2713             || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
2714             || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
2715     {
2716         t_FmPcdCtrlParamsPage *p_ParamsPage;
2717 
2718         FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
2719                          (void**)&p_ParamsPage);
2720         ASSERT_COND(p_ParamsPage);
2721 
2722         WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
2723 #ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
2724         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2725         {
2726             WRITE_UINT32(
2727                     p_ParamsPage->misc,
2728                     (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
2729             WRITE_UINT32(
2730                     p_ParamsPage->discardMask,
2731                     GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
2732         }
2733 #endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
2734 #ifdef FM_ERROR_VSP_NO_MATCH_SW006
2735         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2736             WRITE_UINT32(
2737                     p_ParamsPage->errorsDiscardMask,
2738                     (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
2739         else
2740             WRITE_UINT32(
2741                     p_ParamsPage->errorsDiscardMask,
2742                     (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
2743 #endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
2744     }
2745 #endif /* (DPAA_VERSION >= 11) */
2746 
2747     if (p_FmPort->deepSleepVars.autoResMaxSizes)
2748         FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
2749     return E_OK;
2750 }
2751 
2752 /**************************************************************************//**
2753  @Function      FM_PORT_Free
2754 
2755  @Description   Frees all resources that were assigned to FM module.
2756 
2757  Calling this routine invalidates the descriptor.
2758 
2759  @Param[in]     h_FmPort - FM module descriptor
2760 
2761  @Return        E_OK on success; Error code otherwise.
2762  *//***************************************************************************/
2763 t_Error FM_PORT_Free(t_Handle h_FmPort)
2764 {
2765     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2766     t_FmInterModulePortFreeParams fmParams;
2767 
2768     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2769 
2770     if (p_FmPort->pcdEngines)
2771         RETURN_ERROR(
2772                 MAJOR,
2773                 E_INVALID_STATE,
2774                 ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
2775 
2776     if (p_FmPort->enabled)
2777     {
2778         if (FM_PORT_Disable(p_FmPort) != E_OK)
2779             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
2780     }
2781 
2782     if (p_FmPort->imEn)
2783         FmPortImFree(p_FmPort);
2784 
2785     FmPortDriverParamFree(p_FmPort);
2786 
2787     memset(&fmParams, 0, sizeof(fmParams));
2788     fmParams.hardwarePortId = p_FmPort->hardwarePortId;
2789     fmParams.portType = (e_FmPortType)p_FmPort->portType;
2790     fmParams.deqPipelineDepth =
2791             p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
2792 
2793     FmFreePortParams(p_FmPort->h_Fm, &fmParams);
2794 
2795 #if (DPAA_VERSION >= 11)
2796     if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
2797             != E_OK)
2798         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
2799 
2800     if (p_FmPort->p_ParamsPage)
2801         FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
2802 #endif /* (DPAA_VERSION >= 11) */
2803 
2804     if (p_FmPort->h_Spinlock)
2805         XX_FreeSpinlock(p_FmPort->h_Spinlock);
2806 
2807     XX_Free(p_FmPort);
2808 
2809     return E_OK;
2810 }
2811 
2812 /*************************************************/
2813 /*       API Advanced Init unit functions        */
2814 /*************************************************/
2815 
2816 t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
2817 {
2818     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2819 
2820     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2821     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2822 
2823     p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
2824     memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
2825 
2826     return E_OK;
2827 }
2828 
2829 t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
2830 {
2831     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2832 
2833     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2834     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2835 
2836     memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
2837     p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
2838     return E_OK;
2839 }
2840 
2841 t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
2842 {
2843     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2844 
2845     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2846     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2847 
2848     p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
2849     memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
2850 
2851     return E_OK;
2852 }
2853 
2854 t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
2855 {
2856     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2857 
2858     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2859     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2860     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2861             || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2862         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
2863 
2864     p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
2865 
2866     return E_OK;
2867 }
2868 
2869 t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
2870 {
2871     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2872 
2873     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2874     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2875     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2876             || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2877         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2878                      ("not available for Rx ports"));
2879 
2880     p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
2881             (enum fman_port_deq_type)deqType;
2882 
2883     return E_OK;
2884 }
2885 
2886 t_Error FM_PORT_ConfigDeqPrefetchOption(
2887         t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
2888 {
2889     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2890 
2891     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2892     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2893     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2894             || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2895         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2896                      ("not available for Rx ports"));
2897     p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
2898             (enum fman_port_deq_prefetch)deqPrefetchOption;
2899 
2900     return E_OK;
2901 }
2902 
2903 t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
2904                                   t_FmBackupBmPools *p_BackupBmPools)
2905 {
2906     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2907 
2908     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2909     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2910     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2911             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2912         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2913                      ("available for Rx ports only"));
2914 
2915     p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
2916             (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
2917     if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
2918         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
2919     memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
2920            sizeof(t_FmBackupBmPools));
2921 
2922     return E_OK;
2923 }
2924 
2925 t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
2926 {
2927     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2928 
2929     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2930     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2931     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2932             || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2933         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2934                      ("not available for Rx ports"));
2935 
2936     p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
2937 
2938     return E_OK;
2939 }
2940 
2941 t_Error FM_PORT_ConfigBufferPrefixContent(
2942         t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
2943 {
2944     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2945 
2946     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2947     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2948 
2949     memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
2950            p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
2951     /* if dataAlign was not initialized by user, we return to driver's default */
2952     if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
2953         p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
2954                 DEFAULT_PORT_bufferPrefixContent_dataAlign;
2955 
2956     return E_OK;
2957 }
2958 
2959 t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
2960                                              uint8_t checksumLastBytesIgnore)
2961 {
2962     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2963 
2964     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2965     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2966 
2967     p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
2968             checksumLastBytesIgnore;
2969 
2970     return E_OK;
2971 }
2972 
2973 t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
2974                                       uint8_t cutBytesFromEnd)
2975 {
2976     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2977 
2978     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2979     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2980     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2981             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2982         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2983                      ("available for Rx ports only"));
2984 
2985     p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
2986 
2987     return E_OK;
2988 }
2989 
2990 t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
2991                                     t_FmBufPoolDepletion *p_BufPoolDepletion)
2992 {
2993     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2994 
2995     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2996     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2997     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2998             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2999         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3000                      ("available for Rx ports only"));
3001 
3002     p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
3003     memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
3004            sizeof(t_FmBufPoolDepletion));
3005 
3006     return E_OK;
3007 }
3008 
3009 t_Error FM_PORT_ConfigObservedPoolDepletion(
3010         t_Handle h_FmPort,
3011         t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
3012 {
3013     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3014 
3015     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3016     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3017     if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3018         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3019                      ("available for OP ports only"));
3020 
3021     p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
3022     memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
3023            &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
3024            sizeof(t_FmBufPoolDepletion));
3025     memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
3026            &p_FmPortObservedBufPoolDepletion->poolsParams,
3027            sizeof(t_FmExtPools));
3028 
3029     return E_OK;
3030 }
3031 
3032 t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
3033 {
3034     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3035 
3036     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3037     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3038 
3039     if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3040         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3041                      ("available for OP ports only"));
3042 
3043     memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
3044            sizeof(t_FmExtPools));
3045 
3046     return E_OK;
3047 }
3048 
3049 t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
3050 {
3051     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3052 
3053     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3054     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3055     if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3056             && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3057         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3058                      ("available for Tx ports only"));
3059 
3060     p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
3061 
3062     return E_OK;
3063 }
3064 
3065 t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
3066 {
3067     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3068 
3069     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3070     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3071     p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
3072 
3073     return E_OK;
3074 }
3075 
3076 t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
3077 {
3078     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3079 
3080     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3081     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3082 
3083     if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3084             || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3085         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3086                      ("Not available for Tx ports"));
3087 
3088     p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
3089 
3090     return E_OK;
3091 }
3092 
3093 t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
3094 {
3095     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3096 
3097     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3098     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3099     if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3100             || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3101         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3102                      ("Not available for Tx ports"));
3103 
3104     p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
3105 
3106     return E_OK;
3107 }
3108 
3109 t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
3110                                       fmPortFrameErrSelect_t errs)
3111 {
3112     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3113 
3114     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3115     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3116     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3117             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
3118             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
3119         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3120                      ("available for Rx and offline parsing ports only"));
3121 
3122     p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
3123 
3124     return E_OK;
3125 }
3126 
3127 t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
3128 {
3129     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3130 
3131     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3132     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3133 
3134     p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
3135             (enum fman_port_dma_swap)swapData;
3136 
3137     return E_OK;
3138 }
3139 
3140 t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
3141                                      e_FmDmaCacheOption intContextCacheAttr)
3142 {
3143     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3144 
3145     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3146     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3147 
3148     p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
3149             (bool)(intContextCacheAttr == e_FM_DMA_STASH);
3150 
3151     return E_OK;
3152 }
3153 
3154 t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
3155                                  e_FmDmaCacheOption headerCacheAttr)
3156 {
3157     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3158 
3159     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3160     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3161 
3162     p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
3163             (bool)(headerCacheAttr == e_FM_DMA_STASH);
3164 
3165     return E_OK;
3166 }
3167 
3168 t_Error FM_PORT_ConfigDmaScatterGatherAttr(
3169         t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
3170 {
3171     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3172 
3173     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3174     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3175 
3176     p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
3177             (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
3178 
3179     return E_OK;
3180 }
3181 
3182 t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
3183 {
3184     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3185 
3186     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3187     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3188 
3189     if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3190             || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3191         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3192                      ("Not available for Tx ports"));
3193 
3194     p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
3195 
3196     return E_OK;
3197 }
3198 
3199 #if (DPAA_VERSION >= 11)
3200 t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
3201 {
3202     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3203 
3204     UNUSED(noScatherGather);
3205     UNUSED(p_FmPort);
3206 
3207     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3208     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3209 
3210     p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
3211 
3212     return E_OK;
3213 }
3214 #endif /* (DPAA_VERSION >= 11) */
3215 
3216 t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
3217                                              bool forwardReuse)
3218 {
3219     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3220 
3221     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3222     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3223 
3224     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3225             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3226         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3227                      ("available for Rx ports only"));
3228 
3229     p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
3230 
3231     return E_OK;
3232 }
3233 
3234 t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
3235 {
3236     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3237 
3238     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3239     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3240 
3241     p_FmPort->maxFrameLength = length;
3242 
3243     return E_OK;
3244 }
3245 
3246 #ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
3247 t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
3248 {
3249     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3250 
3251     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3252     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3253 
3254     p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
3255 
3256     return E_OK;
3257 }
3258 #endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
3259 
3260 /****************************************************/
3261 /*       Hidden-DEBUG Only API                      */
3262 /****************************************************/
3263 
3264 t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
3265                                          uint32_t minFillLevel)
3266 {
3267     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3268 
3269     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3270     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3271     if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3272             && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3273         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3274                      ("available for Tx ports only"));
3275 
3276     p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
3277 
3278     return E_OK;
3279 }
3280 
3281 t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
3282                                            uint8_t deqPipelineDepth)
3283 {
3284     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3285 
3286     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3287     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3288 
3289     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
3290             || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
3291         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3292                      ("Not available for Rx ports"));
3293 
3294     if (p_FmPort->imEn)
3295         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3296                      ("Not available for IM ports!"));
3297 
3298     p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
3299             deqPipelineDepth;
3300 
3301     return E_OK;
3302 }
3303 
3304 t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
3305                                          uint32_t fifoLowComfLevel)
3306 {
3307     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3308 
3309     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3310     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3311     if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3312             && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3313         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3314                      ("available for Tx ports only"));
3315 
3316     p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
3317             fifoLowComfLevel;
3318 
3319     return E_OK;
3320 }
3321 
3322 t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
3323 {
3324     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3325 
3326     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3327     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3328     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3329             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3330         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3331                      ("available for Rx ports only"));
3332 
3333     p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
3334 
3335     return E_OK;
3336 }
3337 
3338 t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
3339                                               uint32_t priElevationLevel)
3340 {
3341     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3342 
3343     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3344     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3345     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3346             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3347         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3348                      ("available for Rx ports only"));
3349 
3350     p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
3351 
3352     return E_OK;
3353 }
3354 /****************************************************/
3355 /*       API Run-time Control unit functions        */
3356 /****************************************************/
3357 
3358 t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
3359                                  t_FmPortRsrc *p_NumOfOpenDmas)
3360 {
3361     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3362     t_Error err;
3363 
3364     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3365     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3366 
3367     if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
3368         RETURN_ERROR( MAJOR, E_INVALID_VALUE,
3369                      ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
3370     if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
3371         RETURN_ERROR(
3372                 MAJOR,
3373                 E_INVALID_VALUE,
3374                 ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
3375     err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3376                              (uint8_t*)&p_NumOfOpenDmas->num,
3377                              (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
3378     if (err)
3379         RETURN_ERROR(MAJOR, err, NO_MSG);
3380 
3381     memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
3382 
3383     return E_OK;
3384 }
3385 
3386 t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
3387 {
3388     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3389     t_Error err;
3390 
3391     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3392     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3393 
3394     /* only driver uses host command port, so ASSERT rather than  RETURN_ERROR */
3395     ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
3396 
3397     if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
3398         RETURN_ERROR(
3399                 MAJOR, E_INVALID_VALUE,
3400                 ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
3401     if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
3402         RETURN_ERROR(
3403                 MAJOR,
3404                 E_INVALID_VALUE,
3405                 ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
3406 
3407     err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3408                           (uint8_t*)&p_NumOfTasks->num,
3409                           (uint8_t*)&p_NumOfTasks->extra, FALSE);
3410     if (err)
3411         RETURN_ERROR(MAJOR, err, NO_MSG);
3412 
3413     /* update driver's struct */
3414     memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
3415     return E_OK;
3416 }
3417 
3418 t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
3419 {
3420     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3421     t_Error err;
3422 
3423     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3424     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3425 
3426     if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
3427         RETURN_ERROR(
3428                 MAJOR,
3429                 E_INVALID_VALUE,
3430                 ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
3431     if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
3432         RETURN_ERROR(
3433                 MAJOR, E_INVALID_VALUE,
3434                 ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
3435     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
3436             || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
3437     {
3438         /* extra FIFO size (allowed only to Rx ports) */
3439         if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
3440             RETURN_ERROR(
3441                     MAJOR,
3442                     E_INVALID_VALUE,
3443                     ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
3444     }
3445     else
3446         if (p_SizeOfFifo->extra)
3447             RETURN_ERROR(MAJOR, E_INVALID_VALUE,
3448                          (" No SizeOfFifo-extra for non Rx ports"));
3449 
3450     memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
3451 
3452     /* we do not change user's parameter */
3453     err = VerifySizeOfFifo(p_FmPort);
3454     if (err)
3455         RETURN_ERROR(MAJOR, err, NO_MSG);
3456 
3457     err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3458                           &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
3459     if (err)
3460         RETURN_ERROR(MAJOR, err, NO_MSG);
3461 
3462     return E_OK;
3463 }
3464 
3465 uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
3466 {
3467     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3468 
3469     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
3470     SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3471                               0);
3472 
3473     return p_FmPort->bufferOffsets.dataOffset;
3474 }
3475 
3476 uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
3477 {
3478     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3479 
3480     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3481     SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3482                               NULL);
3483 
3484     if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
3485         return NULL;
3486 
3487     return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
3488 }
3489 
3490 t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
3491 {
3492     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3493 
3494     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3495     SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3496                               NULL);
3497 
3498     if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
3499         return NULL;
3500 
3501     return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
3502 }
3503 
3504 uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
3505 {
3506     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3507 
3508     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3509     SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3510                               NULL);
3511 
3512     if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
3513         return NULL;
3514 
3515     return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
3516 }
3517 
3518 uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
3519 {
3520     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3521 
3522     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3523     SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3524                               NULL);
3525 
3526     if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
3527         return NULL;
3528 
3529     return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
3530 }
3531 
3532 t_Error FM_PORT_Disable(t_Handle h_FmPort)
3533 {
3534     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3535     int err;
3536 
3537     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3538     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3539 
3540     if (p_FmPort->imEn)
3541         FmPortImDisable(p_FmPort);
3542 
3543     err = fman_port_disable(&p_FmPort->port);
3544     if (err == -EBUSY)
3545     {
3546         DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
3547                p_FmPort->name));
3548     }
3549     else
3550         if (err != 0)
3551         {
3552             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
3553         }
3554 
3555     p_FmPort->enabled = FALSE;
3556 
3557     return E_OK;
3558 }
3559 
3560 t_Error FM_PORT_Enable(t_Handle h_FmPort)
3561 {
3562     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3563     int err;
3564 
3565     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3566     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3567 
3568     /* Used by FM_PORT_Free routine as indication
3569      if to disable port. Thus set it to TRUE prior
3570      to enabling itself. This way if part of enable
3571      process fails there will be still things
3572      to disable during Free. For example, if BMI
3573      enable succeeded but QMI failed, still  BMI
3574      needs to be disabled by Free. */
3575     p_FmPort->enabled = TRUE;
3576 
3577     if (p_FmPort->imEn)
3578         FmPortImEnable(p_FmPort);
3579 
3580     err = fman_port_enable(&p_FmPort->port);
3581     if (err != 0)
3582         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
3583 
3584     return E_OK;
3585 }
3586 
3587 t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
3588 {
3589     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3590     uint8_t factor, countUnitBit;
3591     uint16_t baseGran;
3592     struct fman_port_rate_limiter params;
3593     int err;
3594 
3595     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3596     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3597 
3598     switch (p_FmPort->portType)
3599     {
3600         case (e_FM_PORT_TYPE_TX_10G):
3601         case (e_FM_PORT_TYPE_TX):
3602             baseGran = BMI_RATE_LIMIT_GRAN_TX;
3603             break;
3604         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3605             baseGran = BMI_RATE_LIMIT_GRAN_OP;
3606             break;
3607         default:
3608             RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3609                          ("available for Tx and Offline parsing ports only"));
3610     }
3611 
3612     countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
3613     /* normally, we use 1 usec as the reference count */
3614     factor = 1;
3615     /* if ratelimit is too small for a 1usec factor, multiply the factor */
3616     while (p_RateLimit->rateLimit < baseGran / factor)
3617     {
3618         if (countUnitBit == 31)
3619             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
3620 
3621         countUnitBit++;
3622         factor <<= 1;
3623     }
3624     /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
3625     if (p_RateLimit->rateLimit
3626             > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
3627         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
3628 
3629     if (!p_RateLimit->maxBurstSize
3630             || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
3631         RETURN_ERROR(
3632                 MAJOR,
3633                 E_INVALID_VALUE,
3634                 ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
3635 
3636     params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
3637     params.high_burst_size_gran = FALSE;
3638     params.burst_size = p_RateLimit->maxBurstSize;
3639     params.rate = p_RateLimit->rateLimit;
3640     params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
3641 
3642     if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3643     {
3644 #ifndef FM_NO_ADVANCED_RATE_LIMITER
3645 
3646         if ((p_FmPort->fmRevInfo.majorRev == 4)
3647                 || (p_FmPort->fmRevInfo.majorRev >= 6))
3648         {
3649             params.high_burst_size_gran = TRUE;
3650         }
3651         else
3652 #endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
3653         {
3654             if (p_RateLimit->rateLimitDivider
3655                     != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
3656                 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
3657                              ("FM_PORT_ConfigDualRateLimitScaleDown"));
3658 
3659             if (p_RateLimit->maxBurstSize % 1000)
3660             {
3661                 p_RateLimit->maxBurstSize =
3662                         (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
3663                 DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
3664             }
3665             else
3666                 p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
3667                         / 1000);
3668         }
3669         params.rate_factor =
3670                 (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
3671         params.burst_size = p_RateLimit->maxBurstSize;
3672     }
3673 
3674     err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
3675     if (err != 0)
3676         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
3677 
3678     return E_OK;
3679 }
3680 
3681 t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
3682 {
3683     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3684     int err;
3685 
3686     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3687     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3688 
3689     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
3690             || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
3691             || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
3692         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3693                      ("available for Tx and Offline parsing ports only"));
3694 
3695     err = fman_port_delete_rate_limiter(&p_FmPort->port);
3696     if (err != 0)
3697         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
3698     return E_OK;
3699 }
3700 
3701 t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
3702                                                 uint8_t wq)
3703 {
3704     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3705     uint32_t tmpReg;
3706     uint32_t wqTmpReg;
3707 
3708     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3709     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3710 
3711     if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
3712             && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
3713         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3714                      ("PFC mapping is available for Tx ports only"));
3715 
3716     if (prio > 7)
3717         RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
3718                      ("PFC priority (%d) is out of range (0-7)", prio));
3719     if (wq > 7)
3720         RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
3721                      ("WQ (%d) is out of range (0-7)", wq));
3722 
3723     tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
3724     tmpReg &= ~(0xf << ((7 - prio) * 4));
3725     wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
3726     tmpReg |= wqTmpReg;
3727 
3728     WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
3729                  tmpReg);
3730 
3731     return E_OK;
3732 }
3733 
3734 t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
3735 {
3736     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3737 
3738     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3739     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3740 
3741     fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
3742 
3743     return E_OK;
3744 }
3745 
3746 t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
3747 {
3748     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3749     int err;
3750 
3751     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3752     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3753 
3754     err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
3755     if (err != 0)
3756         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
3757     return E_OK;
3758 }
3759 
3760 t_Error FM_PORT_SetPerformanceCountersParams(
3761         t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
3762 {
3763     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3764     struct fman_port_perf_cnt_params params;
3765     int err;
3766 
3767     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3768 
3769     /* check parameters */
3770     if (!p_FmPortPerformanceCnt->taskCompVal
3771             || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
3772         RETURN_ERROR(
3773                 MAJOR,
3774                 E_INVALID_VALUE,
3775                 ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
3776     if (!p_FmPortPerformanceCnt->dmaCompVal
3777             || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
3778         RETURN_ERROR(
3779                 MAJOR,
3780                 E_INVALID_VALUE,
3781                 ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
3782     if (!p_FmPortPerformanceCnt->fifoCompVal
3783             || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
3784         RETURN_ERROR(
3785                 MAJOR,
3786                 E_INVALID_VALUE,
3787                 ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
3788     if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
3789         RETURN_ERROR(
3790                 MAJOR,
3791                 E_INVALID_VALUE,
3792                 ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
3793 
3794     switch (p_FmPort->portType)
3795     {
3796         case (e_FM_PORT_TYPE_RX_10G):
3797         case (e_FM_PORT_TYPE_RX):
3798             if (!p_FmPortPerformanceCnt->queueCompVal
3799                     || (p_FmPortPerformanceCnt->queueCompVal
3800                             > MAX_PERFORMANCE_RX_QUEUE_COMP))
3801                 RETURN_ERROR(
3802                         MAJOR,
3803                         E_INVALID_VALUE,
3804                         ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
3805             break;
3806         case (e_FM_PORT_TYPE_TX_10G):
3807         case (e_FM_PORT_TYPE_TX):
3808             if (!p_FmPortPerformanceCnt->queueCompVal
3809                     || (p_FmPortPerformanceCnt->queueCompVal
3810                             > MAX_PERFORMANCE_TX_QUEUE_COMP))
3811                 RETURN_ERROR(
3812                         MAJOR,
3813                         E_INVALID_VALUE,
3814                         ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
3815             break;
3816         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3817         case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
3818             if (p_FmPortPerformanceCnt->queueCompVal)
3819                 RETURN_ERROR(
3820                         MAJOR,
3821                         E_INVALID_VALUE,
3822                         ("performanceCnt.queueCompVal is not relevant for H/O ports."));
3823             break;
3824         default:
3825             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
3826     }
3827 
3828     params.task_val = p_FmPortPerformanceCnt->taskCompVal;
3829     params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
3830     params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
3831     params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
3832 
3833     err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
3834     if (err != 0)
3835         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
3836 
3837     return E_OK;
3838 }
3839 
3840 t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
3841 {
3842     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3843     t_FmPortPerformanceCnt currParams, savedParams;
3844     t_Error err;
3845     bool underTest, failed = FALSE;
3846 
3847     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3848 
3849     XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
3850              p_FmPort->portType, p_FmPort->portId);
3851 
3852     currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
3853     if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3854             || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
3855         currParams.queueCompVal = 0;
3856     else
3857         currParams.queueCompVal = 1;
3858     currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
3859     currParams.fifoCompVal = p_FmPort->fifoBufs.num;
3860 
3861     FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3862     ClearPerfCnts(p_FmPort);
3863     if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
3864             != E_OK)
3865         RETURN_ERROR(MAJOR, err, NO_MSG);
3866     FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
3867     XX_UDelay(1000000);
3868     FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3869     if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
3870     {
3871         XX_Print(
3872                 "Max num of defined port tasks (%d) utilized - Please enlarge\n",
3873                 p_FmPort->tasks.num);
3874         failed = TRUE;
3875     }
3876     if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
3877     {
3878         XX_Print(
3879                 "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
3880                 p_FmPort->openDmas.num);
3881         failed = TRUE;
3882     }
3883     if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
3884     {
3885         XX_Print(
3886                 "Max size of defined port fifo (%d) utilized - Please enlarge\n",
3887                 p_FmPort->fifoBufs.num);
3888         failed = TRUE;
3889     }
3890     if (failed)
3891         RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
3892 
3893     memset(&savedParams, 0, sizeof(savedParams));
3894     while (TRUE)
3895     {
3896         underTest = FALSE;
3897         if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
3898         {
3899             currParams.taskCompVal--;
3900             underTest = TRUE;
3901         }
3902         if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
3903         {
3904             currParams.dmaCompVal--;
3905             underTest = TRUE;
3906         }
3907         if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
3908                 && !savedParams.fifoCompVal)
3909         {
3910             currParams.fifoCompVal -= BMI_FIFO_UNITS;
3911             underTest = TRUE;
3912         }
3913         if (!underTest)
3914             break;
3915 
3916         ClearPerfCnts(p_FmPort);
3917         if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
3918                 != E_OK)
3919             RETURN_ERROR(MAJOR, err, NO_MSG);
3920         FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
3921         XX_UDelay(1000000);
3922         FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3923 
3924         if (!savedParams.taskCompVal
3925                 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
3926             savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
3927         if (!savedParams.dmaCompVal
3928                 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
3929             savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
3930         if (!savedParams.fifoCompVal
3931                 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
3932             savedParams.fifoCompVal = currParams.fifoCompVal
3933                     + (2 * BMI_FIFO_UNITS);
3934     }
3935 
3936     XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
3937              savedParams.taskCompVal, savedParams.dmaCompVal,
3938              savedParams.fifoCompVal);
3939     return E_OK;
3940 }
3941 
3942 t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
3943 {
3944     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3945     int err;
3946 
3947     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3948     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3949 
3950     err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
3951     if (err != 0)
3952         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
3953     return E_OK;
3954 }
3955 
3956 t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
3957 {
3958     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3959     volatile uint32_t *p_ErrDiscard = NULL;
3960     int err;
3961 
3962     UNUSED(p_ErrDiscard);
3963     err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
3964     if (err != 0)
3965         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
3966 
3967 #ifdef FM_ERROR_VSP_NO_MATCH_SW006
3968     if (p_FmPort->fmRevInfo.majorRev >= 6)
3969     {
3970         t_FmPcdCtrlParamsPage *p_ParamsPage;
3971 
3972         FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
3973                          (void**)&p_ParamsPage);
3974         ASSERT_COND(p_ParamsPage);
3975         switch (p_FmPort->portType)
3976         {
3977             case (e_FM_PORT_TYPE_RX_10G):
3978             case (e_FM_PORT_TYPE_RX):
3979                 p_ErrDiscard =
3980                         &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
3981                 break;
3982             case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3983                 p_ErrDiscard =
3984                         &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
3985                 break;
3986             default:
3987                 RETURN_ERROR(
3988                         MAJOR, E_INVALID_OPERATION,
3989                         ("available for Rx and offline parsing ports only"));
3990         }
3991         WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
3992                      GET_UINT32(*p_ErrDiscard) | errs);
3993     }
3994 #endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
3995 
3996     return E_OK;
3997 }
3998 
3999 t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
4000                                    bool enable)
4001 {
4002     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4003     int err;
4004 
4005     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4006     SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
4007     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4008 
4009     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4010             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
4011         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4012                      ("available for Rx ports only"));
4013 
4014     err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
4015     if (err != 0)
4016         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
4017     return E_OK;
4018 }
4019 
4020 t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
4021 {
4022     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4023 
4024     if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4025             || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
4026         p_BmiStats->cntCycle =
4027             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4028             /* fmbm_rccn */
4029         p_BmiStats->cntTaskUtil =
4030             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4031             /* fmbm_rtuc */
4032         p_BmiStats->cntQueueUtil =
4033             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
4034             /* fmbm_rrquc */
4035         p_BmiStats->cntDmaUtil =
4036             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4037             /* fmbm_rduc */
4038         p_BmiStats->cntFifoUtil =
4039             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4040             /* fmbm_rfuc */
4041         p_BmiStats->cntRxPauseActivation =
4042             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
4043             /* fmbm_rpac */
4044         p_BmiStats->cntFrame =
4045             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4046             /* fmbm_rfrc */
4047         p_BmiStats->cntDiscardFrame =
4048             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4049             /* fmbm_rfdc */
4050         p_BmiStats->cntDeallocBuf =
4051             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4052             /* fmbm_rbdc */
4053         p_BmiStats->cntRxBadFrame =
4054             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
4055             /* fmbm_rfbc */
4056         p_BmiStats->cntRxLargeFrame =
4057             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
4058             /* fmbm_rlfc */
4059         p_BmiStats->cntRxFilterFrame =
4060             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
4061             /* fmbm_rffc */
4062         p_BmiStats->cntRxListDmaErr =
4063             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
4064             /* fmbm_rfldec */
4065         p_BmiStats->cntRxOutOfBuffersDiscard =
4066             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
4067             /* fmbm_rodc */
4068         p_BmiStats->cntWredDiscard = 0;
4069         p_BmiStats->cntLengthErr = 0;
4070         p_BmiStats->cntUnsupportedFormat = 0;
4071     }
4072     else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
4073                 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
4074         p_BmiStats->cntCycle =
4075             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4076             /* fmbm_tccn */
4077         p_BmiStats->cntTaskUtil =
4078             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4079             /* fmbm_ttuc */
4080         p_BmiStats->cntQueueUtil =
4081             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
4082             /* fmbm_ttcquc */
4083         p_BmiStats->cntDmaUtil =
4084             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4085             /* fmbm_tduc */
4086         p_BmiStats->cntFifoUtil =
4087             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4088             /* fmbm_tfuc */
4089         p_BmiStats->cntRxPauseActivation = 0;
4090         p_BmiStats->cntFrame =
4091             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4092             /* fmbm_tfrc */
4093         p_BmiStats->cntDiscardFrame =
4094             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4095             /* fmbm_tfdc */
4096         p_BmiStats->cntDeallocBuf =
4097             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4098             /* fmbm_tbdc */
4099         p_BmiStats->cntRxBadFrame = 0;
4100         p_BmiStats->cntRxLargeFrame = 0;
4101         p_BmiStats->cntRxFilterFrame = 0;
4102         p_BmiStats->cntRxListDmaErr = 0;
4103         p_BmiStats->cntRxOutOfBuffersDiscard = 0;
4104         p_BmiStats->cntWredDiscard = 0;
4105         p_BmiStats->cntLengthErr =
4106             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
4107             /* fmbm_tfledc */
4108         p_BmiStats->cntUnsupportedFormat =
4109             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
4110             /* fmbm_tfufdc */
4111     }
4112     else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
4113         p_BmiStats->cntCycle =
4114             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4115             /* fmbm_occn */
4116         p_BmiStats->cntTaskUtil =
4117             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4118             /* fmbm_otuc */
4119         p_BmiStats->cntQueueUtil = 0;
4120         p_BmiStats->cntDmaUtil =
4121             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4122             /* fmbm_oduc */
4123         p_BmiStats->cntFifoUtil =
4124             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4125             /* fmbm_ofuc*/
4126         p_BmiStats->cntRxPauseActivation = 0;
4127         p_BmiStats->cntFrame =
4128             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4129             /* fmbm_ofrc */
4130         p_BmiStats->cntDiscardFrame =
4131             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4132             /* fmbm_ofdc */
4133         p_BmiStats->cntDeallocBuf =
4134             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4135             /* fmbm_obdc*/
4136         p_BmiStats->cntRxBadFrame = 0;
4137         p_BmiStats->cntRxLargeFrame = 0;
4138         p_BmiStats->cntRxFilterFrame =
4139             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
4140             /* fmbm_offc */
4141         p_BmiStats->cntRxListDmaErr =
4142             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
4143             /* fmbm_ofldec */
4144         p_BmiStats->cntRxOutOfBuffersDiscard =
4145             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
4146             /* fmbm_rodc */
4147         p_BmiStats->cntWredDiscard =
4148             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
4149             /* fmbm_ofwdc */
4150         p_BmiStats->cntLengthErr =
4151             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
4152             /* fmbm_ofledc */
4153         p_BmiStats->cntUnsupportedFormat =
4154             FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
4155             /* fmbm_ofufdc */
4156     }
4157     return E_OK;
4158 }
4159 
4160 uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
4161 {
4162     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4163     bool bmiCounter = FALSE;
4164     enum fman_port_stats_counters statsType;
4165     enum fman_port_perf_counters perfType;
4166     enum fman_port_qmi_counters queueType;
4167     bool isStats;
4168     t_Error errCode;
4169 
4170     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
4171     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4172 
4173     switch (counter)
4174     {
4175         case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4176         case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4177         case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4178             /* check that counter is available for the port type */
4179             if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4180                     || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4181             {
4182                 REPORT_ERROR(MINOR, E_INVALID_STATE,
4183                         ("Requested counter is not available for Rx ports"));
4184                 return 0;
4185             }
4186             bmiCounter = FALSE;
4187             break;
4188         case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4189             bmiCounter = FALSE;
4190             break;
4191         default: /* BMI counters (or error - will be checked in BMI routine )*/
4192             bmiCounter = TRUE;
4193             break;
4194     }
4195 
4196     if (bmiCounter)
4197     {
4198         errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
4199                                                 &perfType, &isStats);
4200         if (errCode != E_OK)
4201         {
4202             REPORT_ERROR(MINOR, errCode, NO_MSG);
4203             return 0;
4204         }
4205         if (isStats)
4206             return fman_port_get_stats_counter(&p_FmPort->port, statsType);
4207         else
4208             return fman_port_get_perf_counter(&p_FmPort->port, perfType);
4209     }
4210     else /* QMI counter */
4211     {
4212         /* check that counters are enabled */
4213         if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
4214                 & QMI_PORT_CFG_EN_COUNTERS))
4215 
4216         {
4217             REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
4218             return 0;
4219         }
4220 
4221         /* Set counter */
4222         switch (counter)
4223         {
4224             case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4225                 queueType = E_FMAN_PORT_ENQ_TOTAL;
4226                 break;
4227             case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4228                 queueType = E_FMAN_PORT_DEQ_TOTAL;
4229                 break;
4230             case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4231                 queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
4232                 break;
4233             case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4234                 queueType = E_FMAN_PORT_DEQ_CONFIRM;
4235                 break;
4236             default:
4237                 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
4238                 return 0;
4239         }
4240 
4241         return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
4242     }
4243 
4244     return 0;
4245 }
4246 
4247 t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
4248                               uint32_t value)
4249 {
4250     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4251     bool bmiCounter = FALSE;
4252     enum fman_port_stats_counters statsType;
4253     enum fman_port_perf_counters perfType;
4254     enum fman_port_qmi_counters queueType;
4255     bool isStats;
4256     t_Error errCode;
4257 
4258     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4259     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4260 
4261     switch (counter)
4262     {
4263         case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4264         case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4265         case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4266             /* check that counter is available for the port type */
4267             if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4268                     || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4269                 RETURN_ERROR(
4270                         MINOR, E_INVALID_STATE,
4271                         ("Requested counter is not available for Rx ports"));
4272         case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4273             bmiCounter = FALSE;
4274             break;
4275         default: /* BMI counters (or error - will be checked in BMI routine )*/
4276             bmiCounter = TRUE;
4277             break;
4278     }
4279 
4280     if (bmiCounter)
4281     {
4282         errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
4283                                                 &perfType, &isStats);
4284         if (errCode != E_OK)
4285         {
4286             RETURN_ERROR(MINOR, errCode, NO_MSG);
4287         }
4288         if (isStats)
4289             fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
4290         else
4291             fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
4292     }
4293     else /* QMI counter */
4294     {
4295         /* check that counters are enabled */
4296         if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
4297                 & QMI_PORT_CFG_EN_COUNTERS))
4298         {
4299             RETURN_ERROR(MINOR, E_INVALID_STATE,
4300                          ("Requested counter was not enabled"));
4301         }
4302 
4303         /* Set counter */
4304         switch (counter)
4305         {
4306             case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4307                 queueType = E_FMAN_PORT_ENQ_TOTAL;
4308                 break;
4309             case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4310                 queueType = E_FMAN_PORT_DEQ_TOTAL;
4311                 break;
4312             case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4313                 queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
4314                 break;
4315             case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4316                 queueType = E_FMAN_PORT_DEQ_CONFIRM;
4317                 break;
4318             default:
4319                 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4320                              ("Requested counter is not available"));
4321         }
4322 
4323         fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
4324     }
4325 
4326     return E_OK;
4327 }
4328 
4329 uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
4330 {
4331     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4332 
4333     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
4334     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4335 
4336     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
4337             && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4338     {
4339         REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
4340         return 0;
4341     }
4342     return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
4343 }
4344 
4345 t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
4346                                       uint32_t value)
4347 {
4348     t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
4349 
4350     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4351     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4352 
4353     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
4354             && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4355         RETURN_ERROR( MINOR, E_INVALID_STATE,
4356                      ("Requested counter is not available for non-Rx ports"));
4357 
4358     fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
4359     return E_OK;
4360 }
4361 bool FM_PORT_IsStalled(t_Handle h_FmPort)
4362 {
4363     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4364     t_Error err;
4365     bool isStalled;
4366 
4367     SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
4368     SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
4369                               FALSE);
4370 
4371     err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
4372     if (err != E_OK)
4373     {
4374         REPORT_ERROR(MAJOR, err, NO_MSG);
4375         return TRUE;
4376     }
4377     return isStalled;
4378 }
4379 
4380 t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
4381 {
4382     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4383 
4384     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4385     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4386 
4387     return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
4388 }
4389 
4390 t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
4391 {
4392     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4393     int err;
4394 
4395     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4396     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4397 
4398     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4399             && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
4400         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4401                      ("available for Rx ports only"));
4402 
4403     if (l4Checksum)
4404         err = fman_port_modify_rx_fd_bits(
4405                 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
4406                 TRUE);
4407     else
4408         err = fman_port_modify_rx_fd_bits(
4409                 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
4410                 FALSE);
4411     if (err != 0)
4412         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
4413 
4414     return E_OK;
4415 }
4416 
4417 /*****************************************************************************/
4418 /*       API Run-time PCD Control unit functions                             */
4419 /*****************************************************************************/
4420 
4421 #if (DPAA_VERSION >= 11)
4422 t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
4423 {
4424     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4425     t_Error err = E_OK;
4426     volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
4427     uint32_t tmpReg = 0, tmp = 0;
4428     uint16_t hwStoragePrflId;
4429 
4430     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4431     SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
4432     /*for numOfProfiles = 0 don't call this function*/
4433     SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
4434     /*dfltRelativeId should be in the range of numOfProfiles*/
4435     SANITY_CHECK_RETURN_ERROR(
4436             p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
4437             E_INVALID_VALUE);
4438     /*p_FmPort should be from Rx type or OP*/
4439     SANITY_CHECK_RETURN_ERROR(
4440             ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
4441             E_INVALID_VALUE);
4442     /*port should be disabled*/
4443     SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
4444     /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
4445     SANITY_CHECK_RETURN_ERROR(
4446             ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
4447             E_INVALID_VALUE);
4448     /*should be called before SetPCD - this port should be without PCD*/
4449     SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
4450 
4451     /*alloc window of VSPs for this port*/
4452     err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
4453                             p_FmPort->portId, p_VSPParams->numOfProfiles);
4454     if (err != E_OK)
4455         RETURN_ERROR(MAJOR, err, NO_MSG);
4456 
4457     /*get absolute VSP ID for dfltRelative*/
4458     err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
4459                                     p_FmPort->portId,
4460                                     p_VSPParams->dfltRelativeId,
4461                                     &hwStoragePrflId);
4462     if (err != E_OK)
4463         RETURN_ERROR(MAJOR, err, NO_MSG);
4464 
4465     /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
4466     switch (p_FmPort->portType)
4467     {
4468         case (e_FM_PORT_TYPE_RX_10G):
4469         case (e_FM_PORT_TYPE_RX):
4470             p_BmiStorageProfileId =
4471                     &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
4472             p_BmiVspe =
4473                     &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
4474 
4475             tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
4476             tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
4477             WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
4478 
4479             tmpReg = GET_UINT32(*p_BmiVspe);
4480             WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
4481 
4482             p_BmiStorageProfileId =
4483                     &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
4484             p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
4485             hwStoragePrflId = p_VSPParams->dfltRelativeId;
4486             break;
4487 
4488         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4489             tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
4490             WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
4491                          tmpReg);
4492 
4493             p_BmiStorageProfileId =
4494                     &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
4495             p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
4496             tmp |= BMI_EBD_EN;
4497             break;
4498 
4499         default:
4500             RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4501                          ("available for Rx and offline parsing ports only"));
4502     }
4503 
4504     p_FmPort->vspe = TRUE;
4505     p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
4506 
4507     tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
4508     tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
4509     WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
4510 
4511     tmpReg = GET_UINT32(*p_BmiVspe);
4512     WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
4513     return E_OK;
4514 }
4515 #endif /* (DPAA_VERSION >= 11) */
4516 
4517 t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
4518 {
4519     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4520     t_Error err = E_OK;
4521 
4522     p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
4523     ASSERT_COND(p_FmPort->h_FmPcd);
4524 
4525     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4526     {
4527         DBG(TRACE, ("FM Port Try Lock - BUSY"));
4528         return ERROR_CODE(E_BUSY);
4529     }
4530 
4531     if (numOfProfiles)
4532     {
4533         err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
4534                                      p_FmPort->hardwarePortId, numOfProfiles);
4535         if (err)
4536             RETURN_ERROR(MAJOR, err, NO_MSG);
4537     }
4538     /* set the port handle within the PCD policer, even if no profiles defined */
4539     FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
4540 
4541     RELEASE_LOCK(p_FmPort->lock);
4542 
4543     return E_OK;
4544 }
4545 
4546 t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
4547 {
4548     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4549     t_Error err = E_OK;
4550 
4551     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4552     {
4553         DBG(TRACE, ("FM Port Try Lock - BUSY"));
4554         return ERROR_CODE(E_BUSY);
4555     }
4556 
4557     err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
4558 
4559     RELEASE_LOCK(p_FmPort->lock);
4560 
4561     if (err)
4562         RETURN_ERROR(MAJOR, err, NO_MSG);
4563 
4564     return E_OK;
4565 }
4566 
4567 t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
4568                                          t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
4569 {
4570     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4571     volatile uint32_t *p_BmiHpnia = NULL;
4572     uint32_t tmpReg;
4573     uint8_t relativeSchemeId;
4574     uint8_t physicalSchemeId;
4575 
4576     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4577     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4578     SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
4579                               E_INVALID_STATE);
4580 
4581     tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
4582     switch (p_FmPort->portType)
4583     {
4584         case (e_FM_PORT_TYPE_RX_10G):
4585         case (e_FM_PORT_TYPE_RX):
4586             p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
4587             break;
4588         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4589             p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
4590             break;
4591         default:
4592             RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4593                          ("available for Rx and offline parsing ports only"));
4594     }
4595 
4596     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4597     {
4598         DBG(TRACE, ("FM Port Try Lock - BUSY"));
4599         return ERROR_CODE(E_BUSY);
4600     }
4601 
4602     /* if we want to change to direct scheme, we need to check that this scheme is valid */
4603     if (p_FmPcdKgScheme->direct)
4604     {
4605         physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
4606         /* check that this scheme is bound to this port */
4607         if (!(p_FmPort->schemesPerPortVector
4608                 & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
4609         {
4610             RELEASE_LOCK(p_FmPort->lock);
4611             RETURN_ERROR(
4612                     MAJOR, E_INVALID_STATE,
4613                     ("called with a scheme that is not bound to this port"));
4614         }
4615 
4616         relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
4617                                                       physicalSchemeId);
4618         if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
4619         {
4620             RELEASE_LOCK(p_FmPort->lock);
4621             RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
4622                          ("called with invalid Scheme "));
4623         }
4624 
4625         if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
4626         {
4627             RELEASE_LOCK(p_FmPort->lock);
4628             RETURN_ERROR(MAJOR, E_INVALID_STATE,
4629                          ("called with uninitialized Scheme "));
4630         }
4631 
4632         WRITE_UINT32(
4633                 *p_BmiHpnia,
4634                 NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
4635     }
4636     else
4637         /* change to indirect scheme */
4638         WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
4639     RELEASE_LOCK(p_FmPort->lock);
4640 
4641     return E_OK;
4642 }
4643 
4644 t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
4645                                             t_Handle h_Profile)
4646 {
4647     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4648     volatile uint32_t *p_BmiNia;
4649     volatile uint32_t *p_BmiHpnia;
4650     uint32_t tmpReg;
4651     uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
4652 
4653     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4654     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4655     SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
4656                               E_INVALID_STATE);
4657 
4658     /* check relevance of this routine  - only when policer is used
4659      directly after BMI or Parser */
4660     if ((p_FmPort->pcdEngines & FM_PCD_KG)
4661             || (p_FmPort->pcdEngines & FM_PCD_CC))
4662         RETURN_ERROR(
4663                 MAJOR,
4664                 E_INVALID_STATE,
4665                 ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
4666 
4667     switch (p_FmPort->portType)
4668     {
4669         case (e_FM_PORT_TYPE_RX_10G):
4670         case (e_FM_PORT_TYPE_RX):
4671             p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
4672             p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
4673             tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
4674             break;
4675         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4676             p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
4677             p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
4678             tmpReg = 0;
4679             break;
4680         default:
4681             RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4682                          ("available for Rx and offline parsing ports only"));
4683     }
4684 
4685     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4686     {
4687         DBG(TRACE, ("FM Port Try Lock - BUSY"));
4688         return ERROR_CODE(E_BUSY);
4689     }
4690 
4691     if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
4692     {
4693         RELEASE_LOCK(p_FmPort->lock);
4694         RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
4695     }
4696 
4697     tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
4698 
4699     if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
4700     {
4701         /* update BMI HPNIA */
4702         WRITE_UINT32(*p_BmiHpnia, tmpReg);
4703     }
4704     else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
4705     {
4706         /* rfne may contain FDCS bits, so first we read them. */
4707         tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
4708         /* update BMI NIA */
4709         WRITE_UINT32(*p_BmiNia, tmpReg);
4710     }RELEASE_LOCK(p_FmPort->lock);
4711 
4712     return E_OK;
4713 }
4714 
4715 t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
4716 {
4717     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4718     t_Error err = E_OK;
4719     volatile uint32_t *p_BmiCcBase = NULL;
4720     volatile uint32_t *p_BmiNia = NULL;
4721     uint32_t ccTreePhysOffset;
4722 
4723     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4724     SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
4725 
4726     if (p_FmPort->imEn)
4727         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4728                      ("available for non-independent mode ports only"));
4729 
4730     /* get PCD registers pointers */
4731     switch (p_FmPort->portType)
4732     {
4733         case (e_FM_PORT_TYPE_RX_10G):
4734         case (e_FM_PORT_TYPE_RX):
4735             p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
4736             break;
4737         case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4738             p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
4739             break;
4740         default:
4741             RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4742                          ("available for Rx and offline parsing ports only"));
4743     }
4744 
4745     /* check that current NIA is BMI to BMI */
4746     if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
4747             != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
4748         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4749                      ("may be called only for ports in BMI-to-BMI state."));
4750 
4751     if (p_FmPort->pcdEngines & FM_PCD_CC)
4752     {
4753         if (p_FmPort->h_IpReassemblyManip)
4754         {
4755             err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
4756                                     p_FmPort->h_IpReassemblyManip, FALSE);
4757             if (err != E_OK)
4758             {
4759                 RETURN_ERROR(MAJOR, err, NO_MSG);
4760             }
4761         }
4762         else
4763             if (p_FmPort->h_CapwapReassemblyManip)
4764             {
4765                 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
4766                                         p_FmPort->h_CapwapReassemblyManip,
4767                                         FALSE);
4768                 if (err != E_OK)
4769                 {
4770                     RETURN_ERROR(MAJOR, err, NO_MSG);
4771                 }
4772             }
4773         switch (p_FmPort->portType)
4774         {
4775             case (e_FM_PORT_TYPE_RX_10G):
4776             case (e_FM_PORT_TYPE_RX):
4777                 p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
4778                 break;
4779             case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4780                 p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
4781                 break;
4782             default:
4783                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
4784         }
4785 
4786         if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4787         {
4788             DBG(TRACE, ("FM Port Try Lock - BUSY"));
4789             return ERROR_CODE(E_BUSY);
4790         }
4791         err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
4792                               &ccTreePhysOffset, h_FmPort);
4793         if (err)
4794         {
4795             RELEASE_LOCK(p_FmPort->lock);
4796             RETURN_ERROR(MAJOR, err, NO_MSG);
4797         }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
4798 
4799         p_FmPort->ccTreeId = h_CcTree;
4800         RELEASE_LOCK(p_FmPort->lock);
4801     }
4802     else
4803         RETURN_ERROR( MAJOR, E_INVALID_STATE,
4804                      ("Coarse Classification not defined for this port."));
4805 
4806     return E_OK;
4807 }
4808 
4809 t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
4810 {
4811     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4812     t_Error err = E_OK;
4813 
4814     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4815     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4816 
4817     if (p_FmPort->imEn)
4818         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4819                      ("available for non-independent mode ports only"));
4820 
4821     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4822             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4823             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4824         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4825                      ("available for Rx and offline parsing ports only"));
4826 
4827     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4828     {
4829         DBG(TRACE, ("FM Port Try Lock - BUSY"));
4830         return ERROR_CODE(E_BUSY);
4831     }
4832 
4833     if (p_FmPort->h_ReassemblyTree)
4834         p_FmPort->pcdEngines |= FM_PCD_CC;
4835 
4836     err = AttachPCD(h_FmPort);
4837     RELEASE_LOCK(p_FmPort->lock);
4838 
4839     return err;
4840 }
4841 
4842 t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
4843 {
4844     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4845     t_Error err = E_OK;
4846 
4847     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4848     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4849 
4850     if (p_FmPort->imEn)
4851         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4852                      ("available for non-independent mode ports only"));
4853 
4854     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4855             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4856             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4857         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4858                      ("available for Rx and offline parsing ports only"));
4859 
4860     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4861     {
4862         DBG(TRACE, ("FM Port Try Lock - BUSY"));
4863         return ERROR_CODE(E_BUSY);
4864     }
4865 
4866     err = DetachPCD(h_FmPort);
4867     if (err != E_OK)
4868     {
4869         RELEASE_LOCK(p_FmPort->lock);
4870         RETURN_ERROR(MAJOR, err, NO_MSG);
4871     }
4872 
4873     if (p_FmPort->h_ReassemblyTree)
4874         p_FmPort->pcdEngines &= ~FM_PCD_CC;
4875     RELEASE_LOCK(p_FmPort->lock);
4876 
4877     return E_OK;
4878 }
4879 
4880 t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
4881 {
4882     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4883     t_Error err = E_OK;
4884     t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
4885     t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
4886     t_FmPortPcdCcParams fmPortPcdCcParams;
4887     t_FmPortGetSetCcParams fmPortGetSetCcParams;
4888 
4889     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4890     SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
4891     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4892 
4893     if (p_FmPort->imEn)
4894         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4895                      ("available for non-independent mode ports only"));
4896 
4897     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4898             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4899             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4900         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4901                      ("available for Rx and offline parsing ports only"));
4902 
4903     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4904     {
4905         DBG(TRACE, ("FM Port Try Lock - BUSY"));
4906         return ERROR_CODE(E_BUSY);
4907     }
4908 
4909     p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
4910     ASSERT_COND(p_FmPort->h_FmPcd);
4911 
4912     if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
4913         RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
4914                      ("Tree handle must be given if CC is required"));
4915 
4916     memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
4917     p_PcdParams = &modifiedPcdParams;
4918     if ((p_PcdParams->h_IpReassemblyManip)
4919 #if (DPAA_VERSION >= 11)
4920             || (p_PcdParams->h_CapwapReassemblyManip)
4921 #endif /* (DPAA_VERSION >= 11) */
4922             )
4923     {
4924         if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4925                 && (p_PcdParams->pcdSupport
4926                         != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
4927                 && (p_PcdParams->pcdSupport
4928                         != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
4929                 && (p_PcdParams->pcdSupport
4930                         != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
4931         {
4932             RELEASE_LOCK(p_FmPort->lock);
4933             RETURN_ERROR( MAJOR, E_INVALID_STATE,
4934                          ("pcdSupport must have KG for supporting Reassembly"));
4935         }
4936         p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
4937 #if (DPAA_VERSION >= 11)
4938         if ((p_PcdParams->h_IpReassemblyManip)
4939                 && (p_PcdParams->h_CapwapReassemblyManip))
4940             RETURN_ERROR(MAJOR, E_INVALID_STATE,
4941                          ("Either IP-R or CAPWAP-R is allowed"));
4942         if ((p_PcdParams->h_CapwapReassemblyManip)
4943                 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4944             RETURN_ERROR(MAJOR, E_INVALID_STATE,
4945                          ("CAPWAP-R is allowed only on offline-port"));
4946         if (p_PcdParams->h_CapwapReassemblyManip)
4947             p_FmPort->h_CapwapReassemblyManip =
4948                     p_PcdParams->h_CapwapReassemblyManip;
4949 #endif /* (DPAA_VERSION >= 11) */
4950 
4951         if (!p_PcdParams->p_CcParams)
4952         {
4953             if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4954                     || (p_PcdParams->pcdSupport
4955                             == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
4956             {
4957                 RELEASE_LOCK(p_FmPort->lock);
4958                 RETURN_ERROR(
4959                         MAJOR,
4960                         E_INVALID_STATE,
4961                         ("PCD initialization structure is not consistent with pcdSupport"));
4962             }
4963 
4964             /* No user-tree, need to build internal tree */
4965             p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
4966                     sizeof(t_FmPcdCcTreeParams));
4967             if (!p_FmPcdCcTreeParams)
4968                 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
4969             memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
4970             p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
4971             p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
4972                     p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
4973 
4974             if (!p_FmPort->h_ReassemblyTree)
4975             {
4976                 RELEASE_LOCK(p_FmPort->lock);
4977                 XX_Free(p_FmPcdCcTreeParams);
4978                 RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
4979                              ("FM_PCD_CcBuildTree for Reassembly failed"));
4980             }
4981             if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4982                 p_PcdParams->pcdSupport =
4983                         e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
4984             else
4985                 p_PcdParams->pcdSupport =
4986                         e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
4987 
4988             memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
4989             fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
4990             p_PcdParams->p_CcParams = &fmPortPcdCcParams;
4991             XX_Free(p_FmPcdCcTreeParams);
4992         }
4993 
4994         if (p_FmPort->h_IpReassemblyManip)
4995             err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
4996                                     p_PcdParams->p_CcParams->h_CcTree,
4997                                     p_PcdParams->h_NetEnv,
4998                                     p_FmPort->h_IpReassemblyManip, TRUE);
4999 #if (DPAA_VERSION >= 11)
5000         else
5001             if (p_FmPort->h_CapwapReassemblyManip)
5002                 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
5003                                         p_PcdParams->p_CcParams->h_CcTree,
5004                                         p_PcdParams->h_NetEnv,
5005                                         p_FmPort->h_CapwapReassemblyManip,
5006                                         TRUE);
5007 #endif /* (DPAA_VERSION >= 11) */
5008 
5009         if (err != E_OK)
5010         {
5011             if (p_FmPort->h_ReassemblyTree)
5012             {
5013                 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5014                 p_FmPort->h_ReassemblyTree = NULL;
5015             }RELEASE_LOCK(p_FmPort->lock);
5016             RETURN_ERROR(MAJOR, err, NO_MSG);
5017         }
5018     }
5019 
5020     if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
5021     {
5022         if (p_FmPort->h_ReassemblyTree)
5023         {
5024             FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5025             p_FmPort->h_ReassemblyTree = NULL;
5026         }RELEASE_LOCK(p_FmPort->lock);
5027         DBG(TRACE, ("Try LockAll - BUSY"));
5028         return ERROR_CODE(E_BUSY);
5029     }
5030 
5031     err = SetPcd(h_FmPort, p_PcdParams);
5032     if (err)
5033     {
5034         if (p_FmPort->h_ReassemblyTree)
5035         {
5036             FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5037             p_FmPort->h_ReassemblyTree = NULL;
5038         }
5039         FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5040         RELEASE_LOCK(p_FmPort->lock);
5041         RETURN_ERROR(MAJOR, err, NO_MSG);
5042     }
5043 
5044     if ((p_FmPort->pcdEngines & FM_PCD_PRS)
5045             && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
5046     {
5047         err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
5048                                               p_FmPort->hardwarePortId, TRUE);
5049         if (err)
5050         {
5051             DeletePcd(p_FmPort);
5052             if (p_FmPort->h_ReassemblyTree)
5053             {
5054                 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5055                 p_FmPort->h_ReassemblyTree = NULL;
5056             }
5057             FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5058             RELEASE_LOCK(p_FmPort->lock);
5059             RETURN_ERROR(MAJOR, err, NO_MSG);
5060         }
5061         p_FmPort->includeInPrsStatistics = TRUE;
5062     }
5063 
5064     FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
5065 
5066     if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5067     {
5068         memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
5069 
5070         if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
5071         {
5072 #ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
5073             if ((p_FmPort->fmRevInfo.majorRev < 6) &&
5074                     (p_FmPort->pcdEngines & FM_PCD_KG))
5075             {
5076                 int i;
5077                 for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
5078                 /* The following function must be locked */
5079                 FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
5080                         p_PcdParams->p_KgParams->h_Schemes[i],
5081                         UPDATE_KG_NIA_CC_WA,
5082                         0);
5083             }
5084 #endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
5085 
5086 #if (DPAA_VERSION >= 11)
5087             {
5088                 t_FmPcdCtrlParamsPage *p_ParamsPage;
5089 
5090                 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
5091                                  (void**)&p_ParamsPage);
5092                 ASSERT_COND(p_ParamsPage);
5093                 WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
5094                              p_FmPort->savedBmiNia);
5095             }
5096 #endif /* (DPAA_VERSION >= 11) */
5097 
5098             /* Set post-bmi-fetch nia */
5099             p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
5100             p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
5101                     | NIA_ENG_FM_CTL);
5102 
5103             /* Set pre-bmi-fetch nia */
5104             fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
5105 #if (DPAA_VERSION >= 11)
5106             fmPortGetSetCcParams.setCcParams.nia =
5107                     (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
5108 #else
5109             fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
5110 #endif /* (DPAA_VERSION >= 11) */
5111             if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
5112                     != E_OK)
5113             {
5114                 DeletePcd(p_FmPort);
5115                 if (p_FmPort->h_ReassemblyTree)
5116                 {
5117                     FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5118                     p_FmPort->h_ReassemblyTree = NULL;
5119                 }
5120                 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5121                 RELEASE_LOCK(p_FmPort->lock);
5122                 RETURN_ERROR(MAJOR, err, NO_MSG);
5123             }
5124         }
5125 
5126         FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5127 
5128         /* Set pop-to-next-step nia */
5129 #if (DPAA_VERSION == 10)
5130         if (p_FmPort->fmRevInfo.majorRev < 6)
5131         {
5132             fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
5133             fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
5134         }
5135         else
5136         {
5137 #endif /* (DPAA_VERSION == 10) */
5138         fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
5139 #if (DPAA_VERSION == 10)
5140     }
5141 #endif /* (DPAA_VERSION == 10) */
5142         if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5143                 != E_OK)
5144         {
5145             DeletePcd(p_FmPort);
5146             if (p_FmPort->h_ReassemblyTree)
5147             {
5148                 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5149                 p_FmPort->h_ReassemblyTree = NULL;
5150             }RELEASE_LOCK(p_FmPort->lock);
5151             RETURN_ERROR(MAJOR, err, NO_MSG);
5152         }
5153 
5154         /* Set post-bmi-prepare-to-enq nia */
5155         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
5156         fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
5157                 | NIA_ENG_FM_CTL);
5158         if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5159                 != E_OK)
5160         {
5161             DeletePcd(p_FmPort);
5162             if (p_FmPort->h_ReassemblyTree)
5163             {
5164                 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5165                 p_FmPort->h_ReassemblyTree = NULL;
5166             }RELEASE_LOCK(p_FmPort->lock);
5167             RETURN_ERROR(MAJOR, err, NO_MSG);
5168         }
5169 
5170         if ((p_FmPort->h_IpReassemblyManip)
5171                 || (p_FmPort->h_CapwapReassemblyManip))
5172         {
5173 #if (DPAA_VERSION == 10)
5174             if (p_FmPort->fmRevInfo.majorRev < 6)
5175             {
5176                 /* Overwrite post-bmi-prepare-to-enq nia */
5177                 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
5178                 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
5179                 fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
5180             }
5181             else
5182             {
5183 #endif /* (DPAA_VERSION == 10) */
5184             /* Set the ORR bit (for order-restoration) */
5185             fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
5186             fmPortGetSetCcParams.setCcParams.nia =
5187                     fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
5188 #if (DPAA_VERSION == 10)
5189         }
5190 #endif /* (DPAA_VERSION == 10) */
5191             if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5192                     != E_OK)
5193             {
5194                 DeletePcd(p_FmPort);
5195                 if (p_FmPort->h_ReassemblyTree)
5196                 {
5197                     FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5198                     p_FmPort->h_ReassemblyTree = NULL;
5199                 }RELEASE_LOCK(p_FmPort->lock);
5200                 RETURN_ERROR(MAJOR, err, NO_MSG);
5201             }
5202         }
5203     }
5204     else
5205         FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5206 
5207 #if (DPAA_VERSION >= 11)
5208     {
5209         t_FmPcdCtrlParamsPage *p_ParamsPage;
5210 
5211         memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
5212 
5213         fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
5214         if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5215             fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
5216                     | NIA_ENG_FM_CTL;
5217         else
5218             fmPortGetSetCcParams.setCcParams.nia =
5219                     NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
5220         if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5221                 != E_OK)
5222         {
5223             DeletePcd(p_FmPort);
5224             if (p_FmPort->h_ReassemblyTree)
5225             {
5226                 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5227                 p_FmPort->h_ReassemblyTree = NULL;
5228             }RELEASE_LOCK(p_FmPort->lock);
5229             RETURN_ERROR(MAJOR, err, NO_MSG);
5230         }
5231 
5232         FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
5233                          (void**)&p_ParamsPage);
5234         ASSERT_COND(p_ParamsPage);
5235 
5236         if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5237             WRITE_UINT32(
5238                     p_ParamsPage->misc,
5239                     GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
5240 
5241         if ((p_FmPort->h_IpReassemblyManip)
5242                 || (p_FmPort->h_CapwapReassemblyManip))
5243         {
5244             if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
5245                 WRITE_UINT32(
5246                         p_ParamsPage->discardMask,
5247                         GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
5248             else
5249                 WRITE_UINT32(
5250                         p_ParamsPage->discardMask,
5251                         GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
5252         }
5253 #ifdef FM_ERROR_VSP_NO_MATCH_SW006
5254         if (p_FmPort->vspe)
5255             WRITE_UINT32(
5256                     p_ParamsPage->misc,
5257                     GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
5258 #endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
5259     }
5260 #endif /* (DPAA_VERSION >= 11) */
5261 
5262     err = AttachPCD(h_FmPort);
5263     if (err)
5264     {
5265         DeletePcd(p_FmPort);
5266         if (p_FmPort->h_ReassemblyTree)
5267         {
5268             FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5269             p_FmPort->h_ReassemblyTree = NULL;
5270         }RELEASE_LOCK(p_FmPort->lock);
5271         RETURN_ERROR(MAJOR, err, NO_MSG);
5272     }
5273 
5274     RELEASE_LOCK(p_FmPort->lock);
5275 
5276     return err;
5277 }
5278 
5279 t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
5280 {
5281     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5282     t_Error err = E_OK;
5283 
5284     SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
5285     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5286 
5287     if (p_FmPort->imEn)
5288         RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
5289                      ("available for non-independant mode ports only"));
5290 
5291     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5292             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5293             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5294         RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
5295                      ("available for Rx and offline parsing ports only"));
5296 
5297     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5298     {
5299         DBG(TRACE, ("FM Port Try Lock - BUSY"));
5300         return ERROR_CODE(E_BUSY);
5301     }
5302 
5303     err = DetachPCD(h_FmPort);
5304     if (err)
5305     {
5306         RELEASE_LOCK(p_FmPort->lock);
5307         RETURN_ERROR(MAJOR, err, NO_MSG);
5308     }
5309 
5310     FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
5311 
5312     /* we do it anyway, instead of checking if included */
5313     if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
5314     {
5315         FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
5316                                         p_FmPort->hardwarePortId, FALSE);
5317         p_FmPort->includeInPrsStatistics = FALSE;
5318     }
5319 
5320     if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
5321     {
5322         RELEASE_LOCK(p_FmPort->lock);
5323         DBG(TRACE, ("Try LockAll - BUSY"));
5324         return ERROR_CODE(E_BUSY);
5325     }
5326 
5327     err = DeletePcd(h_FmPort);
5328     FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5329     if (err)
5330     {
5331         RELEASE_LOCK(p_FmPort->lock);
5332         RETURN_ERROR(MAJOR, err, NO_MSG);
5333     }
5334 
5335     if (p_FmPort->h_ReassemblyTree)
5336     {
5337         err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5338         if (err)
5339         {
5340             RELEASE_LOCK(p_FmPort->lock);
5341             RETURN_ERROR(MAJOR, err, NO_MSG);
5342         }
5343         p_FmPort->h_ReassemblyTree = NULL;
5344     }RELEASE_LOCK(p_FmPort->lock);
5345 
5346     return err;
5347 }
5348 
5349 t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
5350                                  t_FmPcdPortSchemesParams *p_PortScheme)
5351 {
5352     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5353     t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
5354     t_Error err = E_OK;
5355     uint32_t tmpScmVec = 0;
5356     int i;
5357 
5358     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5359     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5360     SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
5361                               E_INVALID_STATE);
5362 
5363     schemeBind.netEnvId = p_FmPort->netEnvId;
5364     schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
5365     schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
5366     schemeBind.useClsPlan = p_FmPort->useClsPlan;
5367     for (i = 0; i < schemeBind.numOfSchemes; i++)
5368     {
5369         schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
5370                 p_PortScheme->h_Schemes[i]);
5371         /* build vector */
5372         tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
5373     }
5374 
5375     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5376     {
5377         DBG(TRACE, ("FM Port Try Lock - BUSY"));
5378         return ERROR_CODE(E_BUSY);
5379     }
5380 
5381     err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
5382     if (err == E_OK)
5383         p_FmPort->schemesPerPortVector |= tmpScmVec;
5384 
5385 #ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
5386     if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
5387             (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
5388             (p_FmPort->fmRevInfo.majorRev < 6))
5389     {
5390         for (i=0; i<p_PortScheme->numOfSchemes; i++)
5391         FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
5392     }
5393 #endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
5394 
5395     RELEASE_LOCK(p_FmPort->lock);
5396 
5397     return err;
5398 }
5399 
5400 t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
5401                                    t_FmPcdPortSchemesParams *p_PortScheme)
5402 {
5403     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5404     t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
5405     t_Error err = E_OK;
5406     uint32_t tmpScmVec = 0;
5407     int i;
5408 
5409     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5410     SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5411     SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
5412                               E_INVALID_STATE);
5413 
5414     schemeBind.netEnvId = p_FmPort->netEnvId;
5415     schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
5416     schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
5417     for (i = 0; i < schemeBind.numOfSchemes; i++)
5418     {
5419         schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
5420                 p_PortScheme->h_Schemes[i]);
5421         /* build vector */
5422         tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
5423     }
5424 
5425     if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5426     {
5427         DBG(TRACE, ("FM Port Try Lock - BUSY"));
5428         return ERROR_CODE(E_BUSY);
5429     }
5430 
5431     err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
5432     if (err == E_OK)
5433         p_FmPort->schemesPerPortVector &= ~tmpScmVec;
5434     RELEASE_LOCK(p_FmPort->lock);
5435 
5436     return err;
5437 }
5438 
5439 t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
5440                                   t_FmPortCongestionGrps *p_CongestionGrps)
5441 {
5442     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5443     uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
5444     uint8_t mod, index;
5445     uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
5446     int err;
5447 #if (DPAA_VERSION >= 11)
5448     int j;
5449 #endif /* (DPAA_VERSION >= 11) */
5450 
5451     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5452 
5453     /* un-necessary check of the indexes; probably will be needed in the future when there
5454      will be more CGs available ....
5455      for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5456      if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
5457      RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
5458      */
5459 
5460 #ifdef FM_NO_OP_OBSERVED_CGS
5461     if ((p_FmPort->fmRevInfo.majorRev != 4) &&
5462             (p_FmPort->fmRevInfo.majorRev < 6))
5463     {
5464         if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
5465                 (p_FmPort->portType != e_FM_PORT_TYPE_RX))
5466         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
5467     }
5468     else
5469 #endif /* FM_NO_OP_OBSERVED_CGS */
5470     if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5471             && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5472             && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5473         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5474                      ("Available for Rx & OP ports only"));
5475 
5476     /* Prepare groups map array */
5477     memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
5478     for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5479     {
5480         index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
5481         mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
5482         if (p_FmPort->fmRevInfo.majorRev != 4)
5483             grpsMap[7 - index] |= (uint32_t)(1 << mod);
5484         else
5485             grpsMap[0] |= (uint32_t)(1 << mod);
5486     }
5487 
5488     memset(&priorityTmpArray, 0,
5489            FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
5490 
5491     for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5492     {
5493 #if (DPAA_VERSION >= 11)
5494         for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
5495             if (p_CongestionGrps->pfcPrioritiesEn[i][j])
5496                 priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
5497                         (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
5498 #endif /* (DPAA_VERSION >= 11) */
5499     }
5500 
5501 #if (DPAA_VERSION >= 11)
5502     for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
5503     {
5504         err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
5505                                               priorityTmpArray[i]);
5506         if (err)
5507             return err;
5508     }
5509 #endif /* (DPAA_VERSION >= 11) */
5510 
5511     err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
5512     if (err != 0)
5513         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
5514 
5515     return E_OK;
5516 }
5517 
5518 t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
5519                                      t_FmPortCongestionGrps *p_CongestionGrps)
5520 {
5521     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5522     uint8_t mod, index;
5523     uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
5524     int err;
5525 
5526     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5527 
5528     {
5529 #ifdef FM_NO_OP_OBSERVED_CGS
5530         t_FmRevisionInfo revInfo;
5531 
5532         FM_GetRevision(p_FmPort->h_Fm, &revInfo);
5533         if (revInfo.majorRev != 4)
5534         {
5535             if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
5536                     (p_FmPort->portType != e_FM_PORT_TYPE_RX))
5537             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
5538         }
5539         else
5540 #endif /* FM_NO_OP_OBSERVED_CGS */
5541         if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5542                 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5543                 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5544             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5545                          ("Available for Rx & OP ports only"));
5546     }
5547 
5548     /* Prepare groups map array */
5549     memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
5550     for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5551     {
5552         index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
5553         mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
5554         if (p_FmPort->fmRevInfo.majorRev != 4)
5555             grpsMap[7 - index] |= (uint32_t)(1 << mod);
5556         else
5557             grpsMap[0] |= (uint32_t)(1 << mod);
5558     }
5559 
5560 #if (DPAA_VERSION >= 11)
5561     for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5562     {
5563         t_Error err = FmSetCongestionGroupPFCpriority(
5564                 p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
5565                 0);
5566         if (err)
5567             return err;
5568     }
5569 #endif /* (DPAA_VERSION >= 11) */
5570 
5571     err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
5572     if (err != 0)
5573         RETURN_ERROR(MAJOR, E_INVALID_VALUE,
5574                      ("fman_port_remove_congestion_grps"));
5575     return E_OK;
5576 }
5577 
5578 #if (DPAA_VERSION >= 11)
5579 t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
5580                                     uint32_t *p_Ipv4OptionsCount)
5581 {
5582     t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5583 
5584     SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5585     SANITY_CHECK_RETURN_ERROR(
5586             (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
5587             E_INVALID_VALUE);
5588     SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
5589     SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
5590 
5591     *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
5592 
5593     return E_OK;
5594 }
5595 #endif /* (DPAA_VERSION >= 11) */
5596 
5597 t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
5598                                   t_FmPortDsarTablesSizes *params)
5599 {
5600     t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5601     p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
5602             sizeof(struct t_FmPortDsarTablesSizes));
5603     memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
5604            sizeof(struct t_FmPortDsarTablesSizes));
5605     return E_OK;
5606 }
5607 
5608 static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
5609 {
5610     uint32_t *param_page;
5611     t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
5612     t_ArCommonDesc *ArCommonDescPtr;
5613     uint32_t size = sizeof(t_ArCommonDesc);
5614     // ARP
5615     // should put here if (params->max_num_of_arp_entries)?
5616     size = ROUND_UP(size,4);
5617     size += sizeof(t_DsarArpDescriptor);
5618     size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
5619     size += sizeof(t_DsarArpStatistics);
5620     //ICMPV4
5621     size = ROUND_UP(size,4);
5622     size += sizeof(t_DsarIcmpV4Descriptor);
5623     size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
5624     size += sizeof(t_DsarIcmpV4Statistics);
5625     //ICMPV6
5626     size = ROUND_UP(size,4);
5627     size += sizeof(t_DsarIcmpV6Descriptor);
5628     size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
5629     size += sizeof(t_DsarIcmpV6Statistics);
5630     //ND
5631     size = ROUND_UP(size,4);
5632     size += sizeof(t_DsarNdDescriptor);
5633     size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
5634     size += sizeof(t_DsarIcmpV6Statistics);
5635     //SNMP
5636     size = ROUND_UP(size,4);
5637     size += sizeof(t_DsarSnmpDescriptor);
5638     size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
5639             * params->maxNumOfSnmpIPV4Entries;
5640     size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
5641             * params->maxNumOfSnmpIPV6Entries;
5642     size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
5643     size += params->maxNumOfSnmpOidChar;
5644     size += sizeof(t_DsarIcmpV6Statistics);
5645     //filters
5646     size = ROUND_UP(size,4);
5647     size += params->maxNumOfIpProtFiltering;
5648     size = ROUND_UP(size,4);
5649     size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
5650     size = ROUND_UP(size,4);
5651     size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
5652 
5653     // add here for more protocols
5654 
5655     // statistics
5656     size = ROUND_UP(size,4);
5657     size += sizeof(t_ArStatistics);
5658 
5659     ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
5660 
5661     param_page =
5662             XX_PhysToVirt(
5663                     p_FmPort->fmMuramPhysBaseAddr
5664                             + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
5665     WRITE_UINT32(
5666             *param_page,
5667             (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
5668     return E_OK;
5669 }
5670 
5671 t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
5672 {
5673     t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5674     return p_FmPort->deepSleepVars.autoResMaxSizes;
5675 }
5676 
5677 struct arOffsets
5678 {
5679     uint32_t arp;
5680     uint32_t nd;
5681     uint32_t icmpv4;
5682     uint32_t icmpv6;
5683     uint32_t snmp;
5684     uint32_t stats;
5685     uint32_t filtIp;
5686     uint32_t filtUdp;
5687     uint32_t filtTcp;
5688 };
5689 
5690 static uint32_t AR_ComputeOffsets(struct arOffsets* of,
5691                                   struct t_FmPortDsarParams *params,
5692                                   t_FmPort *p_FmPort)
5693 {
5694     uint32_t size = sizeof(t_ArCommonDesc);
5695     // ARP
5696     if (params->p_AutoResArpInfo)
5697     {
5698         size = ROUND_UP(size,4);
5699         of->arp = size;
5700         size += sizeof(t_DsarArpDescriptor);
5701         size += sizeof(t_DsarArpBindingEntry)
5702                 * params->p_AutoResArpInfo->tableSize;
5703         size += sizeof(t_DsarArpStatistics);
5704     }
5705     // ICMPV4
5706     if (params->p_AutoResEchoIpv4Info)
5707     {
5708         size = ROUND_UP(size,4);
5709         of->icmpv4 = size;
5710         size += sizeof(t_DsarIcmpV4Descriptor);
5711         size += sizeof(t_DsarIcmpV4BindingEntry)
5712                 * params->p_AutoResEchoIpv4Info->tableSize;
5713         size += sizeof(t_DsarIcmpV4Statistics);
5714     }
5715     // ICMPV6
5716     if (params->p_AutoResEchoIpv6Info)
5717     {
5718         size = ROUND_UP(size,4);
5719         of->icmpv6 = size;
5720         size += sizeof(t_DsarIcmpV6Descriptor);
5721         size += sizeof(t_DsarIcmpV6BindingEntry)
5722                 * params->p_AutoResEchoIpv6Info->tableSize;
5723         size += sizeof(t_DsarIcmpV6Statistics);
5724     }
5725     // ND
5726     if (params->p_AutoResNdpInfo)
5727     {
5728         size = ROUND_UP(size,4);
5729         of->nd = size;
5730         size += sizeof(t_DsarNdDescriptor);
5731         size += sizeof(t_DsarIcmpV6BindingEntry)
5732                 * (params->p_AutoResNdpInfo->tableSizeAssigned
5733                         + params->p_AutoResNdpInfo->tableSizeTmp);
5734         size += sizeof(t_DsarIcmpV6Statistics);
5735     }
5736     // SNMP
5737     if (params->p_AutoResSnmpInfo)
5738     {
5739         size = ROUND_UP(size,4);
5740         of->snmp = size;
5741         size += sizeof(t_DsarSnmpDescriptor);
5742         size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
5743                 * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
5744         size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
5745                 * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
5746         size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
5747         size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
5748         size += sizeof(t_DsarIcmpV6Statistics);
5749     }
5750     //filters
5751     size = ROUND_UP(size,4);
5752     if (params->p_AutoResFilteringInfo)
5753     {
5754         of->filtIp = size;
5755         size += params->p_AutoResFilteringInfo->ipProtTableSize;
5756         size = ROUND_UP(size,4);
5757         of->filtUdp = size;
5758         size += params->p_AutoResFilteringInfo->udpPortsTableSize
5759                 * sizeof(t_PortTblEntry);
5760         size = ROUND_UP(size,4);
5761         of->filtTcp = size;
5762         size += params->p_AutoResFilteringInfo->tcpPortsTableSize
5763                 * sizeof(t_PortTblEntry);
5764     }
5765     // add here for more protocols
5766     // statistics
5767     size = ROUND_UP(size,4);
5768     of->stats = size;
5769     size += sizeof(t_ArStatistics);
5770     return size;
5771 }
5772 
5773 uint32_t* ARDesc;
5774 void PrsEnable(t_Handle p_FmPcd);
5775 void PrsDisable(t_Handle p_FmPcd);
5776 int PrsIsEnabled(t_Handle p_FmPcd);
5777 t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
5778 
5779 static t_Error DsarCheckParams(t_FmPortDsarParams *params,
5780                                t_FmPortDsarTablesSizes *sizes)
5781 {
5782     bool macInit = FALSE;
5783     uint8_t mac[6];
5784     int i = 0;
5785 
5786     // check table sizes
5787     if (params->p_AutoResArpInfo
5788             && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
5789         RETURN_ERROR(
5790                 MAJOR, E_INVALID_VALUE,
5791                 ("DSAR: Arp table size exceeds the configured maximum size."));
5792     if (params->p_AutoResEchoIpv4Info
5793             && sizes->maxNumOfEchoIpv4Entries
5794                     < params->p_AutoResEchoIpv4Info->tableSize)
5795         RETURN_ERROR(
5796                 MAJOR,
5797                 E_INVALID_VALUE,
5798                 ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
5799     if (params->p_AutoResNdpInfo
5800             && sizes->maxNumOfNdpEntries
5801                     < params->p_AutoResNdpInfo->tableSizeAssigned
5802                             + params->p_AutoResNdpInfo->tableSizeTmp)
5803         RETURN_ERROR(
5804                 MAJOR, E_INVALID_VALUE,
5805                 ("DSAR: NDP table size exceeds the configured maximum size."));
5806     if (params->p_AutoResEchoIpv6Info
5807             && sizes->maxNumOfEchoIpv6Entries
5808                     < params->p_AutoResEchoIpv6Info->tableSize)
5809         RETURN_ERROR(
5810                 MAJOR,
5811                 E_INVALID_VALUE,
5812                 ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
5813     if (params->p_AutoResSnmpInfo
5814             && sizes->maxNumOfSnmpOidEntries
5815                     < params->p_AutoResSnmpInfo->oidsTblSize)
5816         RETURN_ERROR(
5817                 MAJOR,
5818                 E_INVALID_VALUE,
5819                 ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
5820     if (params->p_AutoResSnmpInfo
5821             && sizes->maxNumOfSnmpIPV4Entries
5822                     < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
5823         RETURN_ERROR(
5824                 MAJOR,
5825                 E_INVALID_VALUE,
5826                 ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
5827     if (params->p_AutoResSnmpInfo
5828             && sizes->maxNumOfSnmpIPV6Entries
5829                     < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
5830         RETURN_ERROR(
5831                 MAJOR,
5832                 E_INVALID_VALUE,
5833                 ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
5834     if (params->p_AutoResFilteringInfo)
5835     {
5836         if (sizes->maxNumOfIpProtFiltering
5837                 < params->p_AutoResFilteringInfo->ipProtTableSize)
5838             RETURN_ERROR(
5839                     MAJOR,
5840                     E_INVALID_VALUE,
5841                     ("DSAR: ip filter table size exceeds the configured maximum size."));
5842         if (sizes->maxNumOfTcpPortFiltering
5843                 < params->p_AutoResFilteringInfo->udpPortsTableSize)
5844             RETURN_ERROR(
5845                     MAJOR,
5846                     E_INVALID_VALUE,
5847                     ("DSAR: udp filter table size exceeds the configured maximum size."));
5848         if (sizes->maxNumOfUdpPortFiltering
5849                 < params->p_AutoResFilteringInfo->tcpPortsTableSize)
5850             RETURN_ERROR(
5851                     MAJOR,
5852                     E_INVALID_VALUE,
5853                     ("DSAR: tcp filter table size exceeds the configured maximum size."));
5854     }
5855     /* check only 1 MAC address is configured (this is what ucode currently supports) */
5856     if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
5857     {
5858         memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
5859         i = 1;
5860         macInit = TRUE;
5861 
5862         for (; i < params->p_AutoResArpInfo->tableSize; i++)
5863             if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
5864                 RETURN_ERROR(
5865                         MAJOR, E_INVALID_VALUE,
5866                         ("DSAR: Only 1 mac address is currently supported."));
5867     }
5868     if (params->p_AutoResEchoIpv4Info
5869             && params->p_AutoResEchoIpv4Info->tableSize)
5870     {
5871         i = 0;
5872         if (!macInit)
5873         {
5874             memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
5875                    6);
5876             i = 1;
5877             macInit = TRUE;
5878         }
5879         for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
5880             if (memcmp(mac,
5881                        params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
5882                 RETURN_ERROR(
5883                         MAJOR, E_INVALID_VALUE,
5884                         ("DSAR: Only 1 mac address is currently supported."));
5885     }
5886     if (params->p_AutoResEchoIpv6Info
5887             && params->p_AutoResEchoIpv6Info->tableSize)
5888     {
5889         i = 0;
5890         if (!macInit)
5891         {
5892             memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
5893                    6);
5894             i = 1;
5895             macInit = TRUE;
5896         }
5897         for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
5898             if (memcmp(mac,
5899                        params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
5900                 RETURN_ERROR(
5901                         MAJOR, E_INVALID_VALUE,
5902                         ("DSAR: Only 1 mac address is currently supported."));
5903     }
5904     if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
5905     {
5906         i = 0;
5907         if (!macInit)
5908         {
5909             memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
5910                    6);
5911             i = 1;
5912             macInit = TRUE;
5913         }
5914         for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
5915             if (memcmp(mac,
5916                        params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
5917                        6))
5918                 RETURN_ERROR(
5919                         MAJOR, E_INVALID_VALUE,
5920                         ("DSAR: Only 1 mac address is currently supported."));
5921     }
5922     if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
5923     {
5924         i = 0;
5925         if (!macInit)
5926         {
5927             memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
5928             i = 1;
5929         }
5930         for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
5931             if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
5932                        6))
5933                 RETURN_ERROR(
5934                         MAJOR, E_INVALID_VALUE,
5935                         ("DSAR: Only 1 mac address is currently supported."));
5936     }
5937     return E_OK;
5938 }
5939 
5940 static int GetBERLen(uint8_t* buf)
5941 {
5942     if (*buf & 0x80)
5943     {
5944         if ((*buf & 0x7F) == 1)
5945             return buf[1];
5946         else
5947             return *(uint16_t*)&buf[1]; // assuming max len is 2
5948     }
5949     else
5950         return buf[0];
5951 }
5952 #define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
5953 
5954 #ifdef TODO_SOC_SUSPEND // XXX
5955 #define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
5956 #define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
5957 #define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
5958 static int fm_soc_suspend(void)
5959 {
5960 	uint32_t *fmclk, tmp32;
5961 	fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
5962 	tmp32 = GET_UINT32(*fmclk);
5963 	WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
5964 	tmp32 = GET_UINT32(*fmclk);
5965 	iounmap(fmclk);
5966 	return 0;
5967 }
5968 
5969 void fm_clk_down(void)
5970 {
5971 	uint32_t *fmclk, tmp32;
5972 	fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
5973 	tmp32 = GET_UINT32(*fmclk);
5974 	WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
5975 	tmp32 = GET_UINT32(*fmclk);
5976 	iounmap(fmclk);
5977 }
5978 #endif
5979 
5980 #if 0
5981 t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
5982 {
5983     int i, j;
5984     t_Error err;
5985     uint32_t nia;
5986     t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5987     t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
5988     t_DsarArpDescriptor *ArpDescriptor;
5989     t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
5990     t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
5991     t_DsarNdDescriptor* NDDescriptor;
5992 
5993     uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
5994     uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
5995     t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
5996     struct arOffsets* of;
5997     uint8_t tmp = 0;
5998     t_FmGetSetParams fmGetSetParams;
5999     memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6000     fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6001     fmGetSetParams.setParams.sleep = 1;
6002 
6003     err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
6004     if (err != E_OK)
6005         return err;
6006 
6007     p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
6008     of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
6009     IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
6010 
6011     // common
6012     WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
6013     nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
6014     if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
6015         WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
6016     else
6017         WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
6018     WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
6019 
6020     // ARP
6021     if (params->p_AutoResArpInfo)
6022     {
6023         t_DsarArpBindingEntry* arp_bindings;
6024         ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
6025         WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
6026         arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
6027 	if (params->p_AutoResArpInfo->enableConflictDetection)
6028 	        WRITE_UINT16(ArpDescriptor->control, 1);
6029 	else
6030         WRITE_UINT16(ArpDescriptor->control, 0);
6031         if (params->p_AutoResArpInfo->tableSize)
6032         {
6033             t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
6034             WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
6035             WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
6036             WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
6037 
6038             for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
6039             {
6040                 WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
6041                 if (arp_entry[i].isVlan)
6042                     WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
6043             }
6044             WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
6045         }
6046         WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
6047             sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
6048     }
6049 
6050     // ICMPV4
6051     if (params->p_AutoResEchoIpv4Info)
6052     {
6053         t_DsarIcmpV4BindingEntry* icmpv4_bindings;
6054         ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
6055         WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
6056         icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
6057         WRITE_UINT16(ICMPV4Descriptor->control, 0);
6058         if (params->p_AutoResEchoIpv4Info->tableSize)
6059         {
6060             t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
6061             WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
6062             WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
6063             WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
6064 
6065             for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
6066             {
6067                 WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
6068                 if (arp_entry[i].isVlan)
6069                     WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
6070             }
6071             WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
6072         }
6073         WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
6074             sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
6075     }
6076 
6077     // ICMPV6
6078     if (params->p_AutoResEchoIpv6Info)
6079     {
6080         t_DsarIcmpV6BindingEntry* icmpv6_bindings;
6081         ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
6082         WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
6083         icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
6084         WRITE_UINT16(ICMPV6Descriptor->control, 0);
6085         if (params->p_AutoResEchoIpv6Info->tableSize)
6086         {
6087             t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
6088             WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
6089             WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
6090             WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
6091 
6092             for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
6093             {
6094                 for (j = 0; j < 4; j++)
6095                     WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6096                 if (ndp_entry[i].isVlan)
6097                     WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6098             }
6099             WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
6100         }
6101         WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
6102             sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
6103     }
6104 
6105     // ND
6106     if (params->p_AutoResNdpInfo)
6107     {
6108         t_DsarIcmpV6BindingEntry* icmpv6_bindings;
6109         NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
6110         WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
6111         icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
6112 	if (params->p_AutoResNdpInfo->enableConflictDetection)
6113 	        WRITE_UINT16(NDDescriptor->control, 1);
6114 	else
6115         WRITE_UINT16(NDDescriptor->control, 0);
6116         if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
6117         {
6118             t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
6119             WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
6120             WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
6121             WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
6122                 + params->p_AutoResNdpInfo->tableSizeTmp);
6123 
6124             for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
6125             {
6126                 for (j = 0; j < 4; j++)
6127                     WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6128                 if (ndp_entry[i].isVlan)
6129                     WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6130             }
6131             ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
6132             for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
6133             {
6134                 for (j = 0; j < 4; j++)
6135                     WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6136                 if (ndp_entry[i].isVlan)
6137                     WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6138             }
6139             WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
6140         }
6141         WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
6142             * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
6143             - fmMuramVirtBaseAddr);
6144         WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
6145     }
6146 
6147     // SNMP
6148     if (params->p_AutoResSnmpInfo)
6149     {
6150         t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
6151         t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
6152         t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
6153         t_OidsTblEntry* snmpOid;
6154         uint8_t *charPointer;
6155         int len;
6156         t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
6157         WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
6158         WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
6159         WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
6160         snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
6161         if (snmpSrc->numOfIpv4Addresses)
6162         {
6163             t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
6164             WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
6165             for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
6166             {
6167                 WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
6168                 if (snmpIpv4AddrSrc[i].isVlan)
6169                     WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
6170             }
6171             WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
6172         }
6173         snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
6174                 + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
6175         if (snmpSrc->numOfIpv6Addresses)
6176         {
6177             t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
6178             WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
6179             for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
6180             {
6181                 for (j = 0; j < 4; j++)
6182                     WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
6183                 if (snmpIpv6AddrSrc[i].isVlan)
6184                     WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
6185             }
6186             WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
6187         }
6188         snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
6189                 + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
6190         charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
6191                 + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
6192         len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
6193         Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
6194         WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6195         charPointer += len;
6196         len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
6197         Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
6198         WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6199         charPointer += len;
6200         WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
6201         WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
6202         for (i = 0; i < snmpSrc->oidsTblSize; i++)
6203         {
6204             WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
6205             WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
6206             Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
6207             WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6208             charPointer += snmpSrc->p_OidsTbl[i].oidSize;
6209             if (snmpSrc->p_OidsTbl[i].resSize <= 4)
6210                 WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
6211             else
6212             {
6213                 Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
6214                 WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6215                 charPointer += snmpSrc->p_OidsTbl[i].resSize;
6216             }
6217             snmpOid++;
6218         }
6219         charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
6220         WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6221     }
6222 
6223     // filtering
6224     if (params->p_AutoResFilteringInfo)
6225     {
6226         if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
6227             tmp |= IP_PROT_TBL_PASS_MASK;
6228         if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
6229             tmp |= UDP_PORT_TBL_PASS_MASK;
6230         if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
6231             tmp |= TCP_PORT_TBL_PASS_MASK;
6232         WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
6233         WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
6234 
6235         // ip filtering
6236         if (params->p_AutoResFilteringInfo->ipProtTableSize)
6237         {
6238             uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
6239             WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
6240             for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
6241                 WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
6242             WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
6243         }
6244 
6245         // udp filtering
6246         if (params->p_AutoResFilteringInfo->udpPortsTableSize)
6247         {
6248             t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
6249             WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
6250             for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
6251             {
6252                 WRITE_UINT32(udp_tbl[i].Ports,
6253                     (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
6254                     params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
6255                 WRITE_UINT32(udp_tbl[i].PortsMask,
6256                     (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
6257                     params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
6258             }
6259             WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
6260         }
6261 
6262         // tcp filtering
6263         if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
6264         {
6265             t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
6266             WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
6267             for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
6268             {
6269                 WRITE_UINT32(tcp_tbl[i].Ports,
6270                     (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
6271                     params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
6272                 WRITE_UINT32(tcp_tbl[i].PortsMask,
6273                     (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
6274                     params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
6275             }
6276             WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
6277         }
6278     }
6279     // common stats
6280     WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
6281 
6282     // get into Deep Sleep sequence:
6283 
6284 	// Ensures that FMan do not enter the idle state. This is done by programing
6285 	// FMDPSLPCR[FM_STOP] to one.
6286 	fm_soc_suspend();
6287 
6288     ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
6289     return E_OK;
6290 
6291 }
6292 
6293 void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
6294 t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
6295 {
6296 	t_FmGetSetParams fmGetSetParams;
6297 	t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
6298 	t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
6299 	t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
6300 	t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
6301 	memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6302         fmGetSetParams.setParams.type = UPDATE_FM_CLD;
6303         FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6304 
6305 	/* Issue graceful stop to HC port */
6306 	FM_PORT_Disable(p_FmPortHc);
6307 
6308 	// config tx port
6309     p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
6310     WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN);
6311     // ????
6312     p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
6313     WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
6314     // Stage 7:echo
6315     p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
6316     WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
6317     if (!PrsIsEnabled(h_FmPcd))
6318     {
6319         p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
6320         PrsEnable(h_FmPcd);
6321     }
6322     else
6323         p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
6324 
6325     p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
6326     WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
6327 
6328     // save rcfg for restoring: accumulate mode is changed by ucode
6329     p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
6330     WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
6331         memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6332         fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6333         fmGetSetParams.setParams.sleep = 1;
6334         FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6335 
6336 // ***** issue external request sync command
6337         memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6338         fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
6339         FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6340 	// get
6341 	memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6342 	fmGetSetParams.getParams.type = GET_FMFP_EXTC;
6343 	FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6344 	if (fmGetSetParams.getParams.fmfp_extc != 0)
6345 	{
6346 		// clear
6347 		memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6348 		fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
6349 		FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6350 }
6351 
6352 	memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6353 	fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
6354 	do
6355 	{
6356 		FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6357 	} while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
6358 	if (fmGetSetParams.getParams.fm_npi != 0)
6359 		XX_Print("FM: Sync did not finish\n");
6360 
6361         // check that all stoped
6362 	memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6363         fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
6364         FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6365 	while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
6366 	        FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6367 	if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
6368 		XX_Print("FM: Sleeping\n");
6369 //	FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
6370 
6371     return E_OK;
6372 }
6373 
6374 void FM_PORT_Dsar_DumpRegs()
6375 {
6376     uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
6377     DUMP_MEMORY(hh, 0x220);
6378 }
6379 
6380 void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
6381 {
6382     t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
6383     t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
6384     t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
6385     t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
6386     t_FmGetSetParams fmGetSetParams;
6387     memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6388     fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6389     fmGetSetParams.setParams.sleep = 0;
6390     if (p_FmPort->deepSleepVars.autoResOffsets)
6391     {
6392         XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
6393         p_FmPort->deepSleepVars.autoResOffsets = 0;
6394     }
6395 
6396     if (p_FmPort->deepSleepVars.dsarEnabledParser)
6397         PrsDisable(FmGetPcd(p_FmPort->h_Fm));
6398     WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
6399     WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
6400     WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
6401     FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6402     WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
6403     WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
6404     FM_PORT_Enable(p_FmPortHc);
6405 }
6406 
6407 bool FM_PORT_IsInDsar(t_Handle h_FmPort)
6408 {
6409     t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
6410     return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
6411 }
6412 
6413 t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
6414 {
6415     t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
6416     struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
6417     uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
6418     uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
6419     t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
6420     t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
6421     t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6422     t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
6423     t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
6424     t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
6425     t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6426     t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
6427     t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
6428     t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
6429     t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6430     stats->arpArCnt = arp_stats->arCnt;
6431     stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
6432     stats->ndpArCnt = nd_stats->arCnt;
6433     stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
6434     stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
6435     stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
6436     return E_OK;
6437 }
6438 #endif
6439