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/****************************************/
54static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
55
56static 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
416static 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
532static 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
541static 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
651static 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
661static 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
773static 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
800static 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
822static 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
848static 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
974static 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
1049static 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
1079static 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
1111static 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
1670static 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
1760static 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
1838static 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/*****************************************************************************/
1888void 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
1913uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
1914{
1915    return ((t_FmPort*)h_FmPort)->netEnvId;
1916}
1917
1918uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
1919{
1920    return ((t_FmPort*)h_FmPort)->hardwarePortId;
1921}
1922
1923uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
1924{
1925    return ((t_FmPort*)h_FmPort)->pcdEngines;
1926}
1927
1928#if (DPAA_VERSION >= 11)
1929t_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
1995t_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
2211t_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
2561t_FmPort *rx_port = 0;
2562t_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 *//***************************************************************************/
2573t_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 *//***************************************************************************/
2763t_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
2816t_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
2829t_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
2841t_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
2854t_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
2869t_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
2886t_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
2903t_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
2925t_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
2941t_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
2959t_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
2973t_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
2990t_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
3009t_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
3032t_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
3049t_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
3065t_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
3076t_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
3093t_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
3109t_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
3127t_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
3140t_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
3154t_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
3168t_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
3182t_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)
3200t_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
3216t_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
3234t_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
3247t_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
3264t_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
3281t_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
3304t_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
3322t_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
3338t_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
3358t_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
3386t_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
3418t_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
3465uint32_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
3476uint8_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
3490t_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
3504uint64_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
3518uint8_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
3532t_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
3560t_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
3587t_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
3681t_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
3701t_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
3734t_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
3746t_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
3760t_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
3840t_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
3942t_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
3956t_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
3999t_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
4020t_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
4160uint32_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
4247t_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
4329uint32_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
4345t_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}
4361bool 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
4380t_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
4390t_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)
4422t_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
4517t_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
4546t_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
4567t_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
4644t_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
4715t_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
4809t_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
4842t_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
4880t_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
5279t_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
5349t_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
5400t_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
5439t_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
5518t_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)
5579t_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
5597t_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
5608static 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
5671t_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
5677struct 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
5690static 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
5773uint32_t* ARDesc;
5774void PrsEnable(t_Handle p_FmPcd);
5775void PrsDisable(t_Handle p_FmPcd);
5776int PrsIsEnabled(t_Handle p_FmPcd);
5777t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
5778
5779static 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
5940static 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
5958static 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
5969void 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
5981t_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
6293void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
6294t_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
6374void FM_PORT_Dsar_DumpRegs()
6375{
6376    uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
6377    DUMP_MEMORY(hh, 0x220);
6378}
6379
6380void 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
6407bool 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
6413t_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