1254885Sdumbbell/*
2254885Sdumbbell * Copyright 2008-2012 Freescale Semiconductor Inc.
3254885Sdumbbell *
4254885Sdumbbell * Redistribution and use in source and binary forms, with or without
5254885Sdumbbell * modification, are permitted provided that the following conditions are met:
6254885Sdumbbell *     * Redistributions of source code must retain the above copyright
7254885Sdumbbell *       notice, this list of conditions and the following disclaimer.
8254885Sdumbbell *     * Redistributions in binary form must reproduce the above copyright
9254885Sdumbbell *       notice, this list of conditions and the following disclaimer in the
10254885Sdumbbell *       documentation and/or other materials provided with the distribution.
11254885Sdumbbell *     * Neither the name of Freescale Semiconductor nor the
12254885Sdumbbell *       names of its contributors may be used to endorse or promote products
13254885Sdumbbell *       derived from this software without specific prior written permission.
14254885Sdumbbell *
15254885Sdumbbell *
16254885Sdumbbell * ALTERNATIVELY, this software may be distributed under the terms of the
17254885Sdumbbell * GNU General Public License ("GPL") as published by the Free Software
18254885Sdumbbell * Foundation, either version 2 of that License or (at your option) any
19254885Sdumbbell * later version.
20254885Sdumbbell *
21254885Sdumbbell * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22254885Sdumbbell * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23254885Sdumbbell * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24254885Sdumbbell * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25254885Sdumbbell * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26254885Sdumbbell * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27254885Sdumbbell * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28254885Sdumbbell * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29254885Sdumbbell * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30254885Sdumbbell * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31254885Sdumbbell */
32254885Sdumbbell
33254885Sdumbbell
34254885Sdumbbell/******************************************************************************
35254885Sdumbbell @File          fm_port.c
36254885Sdumbbell
37254885Sdumbbell @Description   FM driver routines implementation.
38254885Sdumbbell *//***************************************************************************/
39254885Sdumbbell#include "error_ext.h"
40254885Sdumbbell#include "std_ext.h"
41254885Sdumbbell#include "string_ext.h"
42254885Sdumbbell#include "sprint_ext.h"
43254885Sdumbbell#include "debug_ext.h"
44254885Sdumbbell#include "fm_muram_ext.h"
45254885Sdumbbell
46254885Sdumbbell#include "fman_common.h"
47254885Sdumbbell#include "fm_port.h"
48254885Sdumbbell#include "fm_port_dsar.h"
49254885Sdumbbell#include "common/general.h"
50254885Sdumbbell
51254885Sdumbbell/****************************************/
52254885Sdumbbell/*       static functions               */
53254885Sdumbbell/****************************************/
54254885Sdumbbellstatic t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
55254885Sdumbbell
56254885Sdumbbellstatic t_Error CheckInitParameters(t_FmPort *p_FmPort)
57254885Sdumbbell{
58254885Sdumbbell    t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
59254885Sdumbbell    struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
60254885Sdumbbell    t_Error ans = E_OK;
61254885Sdumbbell    uint32_t unusedMask;
62254885Sdumbbell
63254885Sdumbbell    if (p_FmPort->imEn)
64254885Sdumbbell    {
65254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
66254885Sdumbbell            if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
67254885Sdumbbell                    > 2)
68254885Sdumbbell                RETURN_ERROR(
69254885Sdumbbell                        MAJOR,
70254885Sdumbbell                        E_INVALID_VALUE,
71254885Sdumbbell                        ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
72254885Sdumbbell
73254885Sdumbbell        if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
74254885Sdumbbell            return ERROR_CODE(ans);
75254885Sdumbbell    }
76254885Sdumbbell    else
77254885Sdumbbell    {
78254885Sdumbbell        /****************************************/
79254885Sdumbbell        /*   Rx only                            */
80254885Sdumbbell        /****************************************/
81254885Sdumbbell        if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
82254885Sdumbbell                || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
83254885Sdumbbell        {
84254885Sdumbbell            /* external buffer pools */
85254885Sdumbbell            if (!p_Params->extBufPools.numOfPoolsUsed)
86254885Sdumbbell                RETURN_ERROR(
87254885Sdumbbell                        MAJOR,
88254885Sdumbbell                        E_INVALID_VALUE,
89254885Sdumbbell                        ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
90254885Sdumbbell
91254885Sdumbbell            if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
92254885Sdumbbell                                        p_Params->p_BackupBmPools,
93254885Sdumbbell                                        &p_Params->bufPoolDepletion) != E_OK)
94254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
95254885Sdumbbell
96254885Sdumbbell            /* Check that part of IC that needs copying is small enough to enter start margin */
97254885Sdumbbell            if (p_Params->intContext.size
98254885Sdumbbell                    && (p_Params->intContext.size
99254885Sdumbbell                            + p_Params->intContext.extBufOffset
100254885Sdumbbell                            > p_Params->bufMargins.startMargins))
101254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_VALUE,
102254885Sdumbbell                             ("intContext.size is larger than start margins"));
103254885Sdumbbell
104254885Sdumbbell            if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
105254885Sdumbbell                    && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
106254885Sdumbbell                RETURN_ERROR(
107254885Sdumbbell                        MAJOR,
108254885Sdumbbell                        E_INVALID_VALUE,
109254885Sdumbbell                        ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
110254885Sdumbbell
111254885Sdumbbell#ifdef FM_NO_BACKUP_POOLS
112254885Sdumbbell            if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
113254885Sdumbbell            if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
114254885Sdumbbell            RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
115254885Sdumbbell#endif /* FM_NO_BACKUP_POOLS */
116254885Sdumbbell        }
117254885Sdumbbell
118254885Sdumbbell        /****************************************/
119254885Sdumbbell        /*   Non Rx ports                       */
120254885Sdumbbell        /****************************************/
121254885Sdumbbell        else
122254885Sdumbbell        {
123254885Sdumbbell            if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
124254885Sdumbbell                RETURN_ERROR(
125254885Sdumbbell                        MAJOR,
126254885Sdumbbell                        E_INVALID_VALUE,
127254885Sdumbbell                        (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
128254885Sdumbbell
129254885Sdumbbell            /* to protect HW internal-context from overwrite */
130254885Sdumbbell            if ((p_Params->intContext.size)
131254885Sdumbbell                    && (p_Params->intContext.intContextOffset
132254885Sdumbbell                            < MIN_TX_INT_OFFSET))
133254885Sdumbbell                RETURN_ERROR(
134254885Sdumbbell                        MAJOR,
135254885Sdumbbell                        E_INVALID_VALUE,
136254885Sdumbbell                        ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
137254885Sdumbbell
138254885Sdumbbell            if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
139254885Sdumbbell                    || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
140254885Sdumbbell                    /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
141254885Sdumbbell                    || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
142254885Sdumbbell                            != DEFAULT_notSupported))
143254885Sdumbbell            {
144254885Sdumbbell                /* Check that not larger than 8 */
145254885Sdumbbell                if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
146254885Sdumbbell                        || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
147254885Sdumbbell                                > MAX_FIFO_PIPELINE_DEPTH))
148254885Sdumbbell                    RETURN_ERROR(
149254885Sdumbbell                            MAJOR,
150254885Sdumbbell                            E_INVALID_VALUE,
151254885Sdumbbell                            ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
152254885Sdumbbell            }
153254885Sdumbbell        }
154254885Sdumbbell
155254885Sdumbbell        /****************************************/
156254885Sdumbbell        /*   Rx Or Offline Parsing              */
157254885Sdumbbell        /****************************************/
158254885Sdumbbell        if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
159254885Sdumbbell                || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
160254885Sdumbbell                || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
161254885Sdumbbell        {
162254885Sdumbbell            if (!p_Params->dfltFqid)
163254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_VALUE,
164254885Sdumbbell                             ("dfltFqid must be between 1 and 2^24-1"));
165254885Sdumbbell#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
166254885Sdumbbell            if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
167254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
168254885Sdumbbell#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
169254885Sdumbbell        }
170254885Sdumbbell
171254885Sdumbbell        /****************************************/
172254885Sdumbbell        /*   All ports                          */
173254885Sdumbbell        /****************************************/
174254885Sdumbbell        /* common BMI registers values */
175254885Sdumbbell        /* Check that Queue Id is not larger than 2^24, and is not 0 */
176254885Sdumbbell        if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
177254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE,
178254885Sdumbbell                         ("errFqid must be between 1 and 2^24-1"));
179254885Sdumbbell        if (p_Params->dfltFqid & ~0x00FFFFFF)
180254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE,
181254885Sdumbbell                         ("dfltFqid must be between 1 and 2^24-1"));
182254885Sdumbbell    }
183254885Sdumbbell
184254885Sdumbbell    /****************************************/
185254885Sdumbbell    /*   Rx only                            */
186254885Sdumbbell    /****************************************/
187254885Sdumbbell    if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
188254885Sdumbbell            || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
189254885Sdumbbell    {
190254885Sdumbbell        if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
191254885Sdumbbell            RETURN_ERROR(
192254885Sdumbbell                    MAJOR,
193254885Sdumbbell                    E_INVALID_VALUE,
194254885Sdumbbell                    ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
195254885Sdumbbell        if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
196254885Sdumbbell                || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
197254885Sdumbbell            RETURN_ERROR(
198254885Sdumbbell                    MAJOR,
199254885Sdumbbell                    E_INVALID_VALUE,
200254885Sdumbbell                    ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
201254885Sdumbbell        if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
202254885Sdumbbell            RETURN_ERROR(
203254885Sdumbbell                    MAJOR,
204254885Sdumbbell                    E_INVALID_VALUE,
205254885Sdumbbell                    ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
206254885Sdumbbell        if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
207254885Sdumbbell                || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
208254885Sdumbbell            RETURN_ERROR(
209254885Sdumbbell                    MAJOR,
210254885Sdumbbell                    E_INVALID_VALUE,
211254885Sdumbbell                    ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
212254885Sdumbbell
213254885Sdumbbell        /* Check that not larger than 16 */
214254885Sdumbbell        if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
215254885Sdumbbell            RETURN_ERROR(
216254885Sdumbbell                    MAJOR,
217254885Sdumbbell                    E_INVALID_VALUE,
218254885Sdumbbell                    ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
219254885Sdumbbell
220254885Sdumbbell        if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
221254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
222254885Sdumbbell
223254885Sdumbbell        /* extra FIFO size (allowed only to Rx ports) */
224254885Sdumbbell        if (p_Params->setSizeOfFifo
225254885Sdumbbell                && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
226254885Sdumbbell            RETURN_ERROR(
227254885Sdumbbell                    MAJOR,
228254885Sdumbbell                    E_INVALID_VALUE,
229254885Sdumbbell                    ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
230254885Sdumbbell
231254885Sdumbbell        if (p_Params->bufPoolDepletion.poolsGrpModeEnable
232254885Sdumbbell                && !p_Params->bufPoolDepletion.numOfPools)
233254885Sdumbbell            RETURN_ERROR(
234254885Sdumbbell                    MAJOR,
235254885Sdumbbell                    E_INVALID_VALUE,
236254885Sdumbbell                    ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
237254885Sdumbbell#ifdef FM_CSI_CFED_LIMIT
238254885Sdumbbell        if (p_FmPort->fmRevInfo.majorRev == 4)
239254885Sdumbbell        {
240254885Sdumbbell            /* Check that not larger than 16 */
241254885Sdumbbell            if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
242254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
243254885Sdumbbell        }
244254885Sdumbbell#endif /* FM_CSI_CFED_LIMIT */
245254885Sdumbbell    }
246254885Sdumbbell
247254885Sdumbbell    /****************************************/
248254885Sdumbbell    /*   Non Rx ports                       */
249254885Sdumbbell    /****************************************/
250254885Sdumbbell    /* extra FIFO size (allowed only to Rx ports) */
251254885Sdumbbell    else
252254885Sdumbbell        if (p_FmPort->fifoBufs.extra)
253254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE,
254254885Sdumbbell                         (" No fifoBufs.extra for non Rx ports"));
255254885Sdumbbell
256254885Sdumbbell    /****************************************/
257254885Sdumbbell    /*   Tx only                            */
258254885Sdumbbell    /****************************************/
259254885Sdumbbell    if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
260254885Sdumbbell            || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
261254885Sdumbbell    {
262254885Sdumbbell        if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
263254885Sdumbbell            RETURN_ERROR(
264254885Sdumbbell                    MAJOR,
265254885Sdumbbell                    E_INVALID_VALUE,
266254885Sdumbbell                    ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
267254885Sdumbbell        if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
268254885Sdumbbell            RETURN_ERROR(
269254885Sdumbbell                    MAJOR,
270254885Sdumbbell                    E_INVALID_VALUE,
271254885Sdumbbell                    ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
272254885Sdumbbell        if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
273254885Sdumbbell            RETURN_ERROR(
274254885Sdumbbell                    MAJOR,
275254885Sdumbbell                    E_INVALID_VALUE,
276254885Sdumbbell                    ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
277254885Sdumbbell        if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
278254885Sdumbbell                || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
279254885Sdumbbell            RETURN_ERROR(
280254885Sdumbbell                    MAJOR,
281254885Sdumbbell                    E_INVALID_VALUE,
282254885Sdumbbell                    ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
283254885Sdumbbell
284254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
285254885Sdumbbell            if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
286254885Sdumbbell                    > 2)
287254885Sdumbbell                RETURN_ERROR(
288254885Sdumbbell                        MAJOR, E_INVALID_VALUE,
289254885Sdumbbell                        ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
290254885Sdumbbell    }
291254885Sdumbbell
292254885Sdumbbell    /****************************************/
293254885Sdumbbell    /*   Non Tx Ports                       */
294254885Sdumbbell    /****************************************/
295254885Sdumbbell    /* If discard override was selected , no frames may be discarded. */
296254885Sdumbbell    else
297254885Sdumbbell        if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
298254885Sdumbbell            RETURN_ERROR(
299254885Sdumbbell                    MAJOR,
300254885Sdumbbell                    E_CONFLICT,
301254885Sdumbbell                    ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
302254885Sdumbbell
303254885Sdumbbell    /****************************************/
304254885Sdumbbell    /*   Rx and Offline parsing             */
305254885Sdumbbell    /****************************************/
306254885Sdumbbell    if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
307254885Sdumbbell            || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
308254885Sdumbbell            || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
309254885Sdumbbell    {
310254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
311254885Sdumbbell            unusedMask = BMI_STATUS_OP_MASK_UNUSED;
312254885Sdumbbell        else
313254885Sdumbbell            unusedMask = BMI_STATUS_RX_MASK_UNUSED;
314254885Sdumbbell
315254885Sdumbbell        /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
316254885Sdumbbell        if (p_Params->errorsToDiscard & unusedMask)
317254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
318254885Sdumbbell                         ("errorsToDiscard contains undefined bits"));
319254885Sdumbbell    }
320254885Sdumbbell
321254885Sdumbbell    /****************************************/
322254885Sdumbbell    /*   Offline Ports                      */
323254885Sdumbbell    /****************************************/
324254885Sdumbbell#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
325254885Sdumbbell    if ((p_FmPort->fmRevInfo.majorRev >= 6)
326254885Sdumbbell            && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
327254885Sdumbbell            && p_Params->setNumOfOpenDmas
328254885Sdumbbell            && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
329254885Sdumbbell        RETURN_ERROR(
330254885Sdumbbell                MAJOR,
331254885Sdumbbell                E_INVALID_VALUE,
332254885Sdumbbell                ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
333254885Sdumbbell#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
334254885Sdumbbell
335254885Sdumbbell    /****************************************/
336254885Sdumbbell    /*   Offline & HC Ports                 */
337254885Sdumbbell    /****************************************/
338254885Sdumbbell    if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
339254885Sdumbbell            || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
340254885Sdumbbell    {
341254885Sdumbbell#ifndef FM_FRAME_END_PARAMS_FOR_OP
342254885Sdumbbell        if ((p_FmPort->fmRevInfo.majorRev < 6) &&
343254885Sdumbbell                (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
344254885Sdumbbell        /* this is an indication that user called config for this mode which is not supported in this integration */
345254885Sdumbbell        RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
346254885Sdumbbell#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
347254885Sdumbbell
348254885Sdumbbell#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
349254885Sdumbbell        if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
350254885Sdumbbell                                (p_FmPort->fmRevInfo.majorRev >= 6))) &&
351254885Sdumbbell                (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
352254885Sdumbbell        /* this is an indication that user called config for this mode which is not supported in this integration */
353254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
354254885Sdumbbell#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
355254885Sdumbbell    }
356254885Sdumbbell
357254885Sdumbbell    /****************************************/
358254885Sdumbbell    /*   All ports                          */
359254885Sdumbbell    /****************************************/
360254885Sdumbbell    /* Check that not larger than 16 */
361254885Sdumbbell    if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
362254885Sdumbbell            && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
363254885Sdumbbell        RETURN_ERROR(
364254885Sdumbbell                MAJOR,
365254885Sdumbbell                E_INVALID_VALUE,
366254885Sdumbbell                ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
367254885Sdumbbell
368254885Sdumbbell    if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
369254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
370254885Sdumbbell
371254885Sdumbbell    /* common BMI registers values */
372254885Sdumbbell    if (p_Params->setNumOfTasks
373254885Sdumbbell            && ((!p_FmPort->tasks.num)
374254885Sdumbbell                    || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
375254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_VALUE,
376254885Sdumbbell                     ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
377254885Sdumbbell    if (p_Params->setNumOfTasks
378254885Sdumbbell            && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
379254885Sdumbbell        RETURN_ERROR(
380254885Sdumbbell                MAJOR,
381254885Sdumbbell                E_INVALID_VALUE,
382254885Sdumbbell                ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
383254885Sdumbbell    if (p_Params->setNumOfOpenDmas
384254885Sdumbbell            && ((!p_FmPort->openDmas.num)
385254885Sdumbbell                    || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
386254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_VALUE,
387254885Sdumbbell                     ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
388254885Sdumbbell    if (p_Params->setNumOfOpenDmas
389254885Sdumbbell            && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
390254885Sdumbbell        RETURN_ERROR(
391254885Sdumbbell                MAJOR,
392254885Sdumbbell                E_INVALID_VALUE,
393254885Sdumbbell                ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
394254885Sdumbbell    if (p_Params->setSizeOfFifo
395254885Sdumbbell            && (!p_FmPort->fifoBufs.num
396254885Sdumbbell                    || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
397254885Sdumbbell        RETURN_ERROR(
398254885Sdumbbell                MAJOR,
399254885Sdumbbell                E_INVALID_VALUE,
400254885Sdumbbell                ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
401254885Sdumbbell    if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
402254885Sdumbbell        RETURN_ERROR(
403254885Sdumbbell                MAJOR, E_INVALID_VALUE,
404254885Sdumbbell                ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
405254885Sdumbbell
406254885Sdumbbell#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
407254885Sdumbbell    if (p_FmPort->fmRevInfo.majorRev == 4)
408254885Sdumbbell    if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
409254885Sdumbbell    /* this is an indication that user called config for this mode which is not supported in this integration */
410254885Sdumbbell    RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
411254885Sdumbbell#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
412254885Sdumbbell
413254885Sdumbbell    return E_OK;
414254885Sdumbbell}
415254885Sdumbbell
416254885Sdumbbellstatic t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
417254885Sdumbbell{
418254885Sdumbbell    uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
419254885Sdumbbell
420254885Sdumbbell    /*************************/
421254885Sdumbbell    /*    TX PORTS           */
422254885Sdumbbell    /*************************/
423254885Sdumbbell    if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
424254885Sdumbbell            || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
425254885Sdumbbell    {
426254885Sdumbbell        minFifoSizeRequired =
427254885Sdumbbell                (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
428254885Sdumbbell                        + (3 * BMI_FIFO_UNITS));
429254885Sdumbbell        if (!p_FmPort->imEn)
430254885Sdumbbell            minFifoSizeRequired +=
431254885Sdumbbell                    p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
432254885Sdumbbell                            * BMI_FIFO_UNITS;
433254885Sdumbbell
434254885Sdumbbell        optFifoSizeForB2B = minFifoSizeRequired;
435254885Sdumbbell
436254885Sdumbbell        /* Add some margin for back-to-back capability to improve performance,
437254885Sdumbbell         allows the hardware to pipeline new frame dma while the previous
438254885Sdumbbell         frame not yet transmitted. */
439254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
440254885Sdumbbell            optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
441254885Sdumbbell        else
442254885Sdumbbell            optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
443254885Sdumbbell    }
444254885Sdumbbell
445254885Sdumbbell    /*************************/
446254885Sdumbbell    /*    RX IM PORTS        */
447254885Sdumbbell    /*************************/
448254885Sdumbbell    else
449254885Sdumbbell        if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
450254885Sdumbbell                || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
451254885Sdumbbell                && p_FmPort->imEn)
452254885Sdumbbell        {
453254885Sdumbbell            optFifoSizeForB2B =
454254885Sdumbbell                    minFifoSizeRequired =
455254885Sdumbbell                            (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
456254885Sdumbbell                                    + (4 * BMI_FIFO_UNITS));
457254885Sdumbbell        }
458254885Sdumbbell
459254885Sdumbbell        /*************************/
460254885Sdumbbell        /*    RX non-IM PORTS    */
461254885Sdumbbell        /*************************/
462254885Sdumbbell        else
463254885Sdumbbell            if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
464254885Sdumbbell                    || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
465254885Sdumbbell                    && !p_FmPort->imEn)
466254885Sdumbbell            {
467254885Sdumbbell                if (p_FmPort->fmRevInfo.majorRev == 4)
468254885Sdumbbell                {
469254885Sdumbbell                    if (p_FmPort->rxPoolsParams.numOfPools == 1)
470254885Sdumbbell                        minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
471254885Sdumbbell                    else
472254885Sdumbbell                        minFifoSizeRequired =
473254885Sdumbbell                                (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
474254885Sdumbbell                                        + (7 * BMI_FIFO_UNITS));
475254885Sdumbbell                }
476254885Sdumbbell                else
477254885Sdumbbell                {
478254885Sdumbbell#if (DPAA_VERSION >= 11)
479254885Sdumbbell                    minFifoSizeRequired =
480254885Sdumbbell                            (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
481254885Sdumbbell                                    + (5 * BMI_FIFO_UNITS));
482254885Sdumbbell                    /* 4 according to spec + 1 for FOF>0 */
483254885Sdumbbell#else
484254885Sdumbbell                    minFifoSizeRequired = (uint32_t)
485254885Sdumbbell                    (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
486254885Sdumbbell                            + (7*BMI_FIFO_UNITS));
487254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */
488254885Sdumbbell                }
489254885Sdumbbell
490254885Sdumbbell                optFifoSizeForB2B = minFifoSizeRequired;
491254885Sdumbbell
492254885Sdumbbell                /* Add some margin for back-to-back capability to improve performance,
493254885Sdumbbell                 allows the hardware to pipeline new frame dma while the previous
494254885Sdumbbell                 frame not yet transmitted. */
495254885Sdumbbell                if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
496254885Sdumbbell                    optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
497254885Sdumbbell                else
498254885Sdumbbell                    optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
499254885Sdumbbell            }
500254885Sdumbbell
501254885Sdumbbell            /* For O/H ports, check fifo size and update if necessary */
502254885Sdumbbell            else
503254885Sdumbbell                if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
504254885Sdumbbell                        || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
505254885Sdumbbell                {
506254885Sdumbbell#if (DPAA_VERSION >= 11)
507254885Sdumbbell                    optFifoSizeForB2B =
508254885Sdumbbell                            minFifoSizeRequired =
509254885Sdumbbell                                    (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
510254885Sdumbbell                                            + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
511254885Sdumbbell                                                    + 5) * BMI_FIFO_UNITS));
512254885Sdumbbell                    /* 4 according to spec + 1 for FOF>0 */
513254885Sdumbbell#else
514254885Sdumbbell                    optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
515254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */
516254885Sdumbbell                }
517254885Sdumbbell
518254885Sdumbbell    ASSERT_COND(minFifoSizeRequired > 0);
519254885Sdumbbell    ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
520254885Sdumbbell
521254885Sdumbbell    /* Verify the size  */
522254885Sdumbbell    if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
523254885Sdumbbell        DBG(INFO,
524254885Sdumbbell           ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
525254885Sdumbbell    else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
526254885Sdumbbell        DBG(INFO,
527254885Sdumbbell	    ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
528254885Sdumbbell
529254885Sdumbbell    return E_OK;
530254885Sdumbbell}
531254885Sdumbbell
532254885Sdumbbellstatic void FmPortDriverParamFree(t_FmPort *p_FmPort)
533254885Sdumbbell{
534254885Sdumbbell    if (p_FmPort->p_FmPortDriverParam)
535254885Sdumbbell    {
536254885Sdumbbell        XX_Free(p_FmPort->p_FmPortDriverParam);
537254885Sdumbbell        p_FmPort->p_FmPortDriverParam = NULL;
538254885Sdumbbell    }
539254885Sdumbbell}
540254885Sdumbbell
541254885Sdumbbellstatic t_Error SetExtBufferPools(t_FmPort *p_FmPort)
542254885Sdumbbell{
543254885Sdumbbell    t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
544254885Sdumbbell    t_FmBufPoolDepletion *p_BufPoolDepletion =
545254885Sdumbbell            &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
546254885Sdumbbell    uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
547254885Sdumbbell    uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
548254885Sdumbbell    int i = 0, j = 0, err;
549254885Sdumbbell    struct fman_port_bpools bpools;
550254885Sdumbbell
551254885Sdumbbell    memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
552254885Sdumbbell    memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
553254885Sdumbbell    memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
554254885Sdumbbell
555254885Sdumbbell    FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
556254885Sdumbbell                                        sizesArray);
557254885Sdumbbell
558254885Sdumbbell    /* Prepare flibs bpools structure */
559254885Sdumbbell    memset(&bpools, 0, sizeof(struct fman_port_bpools));
560254885Sdumbbell    bpools.count = p_ExtBufPools->numOfPoolsUsed;
561254885Sdumbbell    bpools.counters_enable = TRUE;
562254885Sdumbbell    for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
563254885Sdumbbell    {
564254885Sdumbbell        bpools.bpool[i].bpid = orderedArray[i];
565254885Sdumbbell        bpools.bpool[i].size = sizesArray[orderedArray[i]];
566254885Sdumbbell        /* functionality available only for some derivatives (limited by config) */
567254885Sdumbbell        if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
568254885Sdumbbell            for (j = 0;
569254885Sdumbbell                    j
570254885Sdumbbell                            < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
571254885Sdumbbell                    j++)
572254885Sdumbbell                if (orderedArray[i]
573254885Sdumbbell                        == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
574254885Sdumbbell                {
575254885Sdumbbell                    bpools.bpool[i].is_backup = TRUE;
576254885Sdumbbell                    break;
577254885Sdumbbell                }
578254885Sdumbbell    }
579254885Sdumbbell
580254885Sdumbbell    /* save pools parameters for later use */
581254885Sdumbbell    p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
582254885Sdumbbell    p_FmPort->rxPoolsParams.largestBufSize =
583254885Sdumbbell            sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
584254885Sdumbbell    p_FmPort->rxPoolsParams.secondLargestBufSize =
585254885Sdumbbell            sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
586254885Sdumbbell
587254885Sdumbbell    /* FMBM_RMPD reg. - pool depletion */
588254885Sdumbbell    if (p_BufPoolDepletion->poolsGrpModeEnable)
589254885Sdumbbell    {
590254885Sdumbbell        bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
591254885Sdumbbell        for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
592254885Sdumbbell        {
593254885Sdumbbell            if (p_BufPoolDepletion->poolsToConsider[i])
594254885Sdumbbell            {
595254885Sdumbbell                for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
596254885Sdumbbell                {
597254885Sdumbbell                    if (i == orderedArray[j])
598254885Sdumbbell                    {
599254885Sdumbbell                        bpools.bpool[j].grp_bp_depleted = TRUE;
600254885Sdumbbell                        break;
601254885Sdumbbell                    }
602254885Sdumbbell                }
603254885Sdumbbell            }
604254885Sdumbbell        }
605254885Sdumbbell    }
606254885Sdumbbell
607254885Sdumbbell    if (p_BufPoolDepletion->singlePoolModeEnable)
608254885Sdumbbell    {
609254885Sdumbbell        for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
610254885Sdumbbell        {
611254885Sdumbbell            if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
612254885Sdumbbell            {
613254885Sdumbbell                for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
614254885Sdumbbell                {
615254885Sdumbbell                    if (i == orderedArray[j])
616254885Sdumbbell                    {
617254885Sdumbbell                        bpools.bpool[j].single_bp_depleted = TRUE;
618254885Sdumbbell                        break;
619254885Sdumbbell                    }
620254885Sdumbbell                }
621254885Sdumbbell            }
622254885Sdumbbell        }
623254885Sdumbbell    }
624254885Sdumbbell
625254885Sdumbbell#if (DPAA_VERSION >= 11)
626254885Sdumbbell    /* fill QbbPEV */
627254885Sdumbbell    if (p_BufPoolDepletion->poolsGrpModeEnable
628254885Sdumbbell            || p_BufPoolDepletion->singlePoolModeEnable)
629254885Sdumbbell    {
630254885Sdumbbell        for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
631254885Sdumbbell        {
632254885Sdumbbell            if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
633254885Sdumbbell            {
634254885Sdumbbell                bpools.bpool[i].pfc_priorities_en = TRUE;
635254885Sdumbbell            }
636254885Sdumbbell        }
637254885Sdumbbell    }
638254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */
639254885Sdumbbell
640254885Sdumbbell    /* Issue flibs function */
641254885Sdumbbell    err = fman_port_set_bpools(&p_FmPort->port, &bpools);
642254885Sdumbbell    if (err != 0)
643254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
644254885Sdumbbell
645254885Sdumbbell    if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
646254885Sdumbbell        XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
647254885Sdumbbell
648254885Sdumbbell    return E_OK;
649254885Sdumbbell}
650254885Sdumbbell
651254885Sdumbbellstatic t_Error ClearPerfCnts(t_FmPort *p_FmPort)
652254885Sdumbbell{
653254885Sdumbbell    if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
654254885Sdumbbell        FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
655254885Sdumbbell    FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
656254885Sdumbbell    FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
657254885Sdumbbell    FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
658254885Sdumbbell    return E_OK;
659254885Sdumbbell}
660254885Sdumbbell
661254885Sdumbbellstatic t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
662254885Sdumbbell{
663254885Sdumbbell    t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
664254885Sdumbbell    struct fman_port_params portParams;
665254885Sdumbbell    uint32_t tmpVal;
666254885Sdumbbell    t_Error err;
667254885Sdumbbell
668254885Sdumbbell    /* Set up flibs parameters and issue init function */
669254885Sdumbbell
670254885Sdumbbell    memset(&portParams, 0, sizeof(struct fman_port_params));
671254885Sdumbbell    portParams.discard_mask = p_DriverParams->errorsToDiscard;
672254885Sdumbbell    portParams.dflt_fqid = p_DriverParams->dfltFqid;
673254885Sdumbbell    portParams.err_fqid = p_DriverParams->errFqid;
674254885Sdumbbell    portParams.deq_sp = p_DriverParams->deqSubPortal;
675254885Sdumbbell    portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
676254885Sdumbbell    switch (p_FmPort->portType)
677254885Sdumbbell    {
678254885Sdumbbell        case (e_FM_PORT_TYPE_RX_10G):
679254885Sdumbbell        case (e_FM_PORT_TYPE_RX):
680254885Sdumbbell            portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
681254885Sdumbbell            if (!p_FmPort->imEn)
682254885Sdumbbell            {
683254885Sdumbbell                if (p_DriverParams->forwardReuseIntContext)
684254885Sdumbbell                    p_DriverParams->dfltCfg.rx_fd_bits =
685254885Sdumbbell                            (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
686254885Sdumbbell            }
687254885Sdumbbell            break;
688254885Sdumbbell
689254885Sdumbbell        case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
690254885Sdumbbell            portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
691254885Sdumbbell            break;
692254885Sdumbbell            break;
693254885Sdumbbell
694254885Sdumbbell        default:
695254885Sdumbbell            break;
696254885Sdumbbell    }
697254885Sdumbbell
698254885Sdumbbell    tmpVal =
699254885Sdumbbell            (uint32_t)(
700254885Sdumbbell                    (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
701254885Sdumbbell                            / OFFSET_UNITS + 1) :
702254885Sdumbbell                            (p_FmPort->internalBufferOffset / OFFSET_UNITS));
703254885Sdumbbell    p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
704254885Sdumbbell    p_DriverParams->dfltCfg.int_buf_start_margin =
705254885Sdumbbell            p_FmPort->internalBufferOffset;
706254885Sdumbbell
707254885Sdumbbell    p_DriverParams->dfltCfg.ext_buf_start_margin =
708254885Sdumbbell            p_DriverParams->bufMargins.startMargins;
709254885Sdumbbell    p_DriverParams->dfltCfg.ext_buf_end_margin =
710254885Sdumbbell            p_DriverParams->bufMargins.endMargins;
711254885Sdumbbell
712254885Sdumbbell    p_DriverParams->dfltCfg.ic_ext_offset =
713254885Sdumbbell            p_DriverParams->intContext.extBufOffset;
714254885Sdumbbell    p_DriverParams->dfltCfg.ic_int_offset =
715254885Sdumbbell            p_DriverParams->intContext.intContextOffset;
716254885Sdumbbell    p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
717254885Sdumbbell
718254885Sdumbbell    p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
719254885Sdumbbell    p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
720254885Sdumbbell    p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
721254885Sdumbbell
722254885Sdumbbell    p_DriverParams->dfltCfg.perf_cnt_params.task_val =
723254885Sdumbbell            (uint8_t)p_FmPort->tasks.num;
724254885Sdumbbell    if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
725254885Sdumbbell    p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
726254885Sdumbbell    else
727254885Sdumbbell    p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
728254885Sdumbbell    p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
729254885Sdumbbell            (uint8_t)p_FmPort->openDmas.num;
730254885Sdumbbell    p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
731254885Sdumbbell
732254885Sdumbbell    if (0
733254885Sdumbbell            != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
734254885Sdumbbell                              &portParams))
735254885Sdumbbell        RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
736254885Sdumbbell
737254885Sdumbbell    if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
738254885Sdumbbell        RETURN_ERROR(MAJOR, err, NO_MSG);
739254885Sdumbbell    else
740254885Sdumbbell    {
741254885Sdumbbell        //  from QMIInit
742254885Sdumbbell        if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
743254885Sdumbbell                && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
744254885Sdumbbell        {
745254885Sdumbbell            if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
746254885Sdumbbell                FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
747254885Sdumbbell                                               FALSE);
748254885Sdumbbell            else
749254885Sdumbbell                FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
750254885Sdumbbell                                               TRUE);
751254885Sdumbbell        }
752254885Sdumbbell    }
753254885Sdumbbell    /* The code bellow is a trick so the FM will not release the buffer
754254885Sdumbbell     to BM nor will try to enqueue the frame to QM */
755254885Sdumbbell    if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
756254885Sdumbbell            || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
757254885Sdumbbell    {
758254885Sdumbbell        if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
759254885Sdumbbell        {
760254885Sdumbbell            /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
761254885Sdumbbell             * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
762254885Sdumbbell             * buffers to BM regardless of fmbm_tfene
763254885Sdumbbell             */
764254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
765254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
766254885Sdumbbell                         NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
767254885Sdumbbell        }
768254885Sdumbbell    }
769254885Sdumbbell
770254885Sdumbbell    return E_OK;
771254885Sdumbbell}
772254885Sdumbbell
773254885Sdumbbellstatic bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
774254885Sdumbbell{
775254885Sdumbbell    UNUSED(p_FmPort);
776254885Sdumbbell
777254885Sdumbbell    switch (counter)
778254885Sdumbbell    {
779254885Sdumbbell        case (e_FM_PORT_COUNTERS_CYCLE):
780254885Sdumbbell        case (e_FM_PORT_COUNTERS_TASK_UTIL):
781254885Sdumbbell        case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
782254885Sdumbbell        case (e_FM_PORT_COUNTERS_DMA_UTIL):
783254885Sdumbbell        case (e_FM_PORT_COUNTERS_FIFO_UTIL):
784254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
785254885Sdumbbell        case (e_FM_PORT_COUNTERS_FRAME):
786254885Sdumbbell        case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
787254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
788254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
789254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
790254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
791254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
792254885Sdumbbell        case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
793254885Sdumbbell        case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
794254885Sdumbbell            return TRUE;
795254885Sdumbbell        default:
796254885Sdumbbell            return FALSE;
797254885Sdumbbell    }
798254885Sdumbbell}
799254885Sdumbbell
800254885Sdumbbellstatic bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
801254885Sdumbbell{
802254885Sdumbbell    UNUSED(p_FmPort);
803254885Sdumbbell
804254885Sdumbbell    switch (counter)
805254885Sdumbbell    {
806254885Sdumbbell        case (e_FM_PORT_COUNTERS_CYCLE):
807254885Sdumbbell        case (e_FM_PORT_COUNTERS_TASK_UTIL):
808254885Sdumbbell        case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
809254885Sdumbbell        case (e_FM_PORT_COUNTERS_DMA_UTIL):
810254885Sdumbbell        case (e_FM_PORT_COUNTERS_FIFO_UTIL):
811254885Sdumbbell        case (e_FM_PORT_COUNTERS_FRAME):
812254885Sdumbbell        case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
813254885Sdumbbell        case (e_FM_PORT_COUNTERS_LENGTH_ERR):
814254885Sdumbbell        case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
815254885Sdumbbell        case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
816254885Sdumbbell            return TRUE;
817254885Sdumbbell        default:
818254885Sdumbbell            return FALSE;
819254885Sdumbbell    }
820254885Sdumbbell}
821254885Sdumbbell
822254885Sdumbbellstatic bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
823254885Sdumbbell{
824254885Sdumbbell    switch (counter)
825254885Sdumbbell    {
826254885Sdumbbell        case (e_FM_PORT_COUNTERS_CYCLE):
827254885Sdumbbell        case (e_FM_PORT_COUNTERS_TASK_UTIL):
828254885Sdumbbell        case (e_FM_PORT_COUNTERS_DMA_UTIL):
829254885Sdumbbell        case (e_FM_PORT_COUNTERS_FIFO_UTIL):
830254885Sdumbbell        case (e_FM_PORT_COUNTERS_FRAME):
831254885Sdumbbell        case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
832254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
833254885Sdumbbell        case (e_FM_PORT_COUNTERS_WRED_DISCARD):
834254885Sdumbbell        case (e_FM_PORT_COUNTERS_LENGTH_ERR):
835254885Sdumbbell        case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
836254885Sdumbbell        case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
837254885Sdumbbell            return TRUE;
838254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
839254885Sdumbbell            if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
840254885Sdumbbell                return FALSE;
841254885Sdumbbell            else
842254885Sdumbbell                return TRUE;
843254885Sdumbbell        default:
844254885Sdumbbell            return FALSE;
845254885Sdumbbell    }
846254885Sdumbbell}
847254885Sdumbbell
848254885Sdumbbellstatic t_Error BmiPortCheckAndGetCounterType(
849254885Sdumbbell        t_FmPort *p_FmPort, e_FmPortCounters counter,
850254885Sdumbbell        enum fman_port_stats_counters *p_StatsType,
851254885Sdumbbell        enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
852254885Sdumbbell{
853254885Sdumbbell    volatile uint32_t *p_Reg;
854254885Sdumbbell    bool isValid;
855254885Sdumbbell
856254885Sdumbbell    switch (p_FmPort->portType)
857254885Sdumbbell    {
858254885Sdumbbell        case (e_FM_PORT_TYPE_RX_10G):
859254885Sdumbbell        case (e_FM_PORT_TYPE_RX):
860254885Sdumbbell            p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
861254885Sdumbbell            isValid = CheckRxBmiCounter(p_FmPort, counter);
862254885Sdumbbell            break;
863254885Sdumbbell        case (e_FM_PORT_TYPE_TX_10G):
864254885Sdumbbell        case (e_FM_PORT_TYPE_TX):
865254885Sdumbbell            p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
866254885Sdumbbell            isValid = CheckTxBmiCounter(p_FmPort, counter);
867254885Sdumbbell            break;
868254885Sdumbbell        case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
869254885Sdumbbell        case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
870254885Sdumbbell            p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
871254885Sdumbbell            isValid = CheckOhBmiCounter(p_FmPort, counter);
872254885Sdumbbell            break;
873254885Sdumbbell        default:
874254885Sdumbbell            RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
875254885Sdumbbell    }
876254885Sdumbbell
877254885Sdumbbell    if (!isValid)
878254885Sdumbbell        RETURN_ERROR(MINOR, E_INVALID_STATE,
879254885Sdumbbell                     ("Requested counter is not available for this port type"));
880254885Sdumbbell
881254885Sdumbbell    /* check that counters are enabled */
882254885Sdumbbell    switch (counter)
883254885Sdumbbell    {
884254885Sdumbbell        case (e_FM_PORT_COUNTERS_CYCLE):
885254885Sdumbbell        case (e_FM_PORT_COUNTERS_TASK_UTIL):
886254885Sdumbbell        case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
887254885Sdumbbell        case (e_FM_PORT_COUNTERS_DMA_UTIL):
888254885Sdumbbell        case (e_FM_PORT_COUNTERS_FIFO_UTIL):
889254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
890254885Sdumbbell            /* performance counters - may be read when disabled */
891254885Sdumbbell            *p_IsStats = FALSE;
892254885Sdumbbell            break;
893254885Sdumbbell        case (e_FM_PORT_COUNTERS_FRAME):
894254885Sdumbbell        case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
895254885Sdumbbell        case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
896254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
897254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
898254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
899254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
900254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
901254885Sdumbbell        case (e_FM_PORT_COUNTERS_LENGTH_ERR):
902254885Sdumbbell        case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
903254885Sdumbbell        case (e_FM_PORT_COUNTERS_WRED_DISCARD):
904254885Sdumbbell            *p_IsStats = TRUE;
905254885Sdumbbell            if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
906254885Sdumbbell                RETURN_ERROR(MINOR, E_INVALID_STATE,
907254885Sdumbbell                             ("Requested counter was not enabled"));
908254885Sdumbbell            break;
909254885Sdumbbell        default:
910254885Sdumbbell            break;
911254885Sdumbbell    }
912254885Sdumbbell
913254885Sdumbbell    /* Set counter */
914254885Sdumbbell    switch (counter)
915254885Sdumbbell    {
916254885Sdumbbell        case (e_FM_PORT_COUNTERS_CYCLE):
917254885Sdumbbell            *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
918254885Sdumbbell            break;
919254885Sdumbbell        case (e_FM_PORT_COUNTERS_TASK_UTIL):
920254885Sdumbbell            *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
921254885Sdumbbell            break;
922254885Sdumbbell        case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
923254885Sdumbbell            *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
924254885Sdumbbell            break;
925254885Sdumbbell        case (e_FM_PORT_COUNTERS_DMA_UTIL):
926254885Sdumbbell            *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
927254885Sdumbbell            break;
928254885Sdumbbell        case (e_FM_PORT_COUNTERS_FIFO_UTIL):
929254885Sdumbbell            *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
930254885Sdumbbell            break;
931254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
932254885Sdumbbell            *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
933254885Sdumbbell            break;
934254885Sdumbbell        case (e_FM_PORT_COUNTERS_FRAME):
935254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
936254885Sdumbbell            break;
937254885Sdumbbell        case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
938254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
939254885Sdumbbell            break;
940254885Sdumbbell        case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
941254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
942254885Sdumbbell            break;
943254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
944254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
945254885Sdumbbell            break;
946254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
947254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
948254885Sdumbbell            break;
949254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
950254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
951254885Sdumbbell            break;
952254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
953254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
954254885Sdumbbell            break;
955254885Sdumbbell        case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
956254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
957254885Sdumbbell            break;
958254885Sdumbbell        case (e_FM_PORT_COUNTERS_WRED_DISCARD):
959254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
960254885Sdumbbell            break;
961254885Sdumbbell        case (e_FM_PORT_COUNTERS_LENGTH_ERR):
962254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
963254885Sdumbbell            break;
964254885Sdumbbell        case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
965254885Sdumbbell            *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
966254885Sdumbbell            break;
967254885Sdumbbell        default:
968254885Sdumbbell            break;
969254885Sdumbbell    }
970254885Sdumbbell
971254885Sdumbbell    return E_OK;
972254885Sdumbbell}
973254885Sdumbbell
974254885Sdumbbellstatic t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
975254885Sdumbbell                                   t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
976254885Sdumbbell                                   uint32_t *p_SoftSeqAttachReg)
977254885Sdumbbell{
978254885Sdumbbell    uint8_t hdrNum, Ipv4HdrNum;
979254885Sdumbbell    u_FmPcdHdrPrsOpts *p_prsOpts;
980254885Sdumbbell    uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
981254885Sdumbbell
982254885Sdumbbell    if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
983254885Sdumbbell            || IS_SPECIAL_HEADER(p_HdrParams->hdr))
984254885Sdumbbell        RETURN_ERROR(
985254885Sdumbbell                MAJOR, E_NOT_SUPPORTED,
986254885Sdumbbell                ("No additional parameters for private or special headers."));
987254885Sdumbbell
988254885Sdumbbell    if (p_HdrParams->errDisable)
989254885Sdumbbell        tmpReg |= PRS_HDR_ERROR_DIS;
990254885Sdumbbell
991254885Sdumbbell    /* Set parser options */
992254885Sdumbbell    if (p_HdrParams->usePrsOpts)
993254885Sdumbbell    {
994254885Sdumbbell        p_prsOpts = &p_HdrParams->prsOpts;
995254885Sdumbbell        switch (p_HdrParams->hdr)
996254885Sdumbbell        {
997254885Sdumbbell            case (HEADER_TYPE_MPLS):
998254885Sdumbbell                if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
999254885Sdumbbell                    tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
1000254885Sdumbbell                hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
1001254885Sdumbbell                if (hdrNum == ILLEGAL_HDR_NUM)
1002254885Sdumbbell                    RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1003254885Sdumbbell                Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1004254885Sdumbbell                if (hdrNum < Ipv4HdrNum)
1005254885Sdumbbell                    RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1006254885Sdumbbell                                 ("Header must be equal or higher than IPv4"));
1007254885Sdumbbell                tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
1008254885Sdumbbell                        << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1009254885Sdumbbell                break;
1010254885Sdumbbell            case (HEADER_TYPE_PPPoE):
1011254885Sdumbbell                if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
1012254885Sdumbbell                    tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
1013254885Sdumbbell                break;
1014254885Sdumbbell            case (HEADER_TYPE_IPv6):
1015254885Sdumbbell                if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
1016254885Sdumbbell                    tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
1017254885Sdumbbell                break;
1018254885Sdumbbell            case (HEADER_TYPE_TCP):
1019254885Sdumbbell                if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
1020254885Sdumbbell                    tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
1021254885Sdumbbell                else
1022254885Sdumbbell                    tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
1023254885Sdumbbell                break;
1024254885Sdumbbell            case (HEADER_TYPE_UDP):
1025254885Sdumbbell                if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
1026254885Sdumbbell                    tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
1027254885Sdumbbell                else
1028254885Sdumbbell                    tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
1029254885Sdumbbell                break;
1030254885Sdumbbell            default:
1031254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
1032254885Sdumbbell        }
1033254885Sdumbbell    }
1034254885Sdumbbell
1035254885Sdumbbell    /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
1036254885Sdumbbell    if (p_HdrParams->swPrsEnable)
1037254885Sdumbbell    {
1038254885Sdumbbell        tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
1039254885Sdumbbell                                           p_HdrParams->indexPerHdr);
1040254885Sdumbbell        if (tmpPrsOffset == ILLEGAL_BASE)
1041254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1042254885Sdumbbell        tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
1043254885Sdumbbell    }
1044254885Sdumbbell    *p_SoftSeqAttachReg = tmpReg;
1045254885Sdumbbell
1046254885Sdumbbell    return E_OK;
1047254885Sdumbbell}
1048254885Sdumbbell
1049254885Sdumbbellstatic uint32_t GetPortSchemeBindParams(
1050254885Sdumbbell        t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
1051254885Sdumbbell{
1052254885Sdumbbell    t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1053254885Sdumbbell    uint32_t walking1Mask = 0x80000000, tmp;
1054254885Sdumbbell    uint8_t idx = 0;
1055254885Sdumbbell
1056254885Sdumbbell    p_SchemeBind->netEnvId = p_FmPort->netEnvId;
1057254885Sdumbbell    p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
1058254885Sdumbbell    p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
1059254885Sdumbbell    p_SchemeBind->numOfSchemes = 0;
1060254885Sdumbbell    tmp = p_FmPort->schemesPerPortVector;
1061254885Sdumbbell    if (tmp)
1062254885Sdumbbell    {
1063254885Sdumbbell        while (tmp)
1064254885Sdumbbell        {
1065254885Sdumbbell            if (tmp & walking1Mask)
1066254885Sdumbbell            {
1067254885Sdumbbell                p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
1068254885Sdumbbell                p_SchemeBind->numOfSchemes++;
1069254885Sdumbbell                tmp &= ~walking1Mask;
1070254885Sdumbbell            }
1071254885Sdumbbell            walking1Mask >>= 1;
1072254885Sdumbbell            idx++;
1073254885Sdumbbell        }
1074254885Sdumbbell    }
1075254885Sdumbbell
1076254885Sdumbbell    return tmp;
1077254885Sdumbbell}
1078254885Sdumbbell
1079254885Sdumbbellstatic void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
1080254885Sdumbbell{
1081254885Sdumbbell    t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1082254885Sdumbbell    volatile uint32_t *p_BmiCfgReg = NULL;
1083254885Sdumbbell    uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
1084254885Sdumbbell    uint32_t lcv, walking1Mask = 0x80000000;
1085254885Sdumbbell    uint8_t cnt = 0;
1086254885Sdumbbell
1087254885Sdumbbell    ASSERT_COND(p_FmPort);
1088254885Sdumbbell    ASSERT_COND(p_FmPort->h_FmPcd);
1089254885Sdumbbell    ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
1090254885Sdumbbell
1091254885Sdumbbell    if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1092254885Sdumbbell            && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
1093254885Sdumbbell        return;
1094254885Sdumbbell
1095254885Sdumbbell    p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
1096254885Sdumbbell    /* get LCV for MACSEC */
1097254885Sdumbbell    if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
1098254885Sdumbbell                    != 0)
1099254885Sdumbbell    {
1100254885Sdumbbell        while (!(lcv & walking1Mask))
1101254885Sdumbbell        {
1102254885Sdumbbell            cnt++;
1103254885Sdumbbell            walking1Mask >>= 1;
1104254885Sdumbbell        }
1105254885Sdumbbell
1106254885Sdumbbell        macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
1107254885Sdumbbell        WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
1108254885Sdumbbell    }
1109254885Sdumbbell}
1110254885Sdumbbell
1111254885Sdumbbellstatic t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
1112254885Sdumbbell{
1113254885Sdumbbell    t_Error err = E_OK;
1114254885Sdumbbell    uint32_t tmpReg;
1115254885Sdumbbell    volatile uint32_t *p_BmiNia = NULL;
1116254885Sdumbbell    volatile uint32_t *p_BmiPrsNia = NULL;
1117254885Sdumbbell    volatile uint32_t *p_BmiPrsStartOffset = NULL;
1118254885Sdumbbell    volatile uint32_t *p_BmiInitPrsResult = NULL;
1119254885Sdumbbell    volatile uint32_t *p_BmiCcBase = NULL;
1120254885Sdumbbell    uint16_t hdrNum, L3HdrNum, greHdrNum;
1121254885Sdumbbell    int i;
1122254885Sdumbbell    bool isEmptyClsPlanGrp;
1123254885Sdumbbell    uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
1124254885Sdumbbell    uint16_t absoluteProfileId;
1125254885Sdumbbell    uint8_t physicalSchemeId;
1126254885Sdumbbell    uint32_t ccTreePhysOffset;
1127254885Sdumbbell    t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1128254885Sdumbbell    uint32_t initialSwPrs = 0;
1129254885Sdumbbell
1130254885Sdumbbell    ASSERT_COND(p_FmPort);
1131254885Sdumbbell    SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1132254885Sdumbbell
1133254885Sdumbbell    if (p_FmPort->imEn)
1134254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1135254885Sdumbbell                     ("available for non-independant mode ports only"));
1136254885Sdumbbell
1137254885Sdumbbell    if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1138254885Sdumbbell            && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1139254885Sdumbbell            && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1140254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1141254885Sdumbbell                     ("available for Rx and offline parsing ports only"));
1142254885Sdumbbell
1143254885Sdumbbell    p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
1144254885Sdumbbell
1145254885Sdumbbell    p_FmPort->pcdEngines = 0;
1146254885Sdumbbell
1147254885Sdumbbell    /* initialize p_FmPort->pcdEngines field in port's structure */
1148254885Sdumbbell    switch (p_PcdParams->pcdSupport)
1149254885Sdumbbell    {
1150254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_NONE):
1151254885Sdumbbell            RETURN_ERROR(
1152254885Sdumbbell                    MAJOR,
1153254885Sdumbbell                    E_INVALID_STATE,
1154254885Sdumbbell                    ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
1155254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1156254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1157254885Sdumbbell            break;
1158254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
1159254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PLCR;
1160254885Sdumbbell            break;
1161254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1162254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1163254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PLCR;
1164254885Sdumbbell            break;
1165254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1166254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1167254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_KG;
1168254885Sdumbbell            break;
1169254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1170254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1171254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_CC;
1172254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_KG;
1173254885Sdumbbell            break;
1174254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1175254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1176254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_KG;
1177254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_CC;
1178254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PLCR;
1179254885Sdumbbell            break;
1180254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1181254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1182254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_CC;
1183254885Sdumbbell            break;
1184254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1185254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1186254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_CC;
1187254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PLCR;
1188254885Sdumbbell            break;
1189254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1190254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PRS;
1191254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_KG;
1192254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PLCR;
1193254885Sdumbbell            break;
1194254885Sdumbbell        case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
1195254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_CC;
1196254885Sdumbbell            break;
1197254885Sdumbbell#ifdef FM_CAPWAP_SUPPORT
1198254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
1199254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_CC;
1200254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_KG;
1201254885Sdumbbell            break;
1202254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
1203254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_CC;
1204254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_KG;
1205254885Sdumbbell            p_FmPort->pcdEngines |= FM_PCD_PLCR;
1206254885Sdumbbell            break;
1207254885Sdumbbell#endif /* FM_CAPWAP_SUPPORT */
1208254885Sdumbbell
1209254885Sdumbbell        default:
1210254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
1211254885Sdumbbell    }
1212254885Sdumbbell
1213254885Sdumbbell    if ((p_FmPort->pcdEngines & FM_PCD_PRS)
1214254885Sdumbbell            && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
1215254885Sdumbbell                    > FM_PCD_PRS_NUM_OF_HDRS))
1216254885Sdumbbell        RETURN_ERROR(
1217254885Sdumbbell                MAJOR,
1218254885Sdumbbell                E_INVALID_VALUE,
1219254885Sdumbbell                ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
1220254885Sdumbbell
1221254885Sdumbbell    /* check that parameters exist for each and only each defined engine */
1222254885Sdumbbell    if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
1223254885Sdumbbell            || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
1224254885Sdumbbell                    != !!p_PcdParams->p_KgParams)
1225254885Sdumbbell            || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
1226254885Sdumbbell                    != !!p_PcdParams->p_CcParams))
1227254885Sdumbbell        RETURN_ERROR(
1228254885Sdumbbell                MAJOR,
1229254885Sdumbbell                E_INVALID_STATE,
1230254885Sdumbbell                ("PCD initialization structure is not consistent with pcdSupport"));
1231254885Sdumbbell
1232254885Sdumbbell    /* get PCD registers pointers */
1233254885Sdumbbell    switch (p_FmPort->portType)
1234254885Sdumbbell    {
1235254885Sdumbbell        case (e_FM_PORT_TYPE_RX_10G):
1236254885Sdumbbell        case (e_FM_PORT_TYPE_RX):
1237254885Sdumbbell            p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1238254885Sdumbbell            p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
1239254885Sdumbbell            p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1240254885Sdumbbell            p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
1241254885Sdumbbell            p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
1242254885Sdumbbell            break;
1243254885Sdumbbell        case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1244254885Sdumbbell            p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1245254885Sdumbbell            p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
1246254885Sdumbbell            p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1247254885Sdumbbell            p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
1248254885Sdumbbell            p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
1249254885Sdumbbell            break;
1250254885Sdumbbell        default:
1251254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1252254885Sdumbbell    }
1253254885Sdumbbell
1254254885Sdumbbell    /* set PCD port parameter */
1255254885Sdumbbell    if (p_FmPort->pcdEngines & FM_PCD_CC)
1256254885Sdumbbell    {
1257254885Sdumbbell        err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
1258254885Sdumbbell                              p_PcdParams->p_CcParams->h_CcTree,
1259254885Sdumbbell                              &ccTreePhysOffset, p_FmPort);
1260254885Sdumbbell        if (err)
1261254885Sdumbbell            RETURN_ERROR(MAJOR, err, NO_MSG);
1262254885Sdumbbell
1263254885Sdumbbell        WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
1264254885Sdumbbell        p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
1265254885Sdumbbell    }
1266254885Sdumbbell
1267254885Sdumbbell    if (p_FmPort->pcdEngines & FM_PCD_KG)
1268254885Sdumbbell    {
1269254885Sdumbbell        if (p_PcdParams->p_KgParams->numOfSchemes == 0)
1270254885Sdumbbell            RETURN_ERROR(
1271254885Sdumbbell                    MAJOR,
1272254885Sdumbbell                    E_INVALID_VALUE,
1273254885Sdumbbell                    ("For ports using Keygen, at least one scheme must be bound. "));
1274254885Sdumbbell
1275254885Sdumbbell        err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
1276254885Sdumbbell                                           p_FmPort->hardwarePortId,
1277254885Sdumbbell                                           p_FmPort->netEnvId,
1278254885Sdumbbell                                           p_FmPort->optArray,
1279254885Sdumbbell                                           &p_FmPort->clsPlanGrpId,
1280254885Sdumbbell                                           &isEmptyClsPlanGrp);
1281254885Sdumbbell        if (err)
1282254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1283254885Sdumbbell                         ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
1284254885Sdumbbell
1285254885Sdumbbell        p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
1286254885Sdumbbell
1287254885Sdumbbell        schemeBind.netEnvId = p_FmPort->netEnvId;
1288254885Sdumbbell        schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
1289254885Sdumbbell        schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
1290254885Sdumbbell        schemeBind.useClsPlan = p_FmPort->useClsPlan;
1291254885Sdumbbell
1292254885Sdumbbell        /* for each scheme */
1293254885Sdumbbell        for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1294254885Sdumbbell        {
1295254885Sdumbbell            ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
1296254885Sdumbbell            physicalSchemeId = FmPcdKgGetSchemeId(
1297254885Sdumbbell                    p_PcdParams->p_KgParams->h_Schemes[i]);
1298254885Sdumbbell            schemeBind.schemesIds[i] = physicalSchemeId;
1299254885Sdumbbell            /* build vector */
1300254885Sdumbbell            p_FmPort->schemesPerPortVector |= 1
1301254885Sdumbbell                    << (31 - (uint32_t)physicalSchemeId);
1302254885Sdumbbell#if (DPAA_VERSION >= 11)
1303254885Sdumbbell            /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
1304254885Sdumbbell             if !VSPE - in port, for relevant scheme VSPE can not be set*/
1305254885Sdumbbell            if (!p_FmPort->vspe
1306254885Sdumbbell                    && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
1307254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_STATE,
1308254885Sdumbbell                             ("VSPE is not at port level"));
1309254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */
1310254885Sdumbbell        }
1311254885Sdumbbell
1312254885Sdumbbell        err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1313254885Sdumbbell        if (err)
1314254885Sdumbbell            RETURN_ERROR(MAJOR, err, NO_MSG);
1315254885Sdumbbell    }
1316254885Sdumbbell
1317254885Sdumbbell    /***************************/
1318254885Sdumbbell    /* configure NIA after BMI */
1319254885Sdumbbell    /***************************/
1320254885Sdumbbell    /* rfne may contain FDCS bits, so first we read them. */
1321254885Sdumbbell    p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
1322254885Sdumbbell
1323254885Sdumbbell    /* If policer is used directly after BMI or PRS */
1324254885Sdumbbell    if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
1325254885Sdumbbell            && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
1326254885Sdumbbell                    || (p_PcdParams->pcdSupport
1327254885Sdumbbell                            == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
1328254885Sdumbbell    {
1329254885Sdumbbell        if (!p_PcdParams->p_PlcrParams->h_Profile)
1330254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE,
1331254885Sdumbbell                         ("Profile should be initialized"));
1332254885Sdumbbell
1333254885Sdumbbell        absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
1334254885Sdumbbell                p_PcdParams->p_PlcrParams->h_Profile);
1335254885Sdumbbell
1336254885Sdumbbell        if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
1337254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE,
1338254885Sdumbbell                         ("Private port profile not valid."));
1339254885Sdumbbell
1340254885Sdumbbell        tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
1341254885Sdumbbell
1342254885Sdumbbell        if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
1343254885Sdumbbell            /* update BMI HPNIA */
1344254885Sdumbbell            WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
1345254885Sdumbbell        else
1346254885Sdumbbell            /* e_FM_PCD_SUPPORT_PLCR_ONLY */
1347254885Sdumbbell            /* update BMI NIA */
1348254885Sdumbbell            p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
1349254885Sdumbbell    }
1350254885Sdumbbell
1351254885Sdumbbell    /* if CC is used directly after BMI */
1352254885Sdumbbell    if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
1353254885Sdumbbell#ifdef FM_CAPWAP_SUPPORT
1354254885Sdumbbell    || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
1355254885Sdumbbell    || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
1356254885Sdumbbell#endif /* FM_CAPWAP_SUPPORT */
1357254885Sdumbbell    )
1358254885Sdumbbell    {
1359254885Sdumbbell        if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1360254885Sdumbbell            RETURN_ERROR(
1361254885Sdumbbell                    MAJOR,
1362254885Sdumbbell                    E_INVALID_OPERATION,
1363254885Sdumbbell                    ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
1364254885Sdumbbell        p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
1365254885Sdumbbell        /* check that prs start offset == RIM[FOF] */
1366254885Sdumbbell    }
1367254885Sdumbbell
1368254885Sdumbbell    if (p_FmPort->pcdEngines & FM_PCD_PRS)
1369254885Sdumbbell    {
1370254885Sdumbbell        ASSERT_COND(p_PcdParams->p_PrsParams);
1371254885Sdumbbell#if (DPAA_VERSION >= 11)
1372254885Sdumbbell        if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
1373254885Sdumbbell            hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
1374254885Sdumbbell        else
1375254885Sdumbbell        {
1376254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */
1377254885Sdumbbell            /* if PRS is used it is always first */
1378254885Sdumbbell                hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
1379254885Sdumbbell            if (hdrNum == ILLEGAL_HDR_NUM)
1380254885Sdumbbell                RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
1381254885Sdumbbell#if (DPAA_VERSION >= 11)
1382254885Sdumbbell        }
1383254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */
1384254885Sdumbbell        p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
1385254885Sdumbbell        /* set after parser NIA */
1386254885Sdumbbell        tmpReg = 0;
1387254885Sdumbbell        switch (p_PcdParams->pcdSupport)
1388254885Sdumbbell        {
1389254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1390254885Sdumbbell                WRITE_UINT32(*p_BmiPrsNia,
1391254885Sdumbbell                             GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
1392254885Sdumbbell                break;
1393254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1394254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1395254885Sdumbbell                tmpReg = NIA_KG_CC_EN;
1396254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1397254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1398254885Sdumbbell                if (p_PcdParams->p_KgParams->directScheme)
1399254885Sdumbbell                {
1400254885Sdumbbell                    physicalSchemeId = FmPcdKgGetSchemeId(
1401254885Sdumbbell                            p_PcdParams->p_KgParams->h_DirectScheme);
1402254885Sdumbbell                    /* check that this scheme was bound to this port */
1403254885Sdumbbell                    for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1404254885Sdumbbell                        if (p_PcdParams->p_KgParams->h_DirectScheme
1405254885Sdumbbell                                == p_PcdParams->p_KgParams->h_Schemes[i])
1406254885Sdumbbell                            break;
1407254885Sdumbbell                    if (i == p_PcdParams->p_KgParams->numOfSchemes)
1408254885Sdumbbell                        RETURN_ERROR(
1409254885Sdumbbell                                MAJOR,
1410254885Sdumbbell                                E_INVALID_VALUE,
1411254885Sdumbbell                                ("Direct scheme is not one of the port selected schemes."));
1412254885Sdumbbell                    tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
1413254885Sdumbbell                }
1414254885Sdumbbell                WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
1415254885Sdumbbell                break;
1416254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1417254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1418254885Sdumbbell                WRITE_UINT32(*p_BmiPrsNia,
1419254885Sdumbbell                             (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
1420254885Sdumbbell                break;
1421254885Sdumbbell            case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1422254885Sdumbbell                break;
1423254885Sdumbbell            default:
1424254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
1425254885Sdumbbell        }
1426254885Sdumbbell
1427254885Sdumbbell        /* set start parsing offset */
1428254885Sdumbbell        WRITE_UINT32(*p_BmiPrsStartOffset,
1429254885Sdumbbell                     p_PcdParams->p_PrsParams->parsingOffset);
1430254885Sdumbbell
1431254885Sdumbbell        /************************************/
1432254885Sdumbbell        /* Parser port parameters           */
1433254885Sdumbbell        /************************************/
1434254885Sdumbbell        /* stop before configuring */
1435254885Sdumbbell        WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1436254885Sdumbbell        /* wait for parser to be in idle state */
1437254885Sdumbbell        while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1438254885Sdumbbell            ;
1439254885Sdumbbell
1440254885Sdumbbell        /* set soft seq attachment register */
1441254885Sdumbbell        memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
1442254885Sdumbbell
1443254885Sdumbbell        /* set protocol options */
1444254885Sdumbbell        for (i = 0; p_FmPort->optArray[i]; i++)
1445254885Sdumbbell            switch (p_FmPort->optArray[i])
1446254885Sdumbbell            {
1447254885Sdumbbell                case (ETH_BROADCAST):
1448254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1449254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
1450254885Sdumbbell                    break;
1451254885Sdumbbell                case (ETH_MULTICAST):
1452254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1453254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
1454254885Sdumbbell                    break;
1455254885Sdumbbell                case (VLAN_STACKED):
1456254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
1457254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
1458254885Sdumbbell                    break;
1459254885Sdumbbell                case (MPLS_STACKED):
1460254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1461254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
1462254885Sdumbbell                    break;
1463254885Sdumbbell                case (IPV4_BROADCAST_1):
1464254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1465254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
1466254885Sdumbbell                    break;
1467254885Sdumbbell                case (IPV4_MULTICAST_1):
1468254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1469254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
1470254885Sdumbbell                    break;
1471254885Sdumbbell                case (IPV4_UNICAST_2):
1472254885Sdumbbell					hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1473254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
1474254885Sdumbbell                    break;
1475254885Sdumbbell                case (IPV4_MULTICAST_BROADCAST_2):
1476254885Sdumbbell					hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1477254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
1478254885Sdumbbell                    break;
1479254885Sdumbbell                case (IPV6_MULTICAST_1):
1480254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1481254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
1482254885Sdumbbell                    break;
1483254885Sdumbbell                case (IPV6_UNICAST_2):
1484254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1485254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
1486254885Sdumbbell                    break;
1487254885Sdumbbell                case (IPV6_MULTICAST_2):
1488254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1489254885Sdumbbell                    tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
1490254885Sdumbbell                    break;
1491254885Sdumbbell            }
1492254885Sdumbbell
1493254885Sdumbbell        if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1494254885Sdumbbell                                  HEADER_TYPE_UDP_ENCAP_ESP))
1495254885Sdumbbell        {
1496254885Sdumbbell            if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
1497254885Sdumbbell                RETURN_ERROR(
1498254885Sdumbbell                         MINOR, E_INVALID_VALUE,
1499254885Sdumbbell                         ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
1500254885Sdumbbell
1501254885Sdumbbell            p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
1502254885Sdumbbell                    HEADER_TYPE_UDP;
1503254885Sdumbbell            p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
1504254885Sdumbbell                    TRUE;
1505254885Sdumbbell            p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
1506254885Sdumbbell        }
1507254885Sdumbbell
1508254885Sdumbbell        /* set MPLS default next header - HW reset workaround  */
1509254885Sdumbbell        hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1510254885Sdumbbell        tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
1511254885Sdumbbell        L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
1512254885Sdumbbell        tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1513254885Sdumbbell
1514254885Sdumbbell        /* for GRE, disable errors */
1515254885Sdumbbell        greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
1516254885Sdumbbell        tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
1517254885Sdumbbell
1518254885Sdumbbell        /* For UDP remove PAD from L4 checksum calculation */
1519254885Sdumbbell        hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
1520254885Sdumbbell        tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
1521254885Sdumbbell        /* For TCP remove PAD from L4 checksum calculation */
1522254885Sdumbbell        hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
1523254885Sdumbbell        tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
1524254885Sdumbbell
1525254885Sdumbbell        /* config additional params for specific headers */
1526254885Sdumbbell        for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
1527254885Sdumbbell                i++)
1528254885Sdumbbell        {
1529254885Sdumbbell            /* case for using sw parser as the initial NIA address, before
1530254885Sdumbbell               * HW parsing
1531254885Sdumbbell               */
1532254885Sdumbbell            if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
1533254885Sdumbbell                    p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
1534254885Sdumbbell            {
1535254885Sdumbbell                initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
1536254885Sdumbbell                               p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
1537254885Sdumbbell                if (initialSwPrs == ILLEGAL_BASE)
1538254885Sdumbbell                    RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1539254885Sdumbbell
1540254885Sdumbbell                /* clear parser first HXS */
1541254885Sdumbbell                p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
1542254885Sdumbbell                /* rewrite with soft parser start */
1543254885Sdumbbell                p_FmPort->savedBmiNia |= initialSwPrs;
1544254885Sdumbbell                continue;
1545254885Sdumbbell            }
1546254885Sdumbbell
1547254885Sdumbbell            hdrNum =
1548254885Sdumbbell                GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
1549254885Sdumbbell            if (hdrNum == ILLEGAL_HDR_NUM)
1550254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1551254885Sdumbbell            if (hdrNum == NO_HDR_NUM)
1552254885Sdumbbell                RETURN_ERROR(
1553254885Sdumbbell                        MAJOR, E_INVALID_VALUE,
1554254885Sdumbbell                        ("Private headers may not use additional parameters"));
1555254885Sdumbbell
1556254885Sdumbbell            err = AdditionalPrsParams(
1557254885Sdumbbell                    p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
1558254885Sdumbbell                    &tmpHxs[hdrNum]);
1559254885Sdumbbell            if (err)
1560254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1561254885Sdumbbell        }
1562254885Sdumbbell
1563254885Sdumbbell        /* Check if ip-reassembly port - need to link sw-parser code */
1564254885Sdumbbell        if (p_FmPort->h_IpReassemblyManip)
1565254885Sdumbbell        {
1566254885Sdumbbell           /* link to sw parser code for IP Frag - only if no other code is applied. */
1567254885Sdumbbell            hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1568254885Sdumbbell            if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1569254885Sdumbbell                tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
1570254885Sdumbbell            hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1571254885Sdumbbell            if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1572254885Sdumbbell                tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
1573254885Sdumbbell        } else {
1574254885Sdumbbell            if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
1575254885Sdumbbell            {
1576254885Sdumbbell                hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1577254885Sdumbbell                if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1578254885Sdumbbell                    tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1579254885Sdumbbell            } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1580254885Sdumbbell                       && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
1581254885Sdumbbell                {
1582254885Sdumbbell                    hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1583254885Sdumbbell                    if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1584254885Sdumbbell                        tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1585254885Sdumbbell                }
1586254885Sdumbbell            }
1587254885Sdumbbell
1588254885Sdumbbell#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
1589254885Sdumbbell        if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1590254885Sdumbbell                        HEADER_TYPE_UDP_LITE))
1591254885Sdumbbell        {
1592254885Sdumbbell            /* link to sw parser code for udp lite - only if no other code is applied. */
1593254885Sdumbbell            hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1594254885Sdumbbell            if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1595254885Sdumbbell            tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
1596254885Sdumbbell        }
1597254885Sdumbbell#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
1598254885Sdumbbell        for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
1599254885Sdumbbell        {
1600254885Sdumbbell            /* For all header set LCV as taken from netEnv*/
1601254885Sdumbbell            WRITE_UINT32(
1602254885Sdumbbell                    p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
1603254885Sdumbbell                    FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
1604254885Sdumbbell            /* set HXS register according to default+Additional params+protocol options */
1605254885Sdumbbell            WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
1606254885Sdumbbell                         tmpHxs[i]);
1607254885Sdumbbell        }
1608254885Sdumbbell
1609254885Sdumbbell        /* set tpid. */
1610254885Sdumbbell        tmpReg = PRS_TPID_DFLT;
1611254885Sdumbbell        if (p_PcdParams->p_PrsParams->setVlanTpid1)
1612254885Sdumbbell        {
1613254885Sdumbbell            tmpReg &= PRS_TPID2_MASK;
1614254885Sdumbbell            tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
1615254885Sdumbbell                    << PRS_PCTPID_SHIFT;
1616254885Sdumbbell        }
1617254885Sdumbbell        if (p_PcdParams->p_PrsParams->setVlanTpid2)
1618254885Sdumbbell        {
1619254885Sdumbbell            tmpReg &= PRS_TPID1_MASK;
1620254885Sdumbbell            tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
1621254885Sdumbbell        }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
1622254885Sdumbbell
1623254885Sdumbbell        /* enable parser */
1624254885Sdumbbell        WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
1625254885Sdumbbell
1626254885Sdumbbell        if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
1627254885Sdumbbell            p_FmPort->privateInfo =
1628254885Sdumbbell                    p_PcdParams->p_PrsParams->prsResultPrivateInfo;
1629254885Sdumbbell
1630254885Sdumbbell    } /* end parser */
1631254885Sdumbbell    else {
1632254885Sdumbbell        if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1633254885Sdumbbell            && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1634254885Sdumbbell        {
1635254885Sdumbbell            hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1636254885Sdumbbell            WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
1637254885Sdumbbell                         (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
1638254885Sdumbbell        }
1639254885Sdumbbell
1640254885Sdumbbell        WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1641254885Sdumbbell
1642254885Sdumbbell        p_FmPort->privateInfo = 0;
1643254885Sdumbbell    }
1644254885Sdumbbell
1645254885Sdumbbell    FmPortCheckNApplyMacsec(p_FmPort);
1646254885Sdumbbell
1647254885Sdumbbell    WRITE_UINT32(
1648254885Sdumbbell            *p_BmiPrsStartOffset,
1649254885Sdumbbell            GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
1650254885Sdumbbell
1651254885Sdumbbell    /* set initial parser result - used for all engines */
1652254885Sdumbbell    for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
1653254885Sdumbbell    {
1654254885Sdumbbell        if (!i)
1655254885Sdumbbell            WRITE_UINT32(
1656254885Sdumbbell                    *(p_BmiInitPrsResult),
1657254885Sdumbbell                    (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
1658254885Sdumbbell        else
1659254885Sdumbbell        {
1660254885Sdumbbell            if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
1661254885Sdumbbell                WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
1662254885Sdumbbell            else
1663254885Sdumbbell                WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
1664254885Sdumbbell        }
1665254885Sdumbbell    }
1666254885Sdumbbell
1667254885Sdumbbell    return E_OK;
1668254885Sdumbbell}
1669254885Sdumbbell
1670254885Sdumbbellstatic t_Error DeletePcd(t_FmPort *p_FmPort)
1671254885Sdumbbell{
1672254885Sdumbbell    t_Error err = E_OK;
1673254885Sdumbbell    volatile uint32_t *p_BmiNia = NULL;
1674254885Sdumbbell    volatile uint32_t *p_BmiPrsStartOffset = NULL;
1675254885Sdumbbell
1676254885Sdumbbell    ASSERT_COND(p_FmPort);
1677254885Sdumbbell    SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1678254885Sdumbbell
1679254885Sdumbbell    if (p_FmPort->imEn)
1680254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1681254885Sdumbbell                     ("available for non-independant mode ports only"));
1682254885Sdumbbell
1683254885Sdumbbell    if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1684254885Sdumbbell            && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1685254885Sdumbbell            && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1686254885Sdumbbell        RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1687254885Sdumbbell                     ("available for Rx and offline parsing ports only"));
1688254885Sdumbbell
1689254885Sdumbbell    if (!p_FmPort->pcdEngines)
1690254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
1691254885Sdumbbell
1692254885Sdumbbell    /* get PCD registers pointers */
1693254885Sdumbbell    switch (p_FmPort->portType)
1694254885Sdumbbell    {
1695254885Sdumbbell        case (e_FM_PORT_TYPE_RX_10G):
1696254885Sdumbbell        case (e_FM_PORT_TYPE_RX):
1697254885Sdumbbell            p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1698254885Sdumbbell            p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1699254885Sdumbbell            break;
1700254885Sdumbbell        case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1701254885Sdumbbell            p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1702254885Sdumbbell            p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1703254885Sdumbbell            break;
1704254885Sdumbbell        default:
1705254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1706254885Sdumbbell    }
1707254885Sdumbbell
1708254885Sdumbbell    if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1709254885Sdumbbell            != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1710254885Sdumbbell        RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1711254885Sdumbbell                     ("port has to be detached previousely"));
1712254885Sdumbbell
1713254885Sdumbbell    WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1714254885Sdumbbell
1715254885Sdumbbell    /* "cut" PCD out of the port's flow - go to BMI */
1716254885Sdumbbell    /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
1717254885Sdumbbell
1718254885Sdumbbell    if (p_FmPort->pcdEngines & FM_PCD_PRS)
1719254885Sdumbbell    {
1720254885Sdumbbell        /* stop parser */
1721254885Sdumbbell        WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1722254885Sdumbbell        /* wait for parser to be in idle state */
1723254885Sdumbbell        while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1724254885Sdumbbell            ;
1725254885Sdumbbell    }
1726254885Sdumbbell
1727254885Sdumbbell    if (p_FmPort->pcdEngines & FM_PCD_KG)
1728254885Sdumbbell    {
1729254885Sdumbbell        t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1730254885Sdumbbell
1731254885Sdumbbell        /* unbind all schemes */
1732254885Sdumbbell        p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
1733254885Sdumbbell                                                                 &schemeBind);
1734254885Sdumbbell
1735254885Sdumbbell        err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1736254885Sdumbbell        if (err)
1737254885Sdumbbell            RETURN_ERROR(MAJOR, err, NO_MSG);
1738254885Sdumbbell
1739254885Sdumbbell        err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
1740254885Sdumbbell                                                    p_FmPort->hardwarePortId,
1741254885Sdumbbell                                                    p_FmPort->clsPlanGrpId);
1742254885Sdumbbell        if (err)
1743254885Sdumbbell            RETURN_ERROR(MAJOR, err, NO_MSG);
1744254885Sdumbbell        p_FmPort->useClsPlan = FALSE;
1745254885Sdumbbell    }
1746254885Sdumbbell
1747254885Sdumbbell    if (p_FmPort->pcdEngines & FM_PCD_CC)
1748254885Sdumbbell    {
1749254885Sdumbbell        /* unbind - we need to get the treeId too */
1750254885Sdumbbell        err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
1751254885Sdumbbell        if (err)
1752254885Sdumbbell            RETURN_ERROR(MAJOR, err, NO_MSG);
1753254885Sdumbbell    }
1754254885Sdumbbell
1755254885Sdumbbell    p_FmPort->pcdEngines = 0;
1756254885Sdumbbell
1757254885Sdumbbell    return E_OK;
1758254885Sdumbbell}
1759254885Sdumbbell
1760254885Sdumbbellstatic t_Error AttachPCD(t_FmPort *p_FmPort)
1761254885Sdumbbell{
1762254885Sdumbbell    volatile uint32_t *p_BmiNia = NULL;
1763254885Sdumbbell
1764254885Sdumbbell    ASSERT_COND(p_FmPort);
1765254885Sdumbbell
1766254885Sdumbbell    /* get PCD registers pointers */
1767254885Sdumbbell    if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1768254885Sdumbbell        p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1769254885Sdumbbell    else
1770254885Sdumbbell        p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1771254885Sdumbbell
1772254885Sdumbbell    /* check that current NIA is BMI to BMI */
1773254885Sdumbbell    if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
1774254885Sdumbbell            != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1775254885Sdumbbell        RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1776254885Sdumbbell                     ("may be called only for ports in BMI-to-BMI state."));
1777254885Sdumbbell
1778254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1779254885Sdumbbell        if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
1780254885Sdumbbell                                   p_FmPort->orFmanCtrl) != E_OK)
1781254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1782254885Sdumbbell
1783254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
1784254885Sdumbbell    {
1785254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1786254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
1787254885Sdumbbell                         p_FmPort->savedBmiCmne);
1788254885Sdumbbell        else
1789254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
1790254885Sdumbbell                         p_FmPort->savedBmiCmne);
1791254885Sdumbbell    }
1792254885Sdumbbell
1793254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1794254885Sdumbbell        WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
1795254885Sdumbbell                     p_FmPort->savedQmiPnen);
1796254885Sdumbbell
1797254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1798254885Sdumbbell    {
1799254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1800254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1801254885Sdumbbell                         p_FmPort->savedBmiFene);
1802254885Sdumbbell        else
1803254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1804254885Sdumbbell                         p_FmPort->savedBmiFene);
1805254885Sdumbbell    }
1806254885Sdumbbell
1807254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
1808254885Sdumbbell    {
1809254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1810254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
1811254885Sdumbbell                         p_FmPort->savedBmiFpne);
1812254885Sdumbbell        else
1813254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
1814254885Sdumbbell                         p_FmPort->savedBmiFpne);
1815254885Sdumbbell    }
1816254885Sdumbbell
1817254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
1818254885Sdumbbell    {
1819254885Sdumbbell        ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
1820254885Sdumbbell
1821254885Sdumbbell        WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
1822254885Sdumbbell                     p_FmPort->savedBmiOfp);
1823254885Sdumbbell    }
1824254885Sdumbbell
1825254885Sdumbbell    WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
1826254885Sdumbbell
1827254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1828254885Sdumbbell    {
1829254885Sdumbbell        p_FmPort->origNonRxQmiRegsPndn =
1830254885Sdumbbell                GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
1831254885Sdumbbell        WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1832254885Sdumbbell                     p_FmPort->savedNonRxQmiRegsPndn);
1833254885Sdumbbell    }
1834254885Sdumbbell
1835254885Sdumbbell    return E_OK;
1836254885Sdumbbell}
1837254885Sdumbbell
1838254885Sdumbbellstatic t_Error DetachPCD(t_FmPort *p_FmPort)
1839254885Sdumbbell{
1840254885Sdumbbell    volatile uint32_t *p_BmiNia = NULL;
1841254885Sdumbbell
1842254885Sdumbbell    ASSERT_COND(p_FmPort);
1843254885Sdumbbell
1844254885Sdumbbell    /* get PCD registers pointers */
1845254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1846254885Sdumbbell        WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1847254885Sdumbbell                     p_FmPort->origNonRxQmiRegsPndn);
1848254885Sdumbbell
1849254885Sdumbbell    if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1850254885Sdumbbell        p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1851254885Sdumbbell    else
1852254885Sdumbbell        p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1853254885Sdumbbell
1854254885Sdumbbell    WRITE_UINT32(
1855254885Sdumbbell            *p_BmiNia,
1856254885Sdumbbell            (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
1857254885Sdumbbell
1858254885Sdumbbell    if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
1859254885Sdumbbell        FmPcdHcSync(p_FmPort->h_FmPcd);
1860254885Sdumbbell
1861254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1862254885Sdumbbell    {
1863254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1864254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1865254885Sdumbbell                         NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1866254885Sdumbbell        else
1867254885Sdumbbell            WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1868254885Sdumbbell                         NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1869254885Sdumbbell    }
1870254885Sdumbbell
1871254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1872254885Sdumbbell        WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
1873254885Sdumbbell                     NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
1874254885Sdumbbell
1875254885Sdumbbell    if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1876254885Sdumbbell        if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
1877254885Sdumbbell                                   p_FmPort->orFmanCtrl) != E_OK)
1878254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1879254885Sdumbbell
1880254885Sdumbbell    p_FmPort->requiredAction = 0;
1881254885Sdumbbell
1882254885Sdumbbell    return E_OK;
1883254885Sdumbbell}
1884254885Sdumbbell
1885254885Sdumbbell/*****************************************************************************/
1886254885Sdumbbell/*              Inter-module API routines                                    */
1887254885Sdumbbell/*****************************************************************************/
1888254885Sdumbbellvoid FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
1889254885Sdumbbell{
1890254885Sdumbbell    t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1891254885Sdumbbell    volatile uint32_t *p_BmiCfgReg = NULL;
1892254885Sdumbbell    uint32_t tmpReg;
1893254885Sdumbbell
1894254885Sdumbbell    SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
1895254885Sdumbbell    SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1896254885Sdumbbell
1897254885Sdumbbell    if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
1898254885Sdumbbell            && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
1899254885Sdumbbell    {
1900254885Sdumbbell        REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
1901254885Sdumbbell        return;
1902254885Sdumbbell    }
1903254885Sdumbbell
1904254885Sdumbbell    p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
1905254885Sdumbbell    tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
1906254885Sdumbbell    tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
1907254885Sdumbbell    tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
1908254885Sdumbbell            & BMI_CMD_ATTR_MACCMD_SC_MASK);
1909254885Sdumbbell
1910254885Sdumbbell    WRITE_UINT32(*p_BmiCfgReg, tmpReg);
1911254885Sdumbbell}
1912254885Sdumbbell
1913254885Sdumbbelluint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
1914254885Sdumbbell{
1915254885Sdumbbell    return ((t_FmPort*)h_FmPort)->netEnvId;
1916254885Sdumbbell}
1917254885Sdumbbell
1918254885Sdumbbelluint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
1919254885Sdumbbell{
1920254885Sdumbbell    return ((t_FmPort*)h_FmPort)->hardwarePortId;
1921254885Sdumbbell}
1922254885Sdumbbell
1923254885Sdumbbelluint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
1924254885Sdumbbell{
1925254885Sdumbbell    return ((t_FmPort*)h_FmPort)->pcdEngines;
1926254885Sdumbbell}
1927254885Sdumbbell
1928254885Sdumbbell#if (DPAA_VERSION >= 11)
1929254885Sdumbbellt_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
1930254885Sdumbbell                         void **p_Value)
1931254885Sdumbbell{
1932254885Sdumbbell    t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1933254885Sdumbbell    uint32_t muramPageOffset;
1934254885Sdumbbell
1935254885Sdumbbell    ASSERT_COND(p_FmPort);
1936254885Sdumbbell    ASSERT_COND(p_Value);
1937254885Sdumbbell
1938254885Sdumbbell    if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
1939254885Sdumbbell    {
1940254885Sdumbbell        if (p_FmPort->gprFunc != gprFunc)
1941254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_STATE,
1942254885Sdumbbell                         ("gpr was assigned with different func"));
1943254885Sdumbbell    }
1944254885Sdumbbell    else
1945254885Sdumbbell    {
1946254885Sdumbbell        switch (gprFunc)
1947254885Sdumbbell        {
1948254885Sdumbbell            case (e_FM_PORT_GPR_MURAM_PAGE):
1949254885Sdumbbell                p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
1950254885Sdumbbell                                                           256, 8);
1951254885Sdumbbell                if (!p_FmPort->p_ParamsPage)
1952254885Sdumbbell                    RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
1953254885Sdumbbell
1954254885Sdumbbell                IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
1955254885Sdumbbell                muramPageOffset =
1956254885Sdumbbell                        (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
1957254885Sdumbbell                                - p_FmPort->fmMuramPhysBaseAddr);
1958254885Sdumbbell                switch (p_FmPort->portType)
1959254885Sdumbbell                {
1960254885Sdumbbell                    case (e_FM_PORT_TYPE_RX_10G):
1961254885Sdumbbell                    case (e_FM_PORT_TYPE_RX):
1962254885Sdumbbell                        WRITE_UINT32(
1963254885Sdumbbell                                p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
1964254885Sdumbbell                                muramPageOffset);
1965254885Sdumbbell                        break;
1966254885Sdumbbell                    case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1967254885Sdumbbell                        WRITE_UINT32(
1968254885Sdumbbell                                p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
1969254885Sdumbbell                                muramPageOffset);
1970254885Sdumbbell                        break;
1971254885Sdumbbell                    default:
1972254885Sdumbbell                        RETURN_ERROR(MAJOR, E_INVALID_STATE,
1973254885Sdumbbell                                     ("Invalid port type"));
1974254885Sdumbbell                }
1975254885Sdumbbell                break;
1976254885Sdumbbell            default:
1977254885Sdumbbell                RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1978254885Sdumbbell        }
1979254885Sdumbbell        p_FmPort->gprFunc = gprFunc;
1980254885Sdumbbell    }
1981254885Sdumbbell
1982254885Sdumbbell    switch (p_FmPort->gprFunc)
1983254885Sdumbbell    {
1984254885Sdumbbell        case (e_FM_PORT_GPR_MURAM_PAGE):
1985254885Sdumbbell            *p_Value = p_FmPort->p_ParamsPage;
1986254885Sdumbbell            break;
1987254885Sdumbbell        default:
1988254885Sdumbbell            RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1989254885Sdumbbell    }
1990254885Sdumbbell
1991254885Sdumbbell    return E_OK;
1992254885Sdumbbell}
1993254885Sdumbbell#endif /* (DPAA_VERSION >= 11) */
1994254885Sdumbbell
1995254885Sdumbbellt_Error FmPortGetSetCcParams(t_Handle h_FmPort,
1996254885Sdumbbell                             t_FmPortGetSetCcParams *p_CcParams)
1997254885Sdumbbell{
1998254885Sdumbbell    t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1999254885Sdumbbell    uint32_t tmpInt;
2000254885Sdumbbell    volatile uint32_t *p_BmiPrsStartOffset = NULL;
2001254885Sdumbbell
2002254885Sdumbbell    /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
2003254885Sdumbbell
2004254885Sdumbbell    if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
2005254885Sdumbbell            && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
2006254885Sdumbbell    {
2007254885Sdumbbell        p_CcParams->getCcParams.prOffset =
2008254885Sdumbbell                (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
2009254885Sdumbbell        p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
2010254885Sdumbbell    }
2011254885Sdumbbell    if (p_CcParams->getCcParams.type & HW_PORT_ID)
2012254885Sdumbbell    {
2013254885Sdumbbell        p_CcParams->getCcParams.hardwarePortId =
2014254885Sdumbbell                (uint8_t)p_FmPort->hardwarePortId;
2015254885Sdumbbell        p_CcParams->getCcParams.type &= ~HW_PORT_ID;
2016254885Sdumbbell    }
2017254885Sdumbbell    if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
2018254885Sdumbbell            && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
2019254885Sdumbbell    {
2020254885Sdumbbell        p_CcParams->getCcParams.dataOffset =
2021254885Sdumbbell                (uint16_t)p_FmPort->bufferOffsets.dataOffset;
2022254885Sdumbbell        p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
2023254885Sdumbbell    }
2024254885Sdumbbell    if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
2025254885Sdumbbell    {
2026254885Sdumbbell        p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
2027254885Sdumbbell        p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
2028254885Sdumbbell    }
2029254885Sdumbbell    if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
2030254885Sdumbbell    {
2031254885Sdumbbell        p_CcParams->getCcParams.numOfExtraTasks =
2032254885Sdumbbell                (uint8_t)p_FmPort->tasks.extra;
2033254885Sdumbbell        p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
2034254885Sdumbbell    }
2035254885Sdumbbell    if (p_CcParams->getCcParams.type & FM_REV)
2036254885Sdumbbell    {
2037254885Sdumbbell        p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
2038254885Sdumbbell        p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
2039254885Sdumbbell        p_CcParams->getCcParams.type &= ~FM_REV;
2040254885Sdumbbell    }
2041254885Sdumbbell    if (p_CcParams->getCcParams.type & DISCARD_MASK)
2042254885Sdumbbell    {
2043254885Sdumbbell        if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2044262861Sjhb            p_CcParams->getCcParams.discardMask =
2045262861Sjhb                    GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
2046262861Sjhb        else
2047254885Sdumbbell            p_CcParams->getCcParams.discardMask =
2048254885Sdumbbell                    GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
2049254885Sdumbbell        p_CcParams->getCcParams.type &= ~DISCARD_MASK;
2050254885Sdumbbell    }
2051254885Sdumbbell    if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
2052254885Sdumbbell    {
2053254885Sdumbbell        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