fm_port.c (852ba100) fm_port.c (a32b5435)
1/*
2 * Copyright 2008-2012 Freescale Semiconductor Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Freescale Semiconductor nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34/******************************************************************************
35 @File fm_port.c
36
37 @Description FM driver routines implementation.
38 *//***************************************************************************/
39#include "error_ext.h"
40#include "std_ext.h"
41#include "string_ext.h"
42#include "sprint_ext.h"
43#include "debug_ext.h"
44#include "fm_muram_ext.h"
45
46#include "fman_common.h"
47#include "fm_port.h"
48#include "fm_port_dsar.h"
49#include "common/general.h"
50
51/****************************************/
52/* static functions */
53/****************************************/
54static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
55
56static t_Error CheckInitParameters(t_FmPort *p_FmPort)
57{
58 t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
59 struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
60 t_Error ans = E_OK;
61 uint32_t unusedMask;
62
63 if (p_FmPort->imEn)
64 {
65 if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
66 if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
67 > 2)
68 RETURN_ERROR(
69 MAJOR,
70 E_INVALID_VALUE,
71 ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
72
73 if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
74 return ERROR_CODE(ans);
75 }
76 else
77 {
78 /****************************************/
79 /* Rx only */
80 /****************************************/
81 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
82 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
83 {
84 /* external buffer pools */
85 if (!p_Params->extBufPools.numOfPoolsUsed)
86 RETURN_ERROR(
87 MAJOR,
88 E_INVALID_VALUE,
89 ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
90
91 if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
92 p_Params->p_BackupBmPools,
93 &p_Params->bufPoolDepletion) != E_OK)
94 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
95
96 /* Check that part of IC that needs copying is small enough to enter start margin */
97 if (p_Params->intContext.size
98 && (p_Params->intContext.size
99 + p_Params->intContext.extBufOffset
100 > p_Params->bufMargins.startMargins))
101 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
102 ("intContext.size is larger than start margins"));
103
104 if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
105 && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
106 RETURN_ERROR(
107 MAJOR,
108 E_INVALID_VALUE,
109 ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
110
111#ifdef FM_NO_BACKUP_POOLS
112 if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
113 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
114 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
115#endif /* FM_NO_BACKUP_POOLS */
116 }
117
118 /****************************************/
119 /* Non Rx ports */
120 /****************************************/
121 else
122 {
123 if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
124 RETURN_ERROR(
125 MAJOR,
126 E_INVALID_VALUE,
127 (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
128
129 /* to protect HW internal-context from overwrite */
130 if ((p_Params->intContext.size)
131 && (p_Params->intContext.intContextOffset
132 < MIN_TX_INT_OFFSET))
133 RETURN_ERROR(
134 MAJOR,
135 E_INVALID_VALUE,
136 ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
137
138 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
139 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
140 /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
141 || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
142 != DEFAULT_notSupported))
143 {
144 /* Check that not larger than 8 */
145 if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
146 || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
147 > MAX_FIFO_PIPELINE_DEPTH))
148 RETURN_ERROR(
149 MAJOR,
150 E_INVALID_VALUE,
151 ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
152 }
153 }
154
155 /****************************************/
156 /* Rx Or Offline Parsing */
157 /****************************************/
158 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
159 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
160 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
161 {
162 if (!p_Params->dfltFqid)
163 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
164 ("dfltFqid must be between 1 and 2^24-1"));
165#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
166 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
167 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
168#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
169 }
170
171 /****************************************/
172 /* All ports */
173 /****************************************/
174 /* common BMI registers values */
175 /* Check that Queue Id is not larger than 2^24, and is not 0 */
176 if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
177 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
178 ("errFqid must be between 1 and 2^24-1"));
179 if (p_Params->dfltFqid & ~0x00FFFFFF)
180 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
181 ("dfltFqid must be between 1 and 2^24-1"));
182 }
183
184 /****************************************/
185 /* Rx only */
186 /****************************************/
187 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
188 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
189 {
190 if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
191 RETURN_ERROR(
192 MAJOR,
193 E_INVALID_VALUE,
194 ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
195 if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
196 || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
197 RETURN_ERROR(
198 MAJOR,
199 E_INVALID_VALUE,
200 ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
201 if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
202 RETURN_ERROR(
203 MAJOR,
204 E_INVALID_VALUE,
205 ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
206 if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
207 || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
208 RETURN_ERROR(
209 MAJOR,
210 E_INVALID_VALUE,
211 ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
212
213 /* Check that not larger than 16 */
214 if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
215 RETURN_ERROR(
216 MAJOR,
217 E_INVALID_VALUE,
218 ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
219
220 if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
221 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
222
223 /* extra FIFO size (allowed only to Rx ports) */
224 if (p_Params->setSizeOfFifo
225 && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
226 RETURN_ERROR(
227 MAJOR,
228 E_INVALID_VALUE,
229 ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
230
231 if (p_Params->bufPoolDepletion.poolsGrpModeEnable
232 && !p_Params->bufPoolDepletion.numOfPools)
233 RETURN_ERROR(
234 MAJOR,
235 E_INVALID_VALUE,
236 ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
237#ifdef FM_CSI_CFED_LIMIT
238 if (p_FmPort->fmRevInfo.majorRev == 4)
239 {
240 /* Check that not larger than 16 */
241 if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
242 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
243 }
244#endif /* FM_CSI_CFED_LIMIT */
245 }
246
247 /****************************************/
248 /* Non Rx ports */
249 /****************************************/
250 /* extra FIFO size (allowed only to Rx ports) */
251 else
252 if (p_FmPort->fifoBufs.extra)
253 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
254 (" No fifoBufs.extra for non Rx ports"));
255
256 /****************************************/
257 /* Tx only */
258 /****************************************/
259 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
260 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
261 {
262 if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
263 RETURN_ERROR(
264 MAJOR,
265 E_INVALID_VALUE,
266 ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
267 if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
268 RETURN_ERROR(
269 MAJOR,
270 E_INVALID_VALUE,
271 ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
272 if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
273 RETURN_ERROR(
274 MAJOR,
275 E_INVALID_VALUE,
276 ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
277 if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
278 || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
279 RETURN_ERROR(
280 MAJOR,
281 E_INVALID_VALUE,
282 ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
283
284 if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
285 if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
286 > 2)
287 RETURN_ERROR(
288 MAJOR, E_INVALID_VALUE,
289 ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
290 }
291
292 /****************************************/
293 /* Non Tx Ports */
294 /****************************************/
295 /* If discard override was selected , no frames may be discarded. */
296 else
297 if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
298 RETURN_ERROR(
299 MAJOR,
300 E_CONFLICT,
301 ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
302
303 /****************************************/
304 /* Rx and Offline parsing */
305 /****************************************/
306 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
307 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
308 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
309 {
310 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
311 unusedMask = BMI_STATUS_OP_MASK_UNUSED;
312 else
313 unusedMask = BMI_STATUS_RX_MASK_UNUSED;
314
315 /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
316 if (p_Params->errorsToDiscard & unusedMask)
317 RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
318 ("errorsToDiscard contains undefined bits"));
319 }
320
321 /****************************************/
322 /* Offline Ports */
323 /****************************************/
324#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
325 if ((p_FmPort->fmRevInfo.majorRev >= 6)
326 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
327 && p_Params->setNumOfOpenDmas
328 && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
329 RETURN_ERROR(
330 MAJOR,
331 E_INVALID_VALUE,
332 ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
333#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
334
335 /****************************************/
336 /* Offline & HC Ports */
337 /****************************************/
338 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
339 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
340 {
341#ifndef FM_FRAME_END_PARAMS_FOR_OP
342 if ((p_FmPort->fmRevInfo.majorRev < 6) &&
343 (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
344 /* this is an indication that user called config for this mode which is not supported in this integration */
345 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
346#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
347
348#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
349 if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
350 (p_FmPort->fmRevInfo.majorRev >= 6))) &&
351 (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
352 /* this is an indication that user called config for this mode which is not supported in this integration */
353 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
354#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
355 }
356
357 /****************************************/
358 /* All ports */
359 /****************************************/
360 /* Check that not larger than 16 */
361 if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
362 && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
363 RETURN_ERROR(
364 MAJOR,
365 E_INVALID_VALUE,
366 ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
367
368 if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
369 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
370
371 /* common BMI registers values */
372 if (p_Params->setNumOfTasks
373 && ((!p_FmPort->tasks.num)
374 || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
375 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
376 ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
377 if (p_Params->setNumOfTasks
378 && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
379 RETURN_ERROR(
380 MAJOR,
381 E_INVALID_VALUE,
382 ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
383 if (p_Params->setNumOfOpenDmas
384 && ((!p_FmPort->openDmas.num)
385 || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
386 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
387 ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
388 if (p_Params->setNumOfOpenDmas
389 && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
390 RETURN_ERROR(
391 MAJOR,
392 E_INVALID_VALUE,
393 ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
394 if (p_Params->setSizeOfFifo
395 && (!p_FmPort->fifoBufs.num
396 || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
397 RETURN_ERROR(
398 MAJOR,
399 E_INVALID_VALUE,
400 ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
401 if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
402 RETURN_ERROR(
403 MAJOR, E_INVALID_VALUE,
404 ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
405
406#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
407 if (p_FmPort->fmRevInfo.majorRev == 4)
408 if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
409 /* this is an indication that user called config for this mode which is not supported in this integration */
410 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
411#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
412
413 return E_OK;
414}
415
416static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
417{
418 uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
419
420 /*************************/
421 /* TX PORTS */
422 /*************************/
423 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
424 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
425 {
426 minFifoSizeRequired =
427 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
428 + (3 * BMI_FIFO_UNITS));
429 if (!p_FmPort->imEn)
430 minFifoSizeRequired +=
431 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
432 * BMI_FIFO_UNITS;
433
434 optFifoSizeForB2B = minFifoSizeRequired;
435
436 /* Add some margin for back-to-back capability to improve performance,
437 allows the hardware to pipeline new frame dma while the previous
438 frame not yet transmitted. */
439 if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
440 optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
441 else
442 optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
443 }
444
445 /*************************/
446 /* RX IM PORTS */
447 /*************************/
448 else
449 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
450 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
451 && p_FmPort->imEn)
452 {
453 optFifoSizeForB2B =
454 minFifoSizeRequired =
455 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
456 + (4 * BMI_FIFO_UNITS));
457 }
458
459 /*************************/
460 /* RX non-IM PORTS */
461 /*************************/
462 else
463 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
464 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
465 && !p_FmPort->imEn)
466 {
467 if (p_FmPort->fmRevInfo.majorRev == 4)
468 {
469 if (p_FmPort->rxPoolsParams.numOfPools == 1)
470 minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
471 else
472 minFifoSizeRequired =
473 (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
474 + (7 * BMI_FIFO_UNITS));
475 }
476 else
477 {
478#if (DPAA_VERSION >= 11)
479 minFifoSizeRequired =
480 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
481 + (5 * BMI_FIFO_UNITS));
482 /* 4 according to spec + 1 for FOF>0 */
483#else
484 minFifoSizeRequired = (uint32_t)
485 (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
486 + (7*BMI_FIFO_UNITS));
487#endif /* (DPAA_VERSION >= 11) */
488 }
489
490 optFifoSizeForB2B = minFifoSizeRequired;
491
492 /* Add some margin for back-to-back capability to improve performance,
493 allows the hardware to pipeline new frame dma while the previous
494 frame not yet transmitted. */
495 if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
496 optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
497 else
498 optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
499 }
500
501 /* For O/H ports, check fifo size and update if necessary */
502 else
503 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
504 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
505 {
506#if (DPAA_VERSION >= 11)
507 optFifoSizeForB2B =
508 minFifoSizeRequired =
509 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
510 + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
511 + 5) * BMI_FIFO_UNITS));
512 /* 4 according to spec + 1 for FOF>0 */
513#else
514 optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
515#endif /* (DPAA_VERSION >= 11) */
516 }
517
518 ASSERT_COND(minFifoSizeRequired > 0);
519 ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
520
521 /* Verify the size */
522 if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
523 DBG(INFO,
524 ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
525 else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
526 DBG(INFO,
527 ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
528
529 return E_OK;
530}
531
532static void FmPortDriverParamFree(t_FmPort *p_FmPort)
533{
534 if (p_FmPort->p_FmPortDriverParam)
535 {
536 XX_Free(p_FmPort->p_FmPortDriverParam);
537 p_FmPort->p_FmPortDriverParam = NULL;
538 }
539}
540
541static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
542{
543 t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
544 t_FmBufPoolDepletion *p_BufPoolDepletion =
545 &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
546 uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
547 uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
548 int i = 0, j = 0, err;
549 struct fman_port_bpools bpools;
550
551 memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
552 memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
553 memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
554
555 FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
556 sizesArray);
557
558 /* Prepare flibs bpools structure */
559 memset(&bpools, 0, sizeof(struct fman_port_bpools));
560 bpools.count = p_ExtBufPools->numOfPoolsUsed;
561 bpools.counters_enable = TRUE;
562 for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
563 {
564 bpools.bpool[i].bpid = orderedArray[i];
565 bpools.bpool[i].size = sizesArray[orderedArray[i]];
566 /* functionality available only for some derivatives (limited by config) */
567 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
568 for (j = 0;
569 j
570 < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
571 j++)
572 if (orderedArray[i]
573 == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
574 {
575 bpools.bpool[i].is_backup = TRUE;
576 break;
577 }
578 }
579
580 /* save pools parameters for later use */
581 p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
582 p_FmPort->rxPoolsParams.largestBufSize =
583 sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
584 p_FmPort->rxPoolsParams.secondLargestBufSize =
585 sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
586
587 /* FMBM_RMPD reg. - pool depletion */
588 if (p_BufPoolDepletion->poolsGrpModeEnable)
589 {
590 bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
591 for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
592 {
593 if (p_BufPoolDepletion->poolsToConsider[i])
594 {
595 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
596 {
597 if (i == orderedArray[j])
598 {
599 bpools.bpool[j].grp_bp_depleted = TRUE;
600 break;
601 }
602 }
603 }
604 }
605 }
606
607 if (p_BufPoolDepletion->singlePoolModeEnable)
608 {
609 for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
610 {
611 if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
612 {
613 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
614 {
615 if (i == orderedArray[j])
616 {
617 bpools.bpool[j].single_bp_depleted = TRUE;
618 break;
619 }
620 }
621 }
622 }
623 }
624
625#if (DPAA_VERSION >= 11)
626 /* fill QbbPEV */
627 if (p_BufPoolDepletion->poolsGrpModeEnable
628 || p_BufPoolDepletion->singlePoolModeEnable)
629 {
630 for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
631 {
632 if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
633 {
634 bpools.bpool[i].pfc_priorities_en = TRUE;
635 }
636 }
637 }
638#endif /* (DPAA_VERSION >= 11) */
639
640 /* Issue flibs function */
641 err = fman_port_set_bpools(&p_FmPort->port, &bpools);
642 if (err != 0)
643 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
644
645 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
646 XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
647
648 return E_OK;
649}
650
651static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
652{
653 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
654 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
655 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
656 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
657 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
658 return E_OK;
659}
660
661static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
662{
663 t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
664 struct fman_port_params portParams;
665 uint32_t tmpVal;
666 t_Error err;
667
668 /* Set up flibs parameters and issue init function */
669
670 memset(&portParams, 0, sizeof(struct fman_port_params));
671 portParams.discard_mask = p_DriverParams->errorsToDiscard;
672 portParams.dflt_fqid = p_DriverParams->dfltFqid;
673 portParams.err_fqid = p_DriverParams->errFqid;
674 portParams.deq_sp = p_DriverParams->deqSubPortal;
675 portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
676 switch (p_FmPort->portType)
677 {
678 case (e_FM_PORT_TYPE_RX_10G):
679 case (e_FM_PORT_TYPE_RX):
680 portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
681 if (!p_FmPort->imEn)
682 {
683 if (p_DriverParams->forwardReuseIntContext)
684 p_DriverParams->dfltCfg.rx_fd_bits =
685 (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
686 }
687 break;
688
689 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
690 portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
691 break;
692 break;
693
694 default:
695 break;
696 }
697
698 tmpVal =
699 (uint32_t)(
700 (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
701 / OFFSET_UNITS + 1) :
702 (p_FmPort->internalBufferOffset / OFFSET_UNITS));
703 p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
704 p_DriverParams->dfltCfg.int_buf_start_margin =
705 p_FmPort->internalBufferOffset;
706
707 p_DriverParams->dfltCfg.ext_buf_start_margin =
708 p_DriverParams->bufMargins.startMargins;
709 p_DriverParams->dfltCfg.ext_buf_end_margin =
710 p_DriverParams->bufMargins.endMargins;
711
712 p_DriverParams->dfltCfg.ic_ext_offset =
713 p_DriverParams->intContext.extBufOffset;
714 p_DriverParams->dfltCfg.ic_int_offset =
715 p_DriverParams->intContext.intContextOffset;
716 p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
717
718 p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
719 p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
720 p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
721
722 p_DriverParams->dfltCfg.perf_cnt_params.task_val =
723 (uint8_t)p_FmPort->tasks.num;
724 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
725 p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
726 else
727 p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
728 p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
729 (uint8_t)p_FmPort->openDmas.num;
730 p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
731
732 if (0
733 != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
734 &portParams))
735 RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
736
737 if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
738 RETURN_ERROR(MAJOR, err, NO_MSG);
739 else
740 {
741 // from QMIInit
742 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
743 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
744 {
745 if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
746 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
747 FALSE);
748 else
749 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
750 TRUE);
751 }
752 }
753 /* The code bellow is a trick so the FM will not release the buffer
754 to BM nor will try to enqueue the frame to QM */
755 if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
756 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
757 {
758 if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
759 {
760 /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
761 * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
762 * buffers to BM regardless of fmbm_tfene
763 */
764 WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
765 WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
766 NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
767 }
768 }
769
770 return E_OK;
771}
772
773static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
774{
775 UNUSED(p_FmPort);
776
777 switch (counter)
778 {
779 case (e_FM_PORT_COUNTERS_CYCLE):
780 case (e_FM_PORT_COUNTERS_TASK_UTIL):
781 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
782 case (e_FM_PORT_COUNTERS_DMA_UTIL):
783 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
784 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
785 case (e_FM_PORT_COUNTERS_FRAME):
786 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
787 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
788 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
789 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
790 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
791 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
792 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
793 case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
794 return TRUE;
795 default:
796 return FALSE;
797 }
798}
799
800static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
801{
802 UNUSED(p_FmPort);
803
804 switch (counter)
805 {
806 case (e_FM_PORT_COUNTERS_CYCLE):
807 case (e_FM_PORT_COUNTERS_TASK_UTIL):
808 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
809 case (e_FM_PORT_COUNTERS_DMA_UTIL):
810 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
811 case (e_FM_PORT_COUNTERS_FRAME):
812 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
813 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
814 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
815 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
816 return TRUE;
817 default:
818 return FALSE;
819 }
820}
821
822static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
823{
824 switch (counter)
825 {
826 case (e_FM_PORT_COUNTERS_CYCLE):
827 case (e_FM_PORT_COUNTERS_TASK_UTIL):
828 case (e_FM_PORT_COUNTERS_DMA_UTIL):
829 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
830 case (e_FM_PORT_COUNTERS_FRAME):
831 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
832 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
833 case (e_FM_PORT_COUNTERS_WRED_DISCARD):
834 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
835 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
836 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
837 return TRUE;
838 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
839 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
840 return FALSE;
841 else
842 return TRUE;
843 default:
844 return FALSE;
845 }
846}
847
848static t_Error BmiPortCheckAndGetCounterType(
849 t_FmPort *p_FmPort, e_FmPortCounters counter,
850 enum fman_port_stats_counters *p_StatsType,
851 enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
852{
853 volatile uint32_t *p_Reg;
854 bool isValid;
855
856 switch (p_FmPort->portType)
857 {
858 case (e_FM_PORT_TYPE_RX_10G):
859 case (e_FM_PORT_TYPE_RX):
860 p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
861 isValid = CheckRxBmiCounter(p_FmPort, counter);
862 break;
863 case (e_FM_PORT_TYPE_TX_10G):
864 case (e_FM_PORT_TYPE_TX):
865 p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
866 isValid = CheckTxBmiCounter(p_FmPort, counter);
867 break;
868 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
869 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
870 p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
871 isValid = CheckOhBmiCounter(p_FmPort, counter);
872 break;
873 default:
874 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
875 }
876
877 if (!isValid)
878 RETURN_ERROR(MINOR, E_INVALID_STATE,
879 ("Requested counter is not available for this port type"));
880
881 /* check that counters are enabled */
882 switch (counter)
883 {
884 case (e_FM_PORT_COUNTERS_CYCLE):
885 case (e_FM_PORT_COUNTERS_TASK_UTIL):
886 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
887 case (e_FM_PORT_COUNTERS_DMA_UTIL):
888 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
889 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
890 /* performance counters - may be read when disabled */
891 *p_IsStats = FALSE;
892 break;
893 case (e_FM_PORT_COUNTERS_FRAME):
894 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
895 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
896 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
897 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
898 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
899 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
900 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
901 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
902 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
903 case (e_FM_PORT_COUNTERS_WRED_DISCARD):
904 *p_IsStats = TRUE;
905 if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
906 RETURN_ERROR(MINOR, E_INVALID_STATE,
907 ("Requested counter was not enabled"));
908 break;
909 default:
910 break;
911 }
912
913 /* Set counter */
914 switch (counter)
915 {
916 case (e_FM_PORT_COUNTERS_CYCLE):
917 *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
918 break;
919 case (e_FM_PORT_COUNTERS_TASK_UTIL):
920 *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
921 break;
922 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
923 *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
924 break;
925 case (e_FM_PORT_COUNTERS_DMA_UTIL):
926 *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
927 break;
928 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
929 *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
930 break;
931 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
932 *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
933 break;
934 case (e_FM_PORT_COUNTERS_FRAME):
935 *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
936 break;
937 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
938 *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
939 break;
940 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
941 *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
942 break;
943 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
944 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
945 break;
946 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
947 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
948 break;
949 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
950 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
951 break;
952 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
953 *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
954 break;
955 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
956 *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
957 break;
958 case (e_FM_PORT_COUNTERS_WRED_DISCARD):
959 *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
960 break;
961 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
962 *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
963 break;
964 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
965 *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
966 break;
967 default:
968 break;
969 }
970
971 return E_OK;
972}
973
974static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
975 t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
976 uint32_t *p_SoftSeqAttachReg)
977{
978 uint8_t hdrNum, Ipv4HdrNum;
979 u_FmPcdHdrPrsOpts *p_prsOpts;
980 uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
981
982 if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
983 || IS_SPECIAL_HEADER(p_HdrParams->hdr))
984 RETURN_ERROR(
985 MAJOR, E_NOT_SUPPORTED,
986 ("No additional parameters for private or special headers."));
987
988 if (p_HdrParams->errDisable)
989 tmpReg |= PRS_HDR_ERROR_DIS;
990
991 /* Set parser options */
992 if (p_HdrParams->usePrsOpts)
993 {
994 p_prsOpts = &p_HdrParams->prsOpts;
995 switch (p_HdrParams->hdr)
996 {
997 case (HEADER_TYPE_MPLS):
998 if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
999 tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
1000 hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
1001 if (hdrNum == ILLEGAL_HDR_NUM)
1002 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1003 Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1004 if (hdrNum < Ipv4HdrNum)
1005 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1006 ("Header must be equal or higher than IPv4"));
1007 tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
1008 << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1009 break;
1010 case (HEADER_TYPE_PPPoE):
1011 if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
1012 tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
1013 break;
1014 case (HEADER_TYPE_IPv6):
1015 if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
1016 tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
1017 break;
1018 case (HEADER_TYPE_TCP):
1019 if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
1020 tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
1021 else
1022 tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
1023 break;
1024 case (HEADER_TYPE_UDP):
1025 if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
1026 tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
1027 else
1028 tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
1029 break;
1030 default:
1031 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
1032 }
1033 }
1034
1035 /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
1036 if (p_HdrParams->swPrsEnable)
1037 {
1038 tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
1039 p_HdrParams->indexPerHdr);
1040 if (tmpPrsOffset == ILLEGAL_BASE)
1041 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1042 tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
1043 }
1044 *p_SoftSeqAttachReg = tmpReg;
1045
1046 return E_OK;
1047}
1048
1049static uint32_t GetPortSchemeBindParams(
1050 t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
1051{
1052 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1053 uint32_t walking1Mask = 0x80000000, tmp;
1054 uint8_t idx = 0;
1055
1056 p_SchemeBind->netEnvId = p_FmPort->netEnvId;
1057 p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
1058 p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
1059 p_SchemeBind->numOfSchemes = 0;
1060 tmp = p_FmPort->schemesPerPortVector;
1061 if (tmp)
1062 {
1063 while (tmp)
1064 {
1065 if (tmp & walking1Mask)
1066 {
1067 p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
1068 p_SchemeBind->numOfSchemes++;
1069 tmp &= ~walking1Mask;
1070 }
1071 walking1Mask >>= 1;
1072 idx++;
1073 }
1074 }
1075
1076 return tmp;
1077}
1078
1079static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
1080{
1081 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1082 volatile uint32_t *p_BmiCfgReg = NULL;
1083 uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
1084 uint32_t lcv, walking1Mask = 0x80000000;
1085 uint8_t cnt = 0;
1086
1087 ASSERT_COND(p_FmPort);
1088 ASSERT_COND(p_FmPort->h_FmPcd);
1089 ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
1090
1091 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1092 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
1093 return;
1094
1095 p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
1096 /* get LCV for MACSEC */
1097 if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
1098 != 0)
1099 {
1100 while (!(lcv & walking1Mask))
1101 {
1102 cnt++;
1103 walking1Mask >>= 1;
1104 }
1105
1106 macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
1107 WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
1108 }
1109}
1110
1111static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
1112{
1113 t_Error err = E_OK;
1114 uint32_t tmpReg;
1115 volatile uint32_t *p_BmiNia = NULL;
1116 volatile uint32_t *p_BmiPrsNia = NULL;
1117 volatile uint32_t *p_BmiPrsStartOffset = NULL;
1118 volatile uint32_t *p_BmiInitPrsResult = NULL;
1119 volatile uint32_t *p_BmiCcBase = NULL;
1120 uint16_t hdrNum, L3HdrNum, greHdrNum;
1121 int i;
1122 bool isEmptyClsPlanGrp;
1123 uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
1124 uint16_t absoluteProfileId;
1125 uint8_t physicalSchemeId;
1126 uint32_t ccTreePhysOffset;
1127 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1128 uint32_t initialSwPrs = 0;
1129
1130 ASSERT_COND(p_FmPort);
1131 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1132
1133 if (p_FmPort->imEn)
1134 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1135 ("available for non-independant mode ports only"));
1136
1137 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1138 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1139 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1140 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1141 ("available for Rx and offline parsing ports only"));
1142
1143 p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
1144
1145 p_FmPort->pcdEngines = 0;
1146
1147 /* initialize p_FmPort->pcdEngines field in port's structure */
1148 switch (p_PcdParams->pcdSupport)
1149 {
1150 case (e_FM_PORT_PCD_SUPPORT_NONE):
1151 RETURN_ERROR(
1152 MAJOR,
1153 E_INVALID_STATE,
1154 ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
1155 case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1156 p_FmPort->pcdEngines |= FM_PCD_PRS;
1157 break;
1158 case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
1159 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1160 break;
1161 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1162 p_FmPort->pcdEngines |= FM_PCD_PRS;
1163 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1164 break;
1165 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1166 p_FmPort->pcdEngines |= FM_PCD_PRS;
1167 p_FmPort->pcdEngines |= FM_PCD_KG;
1168 break;
1169 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1170 p_FmPort->pcdEngines |= FM_PCD_PRS;
1171 p_FmPort->pcdEngines |= FM_PCD_CC;
1172 p_FmPort->pcdEngines |= FM_PCD_KG;
1173 break;
1174 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1175 p_FmPort->pcdEngines |= FM_PCD_PRS;
1176 p_FmPort->pcdEngines |= FM_PCD_KG;
1177 p_FmPort->pcdEngines |= FM_PCD_CC;
1178 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1179 break;
1180 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1181 p_FmPort->pcdEngines |= FM_PCD_PRS;
1182 p_FmPort->pcdEngines |= FM_PCD_CC;
1183 break;
1184 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1185 p_FmPort->pcdEngines |= FM_PCD_PRS;
1186 p_FmPort->pcdEngines |= FM_PCD_CC;
1187 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1188 break;
1189 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1190 p_FmPort->pcdEngines |= FM_PCD_PRS;
1191 p_FmPort->pcdEngines |= FM_PCD_KG;
1192 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1193 break;
1194 case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
1195 p_FmPort->pcdEngines |= FM_PCD_CC;
1196 break;
1197#ifdef FM_CAPWAP_SUPPORT
1198 case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
1199 p_FmPort->pcdEngines |= FM_PCD_CC;
1200 p_FmPort->pcdEngines |= FM_PCD_KG;
1201 break;
1202 case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
1203 p_FmPort->pcdEngines |= FM_PCD_CC;
1204 p_FmPort->pcdEngines |= FM_PCD_KG;
1205 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1206 break;
1207#endif /* FM_CAPWAP_SUPPORT */
1208
1209 default:
1210 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
1211 }
1212
1213 if ((p_FmPort->pcdEngines & FM_PCD_PRS)
1214 && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
1215 > FM_PCD_PRS_NUM_OF_HDRS))
1216 RETURN_ERROR(
1217 MAJOR,
1218 E_INVALID_VALUE,
1219 ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
1220
1221 /* check that parameters exist for each and only each defined engine */
1222 if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
1223 || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
1224 != !!p_PcdParams->p_KgParams)
1225 || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
1226 != !!p_PcdParams->p_CcParams))
1227 RETURN_ERROR(
1228 MAJOR,
1229 E_INVALID_STATE,
1230 ("PCD initialization structure is not consistent with pcdSupport"));
1231
1232 /* get PCD registers pointers */
1233 switch (p_FmPort->portType)
1234 {
1235 case (e_FM_PORT_TYPE_RX_10G):
1236 case (e_FM_PORT_TYPE_RX):
1237 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1238 p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
1239 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1240 p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
1241 p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
1242 break;
1243 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1244 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1245 p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
1246 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1247 p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
1248 p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
1249 break;
1250 default:
1251 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1252 }
1253
1254 /* set PCD port parameter */
1255 if (p_FmPort->pcdEngines & FM_PCD_CC)
1256 {
1257 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
1258 p_PcdParams->p_CcParams->h_CcTree,
1259 &ccTreePhysOffset, p_FmPort);
1260 if (err)
1261 RETURN_ERROR(MAJOR, err, NO_MSG);
1262
1263 WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
1264 p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
1265 }
1266
1267 if (p_FmPort->pcdEngines & FM_PCD_KG)
1268 {
1269 if (p_PcdParams->p_KgParams->numOfSchemes == 0)
1270 RETURN_ERROR(
1271 MAJOR,
1272 E_INVALID_VALUE,
1273 ("For ports using Keygen, at least one scheme must be bound. "));
1274
1275 err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
1276 p_FmPort->hardwarePortId,
1277 p_FmPort->netEnvId,
1278 p_FmPort->optArray,
1279 &p_FmPort->clsPlanGrpId,
1280 &isEmptyClsPlanGrp);
1281 if (err)
1282 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1283 ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
1284
1285 p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
1286
1287 schemeBind.netEnvId = p_FmPort->netEnvId;
1288 schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
1289 schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
1290 schemeBind.useClsPlan = p_FmPort->useClsPlan;
1291
1292 /* for each scheme */
1293 for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1294 {
1295 ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
1296 physicalSchemeId = FmPcdKgGetSchemeId(
1297 p_PcdParams->p_KgParams->h_Schemes[i]);
1298 schemeBind.schemesIds[i] = physicalSchemeId;
1299 /* build vector */
1300 p_FmPort->schemesPerPortVector |= 1
1301 << (31 - (uint32_t)physicalSchemeId);
1302#if (DPAA_VERSION >= 11)
1303 /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
1304 if !VSPE - in port, for relevant scheme VSPE can not be set*/
1305 if (!p_FmPort->vspe
1306 && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
1307 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1308 ("VSPE is not at port level"));
1309#endif /* (DPAA_VERSION >= 11) */
1310 }
1311
1312 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1313 if (err)
1314 RETURN_ERROR(MAJOR, err, NO_MSG);
1315 }
1316
1317 /***************************/
1318 /* configure NIA after BMI */
1319 /***************************/
1320 /* rfne may contain FDCS bits, so first we read them. */
1321 p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
1322
1323 /* If policer is used directly after BMI or PRS */
1324 if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
1325 && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
1326 || (p_PcdParams->pcdSupport
1327 == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
1328 {
1329 if (!p_PcdParams->p_PlcrParams->h_Profile)
1330 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1331 ("Profile should be initialized"));
1332
1333 absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
1334 p_PcdParams->p_PlcrParams->h_Profile);
1335
1336 if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
1337 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1338 ("Private port profile not valid."));
1339
1340 tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
1341
1342 if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
1343 /* update BMI HPNIA */
1344 WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
1345 else
1346 /* e_FM_PCD_SUPPORT_PLCR_ONLY */
1347 /* update BMI NIA */
1348 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
1349 }
1350
1351 /* if CC is used directly after BMI */
1352 if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
1353#ifdef FM_CAPWAP_SUPPORT
1354 || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
1355 || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
1356#endif /* FM_CAPWAP_SUPPORT */
1357 )
1358 {
1359 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1360 RETURN_ERROR(
1361 MAJOR,
1362 E_INVALID_OPERATION,
1363 ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
1364 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
1365 /* check that prs start offset == RIM[FOF] */
1366 }
1367
1368 if (p_FmPort->pcdEngines & FM_PCD_PRS)
1369 {
1370 ASSERT_COND(p_PcdParams->p_PrsParams);
1371#if (DPAA_VERSION >= 11)
1372 if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
1373 hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
1374 else
1375 {
1376#endif /* (DPAA_VERSION >= 11) */
1377 /* if PRS is used it is always first */
1378 hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
1379 if (hdrNum == ILLEGAL_HDR_NUM)
1380 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
1381#if (DPAA_VERSION >= 11)
1382 }
1383#endif /* (DPAA_VERSION >= 11) */
1384 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
1385 /* set after parser NIA */
1386 tmpReg = 0;
1387 switch (p_PcdParams->pcdSupport)
1388 {
1389 case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1390 WRITE_UINT32(*p_BmiPrsNia,
1391 GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
1392 break;
1393 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1394 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1395 tmpReg = NIA_KG_CC_EN;
1396 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1397 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1398 if (p_PcdParams->p_KgParams->directScheme)
1399 {
1400 physicalSchemeId = FmPcdKgGetSchemeId(
1401 p_PcdParams->p_KgParams->h_DirectScheme);
1402 /* check that this scheme was bound to this port */
1403 for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1404 if (p_PcdParams->p_KgParams->h_DirectScheme
1405 == p_PcdParams->p_KgParams->h_Schemes[i])
1406 break;
1407 if (i == p_PcdParams->p_KgParams->numOfSchemes)
1408 RETURN_ERROR(
1409 MAJOR,
1410 E_INVALID_VALUE,
1411 ("Direct scheme is not one of the port selected schemes."));
1412 tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
1413 }
1414 WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
1415 break;
1416 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1417 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1418 WRITE_UINT32(*p_BmiPrsNia,
1419 (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
1420 break;
1421 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1422 break;
1423 default:
1424 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
1425 }
1426
1427 /* set start parsing offset */
1428 WRITE_UINT32(*p_BmiPrsStartOffset,
1429 p_PcdParams->p_PrsParams->parsingOffset);
1430
1431 /************************************/
1432 /* Parser port parameters */
1433 /************************************/
1434 /* stop before configuring */
1435 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1436 /* wait for parser to be in idle state */
1437 while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1438 ;
1439
1440 /* set soft seq attachment register */
1441 memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
1442
1443 /* set protocol options */
1444 for (i = 0; p_FmPort->optArray[i]; i++)
1445 switch (p_FmPort->optArray[i])
1446 {
1447 case (ETH_BROADCAST):
1448 hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1449 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
1450 break;
1451 case (ETH_MULTICAST):
1452 hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1453 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
1454 break;
1455 case (VLAN_STACKED):
1456 hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
1457 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
1458 break;
1459 case (MPLS_STACKED):
1460 hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1461 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
1462 break;
1463 case (IPV4_BROADCAST_1):
1464 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1465 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
1466 break;
1467 case (IPV4_MULTICAST_1):
1468 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1469 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
1470 break;
1471 case (IPV4_UNICAST_2):
1472 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1473 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
1474 break;
1475 case (IPV4_MULTICAST_BROADCAST_2):
1476 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1477 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
1478 break;
1479 case (IPV6_MULTICAST_1):
1480 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1481 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
1482 break;
1483 case (IPV6_UNICAST_2):
1484 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1485 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
1486 break;
1487 case (IPV6_MULTICAST_2):
1488 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1489 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
1490 break;
1491 }
1492
1493 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1494 HEADER_TYPE_UDP_ENCAP_ESP))
1495 {
1496 if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
1497 RETURN_ERROR(
1498 MINOR, E_INVALID_VALUE,
1499 ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
1500
1501 p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
1502 HEADER_TYPE_UDP;
1503 p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
1504 TRUE;
1505 p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
1506 }
1507
1508 /* set MPLS default next header - HW reset workaround */
1509 hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1510 tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
1511 L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
1512 tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1513
1514 /* for GRE, disable errors */
1515 greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
1516 tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
1517
1518 /* For UDP remove PAD from L4 checksum calculation */
1519 hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
1520 tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
1521 /* For TCP remove PAD from L4 checksum calculation */
1522 hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
1523 tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
1524
1525 /* config additional params for specific headers */
1526 for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
1527 i++)
1528 {
1529 /* case for using sw parser as the initial NIA address, before
1530 * HW parsing
1531 */
1532 if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
1533 p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
1534 {
1535 initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
1536 p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
1537 if (initialSwPrs == ILLEGAL_BASE)
1538 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1539
1540 /* clear parser first HXS */
1541 p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
1542 /* rewrite with soft parser start */
1543 p_FmPort->savedBmiNia |= initialSwPrs;
1544 continue;
1545 }
1546
1547 hdrNum =
1548 GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
1549 if (hdrNum == ILLEGAL_HDR_NUM)
1550 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1551 if (hdrNum == NO_HDR_NUM)
1552 RETURN_ERROR(
1553 MAJOR, E_INVALID_VALUE,
1554 ("Private headers may not use additional parameters"));
1555
1556 err = AdditionalPrsParams(
1557 p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
1558 &tmpHxs[hdrNum]);
1559 if (err)
1560 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1561 }
1562
1563 /* Check if ip-reassembly port - need to link sw-parser code */
1564 if (p_FmPort->h_IpReassemblyManip)
1565 {
1566 /* link to sw parser code for IP Frag - only if no other code is applied. */
1567 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1568 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1569 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
1570 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1571 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1572 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
1573 } else {
1574 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
1575 {
1576 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1577 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1578 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1579 } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1580 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
1581 {
1582 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1583 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1584 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1585 }
1586 }
1587
1588#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
1589 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1590 HEADER_TYPE_UDP_LITE))
1591 {
1592 /* link to sw parser code for udp lite - only if no other code is applied. */
1593 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1594 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1595 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
1596 }
1597#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
1598 for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
1599 {
1600 /* For all header set LCV as taken from netEnv*/
1601 WRITE_UINT32(
1602 p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
1603 FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
1604 /* set HXS register according to default+Additional params+protocol options */
1605 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
1606 tmpHxs[i]);
1607 }
1608
1609 /* set tpid. */
1610 tmpReg = PRS_TPID_DFLT;
1611 if (p_PcdParams->p_PrsParams->setVlanTpid1)
1612 {
1613 tmpReg &= PRS_TPID2_MASK;
1614 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
1615 << PRS_PCTPID_SHIFT;
1616 }
1617 if (p_PcdParams->p_PrsParams->setVlanTpid2)
1618 {
1619 tmpReg &= PRS_TPID1_MASK;
1620 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
1621 }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
1622
1623 /* enable parser */
1624 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
1625
1626 if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
1627 p_FmPort->privateInfo =
1628 p_PcdParams->p_PrsParams->prsResultPrivateInfo;
1629
1630 } /* end parser */
1631 else {
1632 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1633 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1634 {
1635 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1636 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
1637 (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
1638 }
1639
1640 WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1641
1642 p_FmPort->privateInfo = 0;
1643 }
1644
1645 FmPortCheckNApplyMacsec(p_FmPort);
1646
1647 WRITE_UINT32(
1648 *p_BmiPrsStartOffset,
1649 GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
1650
1651 /* set initial parser result - used for all engines */
1652 for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
1653 {
1654 if (!i)
1655 WRITE_UINT32(
1656 *(p_BmiInitPrsResult),
1657 (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
1658 else
1659 {
1660 if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
1661 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
1662 else
1663 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
1664 }
1665 }
1666
1667 return E_OK;
1668}
1669
1670static t_Error DeletePcd(t_FmPort *p_FmPort)
1671{
1672 t_Error err = E_OK;
1673 volatile uint32_t *p_BmiNia = NULL;
1674 volatile uint32_t *p_BmiPrsStartOffset = NULL;
1675
1676 ASSERT_COND(p_FmPort);
1677 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1678
1679 if (p_FmPort->imEn)
1680 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1681 ("available for non-independant mode ports only"));
1682
1683 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1684 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1685 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1686 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1687 ("available for Rx and offline parsing ports only"));
1688
1689 if (!p_FmPort->pcdEngines)
1690 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
1691
1692 /* get PCD registers pointers */
1693 switch (p_FmPort->portType)
1694 {
1695 case (e_FM_PORT_TYPE_RX_10G):
1696 case (e_FM_PORT_TYPE_RX):
1697 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1698 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1699 break;
1700 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1701 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1702 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1703 break;
1704 default:
1705 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1706 }
1707
1708 if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1709 != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1710 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1711 ("port has to be detached previousely"));
1712
1713 WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1714
1715 /* "cut" PCD out of the port's flow - go to BMI */
1716 /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
1717
1718 if (p_FmPort->pcdEngines & FM_PCD_PRS)
1719 {
1720 /* stop parser */
1721 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1722 /* wait for parser to be in idle state */
1723 while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1724 ;
1725 }
1726
1727 if (p_FmPort->pcdEngines & FM_PCD_KG)
1728 {
1729 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1730
1731 /* unbind all schemes */
1732 p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
1733 &schemeBind);
1734
1735 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1736 if (err)
1737 RETURN_ERROR(MAJOR, err, NO_MSG);
1738
1739 err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
1740 p_FmPort->hardwarePortId,
1741 p_FmPort->clsPlanGrpId);
1742 if (err)
1743 RETURN_ERROR(MAJOR, err, NO_MSG);
1744 p_FmPort->useClsPlan = FALSE;
1745 }
1746
1747 if (p_FmPort->pcdEngines & FM_PCD_CC)
1748 {
1749 /* unbind - we need to get the treeId too */
1750 err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
1751 if (err)
1752 RETURN_ERROR(MAJOR, err, NO_MSG);
1753 }
1754
1755 p_FmPort->pcdEngines = 0;
1756
1757 return E_OK;
1758}
1759
1760static t_Error AttachPCD(t_FmPort *p_FmPort)
1761{
1762 volatile uint32_t *p_BmiNia = NULL;
1763
1764 ASSERT_COND(p_FmPort);
1765
1766 /* get PCD registers pointers */
1767 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1768 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1769 else
1770 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1771
1772 /* check that current NIA is BMI to BMI */
1773 if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
1774 != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1775 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1776 ("may be called only for ports in BMI-to-BMI state."));
1777
1778 if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1779 if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
1780 p_FmPort->orFmanCtrl) != E_OK)
1781 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1782
1783 if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
1784 {
1785 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1786 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
1787 p_FmPort->savedBmiCmne);
1788 else
1789 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
1790 p_FmPort->savedBmiCmne);
1791 }
1792
1793 if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1794 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
1795 p_FmPort->savedQmiPnen);
1796
1797 if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1798 {
1799 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1800 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1801 p_FmPort->savedBmiFene);
1802 else
1803 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1804 p_FmPort->savedBmiFene);
1805 }
1806
1807 if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
1808 {
1809 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1810 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
1811 p_FmPort->savedBmiFpne);
1812 else
1813 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
1814 p_FmPort->savedBmiFpne);
1815 }
1816
1817 if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
1818 {
1819 ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
1820
1821 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
1822 p_FmPort->savedBmiOfp);
1823 }
1824
1825 WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
1826
1827 if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1828 {
1829 p_FmPort->origNonRxQmiRegsPndn =
1830 GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
1831 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1832 p_FmPort->savedNonRxQmiRegsPndn);
1833 }
1834
1835 return E_OK;
1836}
1837
1838static t_Error DetachPCD(t_FmPort *p_FmPort)
1839{
1840 volatile uint32_t *p_BmiNia = NULL;
1841
1842 ASSERT_COND(p_FmPort);
1843
1844 /* get PCD registers pointers */
1845 if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1846 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1847 p_FmPort->origNonRxQmiRegsPndn);
1848
1849 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1850 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1851 else
1852 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1853
1854 WRITE_UINT32(
1855 *p_BmiNia,
1856 (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
1857
1858 if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
1859 FmPcdHcSync(p_FmPort->h_FmPcd);
1860
1861 if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1862 {
1863 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1864 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1865 NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1866 else
1867 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1868 NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1869 }
1870
1871 if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1872 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
1873 NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
1874
1875 if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1876 if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
1877 p_FmPort->orFmanCtrl) != E_OK)
1878 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1879
1880 p_FmPort->requiredAction = 0;
1881
1882 return E_OK;
1883}
1884
1885/*****************************************************************************/
1886/* Inter-module API routines */
1887/*****************************************************************************/
1888void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
1889{
1890 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1891 volatile uint32_t *p_BmiCfgReg = NULL;
1892 uint32_t tmpReg;
1893
1894 SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
1895 SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1896
1897 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
1898 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
1899 {
1900 REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
1901 return;
1902 }
1903
1904 p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
1905 tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
1906 tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
1907 tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
1908 & BMI_CMD_ATTR_MACCMD_SC_MASK);
1909
1910 WRITE_UINT32(*p_BmiCfgReg, tmpReg);
1911}
1912
1913uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
1914{
1915 return ((t_FmPort*)h_FmPort)->netEnvId;
1916}
1917
1918uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
1919{
1920 return ((t_FmPort*)h_FmPort)->hardwarePortId;
1921}
1922
1923uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
1924{
1925 return ((t_FmPort*)h_FmPort)->pcdEngines;
1926}
1927
1928#if (DPAA_VERSION >= 11)
1929t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
1930 void **p_Value)
1931{
1932 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1933 uint32_t muramPageOffset;
1934
1935 ASSERT_COND(p_FmPort);
1936 ASSERT_COND(p_Value);
1937
1938 if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
1939 {
1940 if (p_FmPort->gprFunc != gprFunc)
1941 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1942 ("gpr was assigned with different func"));
1943 }
1944 else
1945 {
1946 switch (gprFunc)
1947 {
1948 case (e_FM_PORT_GPR_MURAM_PAGE):
1949 p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
1950 256, 8);
1951 if (!p_FmPort->p_ParamsPage)
1952 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
1953
1954 IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
1955 muramPageOffset =
1956 (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
1957 - p_FmPort->fmMuramPhysBaseAddr);
1958 switch (p_FmPort->portType)
1959 {
1960 case (e_FM_PORT_TYPE_RX_10G):
1961 case (e_FM_PORT_TYPE_RX):
1962 WRITE_UINT32(
1963 p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
1964 muramPageOffset);
1965 break;
1966 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1967 WRITE_UINT32(
1968 p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
1969 muramPageOffset);
1970 break;
1971 default:
1972 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1973 ("Invalid port type"));
1974 }
1975 break;
1976 default:
1977 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1978 }
1979 p_FmPort->gprFunc = gprFunc;
1980 }
1981
1982 switch (p_FmPort->gprFunc)
1983 {
1984 case (e_FM_PORT_GPR_MURAM_PAGE):
1985 *p_Value = p_FmPort->p_ParamsPage;
1986 break;
1987 default:
1988 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1989 }
1990
1991 return E_OK;
1992}
1993#endif /* (DPAA_VERSION >= 11) */
1994
1995t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
1996 t_FmPortGetSetCcParams *p_CcParams)
1997{
1998 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1/*
2 * Copyright 2008-2012 Freescale Semiconductor Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Freescale Semiconductor nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33
34/******************************************************************************
35 @File fm_port.c
36
37 @Description FM driver routines implementation.
38 *//***************************************************************************/
39#include "error_ext.h"
40#include "std_ext.h"
41#include "string_ext.h"
42#include "sprint_ext.h"
43#include "debug_ext.h"
44#include "fm_muram_ext.h"
45
46#include "fman_common.h"
47#include "fm_port.h"
48#include "fm_port_dsar.h"
49#include "common/general.h"
50
51/****************************************/
52/* static functions */
53/****************************************/
54static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
55
56static t_Error CheckInitParameters(t_FmPort *p_FmPort)
57{
58 t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
59 struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
60 t_Error ans = E_OK;
61 uint32_t unusedMask;
62
63 if (p_FmPort->imEn)
64 {
65 if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
66 if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
67 > 2)
68 RETURN_ERROR(
69 MAJOR,
70 E_INVALID_VALUE,
71 ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
72
73 if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
74 return ERROR_CODE(ans);
75 }
76 else
77 {
78 /****************************************/
79 /* Rx only */
80 /****************************************/
81 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
82 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
83 {
84 /* external buffer pools */
85 if (!p_Params->extBufPools.numOfPoolsUsed)
86 RETURN_ERROR(
87 MAJOR,
88 E_INVALID_VALUE,
89 ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
90
91 if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
92 p_Params->p_BackupBmPools,
93 &p_Params->bufPoolDepletion) != E_OK)
94 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
95
96 /* Check that part of IC that needs copying is small enough to enter start margin */
97 if (p_Params->intContext.size
98 && (p_Params->intContext.size
99 + p_Params->intContext.extBufOffset
100 > p_Params->bufMargins.startMargins))
101 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
102 ("intContext.size is larger than start margins"));
103
104 if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
105 && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
106 RETURN_ERROR(
107 MAJOR,
108 E_INVALID_VALUE,
109 ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
110
111#ifdef FM_NO_BACKUP_POOLS
112 if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
113 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
114 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
115#endif /* FM_NO_BACKUP_POOLS */
116 }
117
118 /****************************************/
119 /* Non Rx ports */
120 /****************************************/
121 else
122 {
123 if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
124 RETURN_ERROR(
125 MAJOR,
126 E_INVALID_VALUE,
127 (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
128
129 /* to protect HW internal-context from overwrite */
130 if ((p_Params->intContext.size)
131 && (p_Params->intContext.intContextOffset
132 < MIN_TX_INT_OFFSET))
133 RETURN_ERROR(
134 MAJOR,
135 E_INVALID_VALUE,
136 ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
137
138 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
139 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
140 /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
141 || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
142 != DEFAULT_notSupported))
143 {
144 /* Check that not larger than 8 */
145 if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
146 || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
147 > MAX_FIFO_PIPELINE_DEPTH))
148 RETURN_ERROR(
149 MAJOR,
150 E_INVALID_VALUE,
151 ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
152 }
153 }
154
155 /****************************************/
156 /* Rx Or Offline Parsing */
157 /****************************************/
158 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
159 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
160 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
161 {
162 if (!p_Params->dfltFqid)
163 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
164 ("dfltFqid must be between 1 and 2^24-1"));
165#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
166 if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
167 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
168#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
169 }
170
171 /****************************************/
172 /* All ports */
173 /****************************************/
174 /* common BMI registers values */
175 /* Check that Queue Id is not larger than 2^24, and is not 0 */
176 if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
177 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
178 ("errFqid must be between 1 and 2^24-1"));
179 if (p_Params->dfltFqid & ~0x00FFFFFF)
180 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
181 ("dfltFqid must be between 1 and 2^24-1"));
182 }
183
184 /****************************************/
185 /* Rx only */
186 /****************************************/
187 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
188 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
189 {
190 if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
191 RETURN_ERROR(
192 MAJOR,
193 E_INVALID_VALUE,
194 ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
195 if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
196 || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
197 RETURN_ERROR(
198 MAJOR,
199 E_INVALID_VALUE,
200 ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
201 if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
202 RETURN_ERROR(
203 MAJOR,
204 E_INVALID_VALUE,
205 ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
206 if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
207 || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
208 RETURN_ERROR(
209 MAJOR,
210 E_INVALID_VALUE,
211 ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
212
213 /* Check that not larger than 16 */
214 if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
215 RETURN_ERROR(
216 MAJOR,
217 E_INVALID_VALUE,
218 ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
219
220 if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
221 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
222
223 /* extra FIFO size (allowed only to Rx ports) */
224 if (p_Params->setSizeOfFifo
225 && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
226 RETURN_ERROR(
227 MAJOR,
228 E_INVALID_VALUE,
229 ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
230
231 if (p_Params->bufPoolDepletion.poolsGrpModeEnable
232 && !p_Params->bufPoolDepletion.numOfPools)
233 RETURN_ERROR(
234 MAJOR,
235 E_INVALID_VALUE,
236 ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
237#ifdef FM_CSI_CFED_LIMIT
238 if (p_FmPort->fmRevInfo.majorRev == 4)
239 {
240 /* Check that not larger than 16 */
241 if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
242 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
243 }
244#endif /* FM_CSI_CFED_LIMIT */
245 }
246
247 /****************************************/
248 /* Non Rx ports */
249 /****************************************/
250 /* extra FIFO size (allowed only to Rx ports) */
251 else
252 if (p_FmPort->fifoBufs.extra)
253 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
254 (" No fifoBufs.extra for non Rx ports"));
255
256 /****************************************/
257 /* Tx only */
258 /****************************************/
259 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
260 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
261 {
262 if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
263 RETURN_ERROR(
264 MAJOR,
265 E_INVALID_VALUE,
266 ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
267 if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
268 RETURN_ERROR(
269 MAJOR,
270 E_INVALID_VALUE,
271 ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
272 if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
273 RETURN_ERROR(
274 MAJOR,
275 E_INVALID_VALUE,
276 ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
277 if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
278 || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
279 RETURN_ERROR(
280 MAJOR,
281 E_INVALID_VALUE,
282 ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
283
284 if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
285 if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
286 > 2)
287 RETURN_ERROR(
288 MAJOR, E_INVALID_VALUE,
289 ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
290 }
291
292 /****************************************/
293 /* Non Tx Ports */
294 /****************************************/
295 /* If discard override was selected , no frames may be discarded. */
296 else
297 if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
298 RETURN_ERROR(
299 MAJOR,
300 E_CONFLICT,
301 ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
302
303 /****************************************/
304 /* Rx and Offline parsing */
305 /****************************************/
306 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
307 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
308 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
309 {
310 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
311 unusedMask = BMI_STATUS_OP_MASK_UNUSED;
312 else
313 unusedMask = BMI_STATUS_RX_MASK_UNUSED;
314
315 /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
316 if (p_Params->errorsToDiscard & unusedMask)
317 RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
318 ("errorsToDiscard contains undefined bits"));
319 }
320
321 /****************************************/
322 /* Offline Ports */
323 /****************************************/
324#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
325 if ((p_FmPort->fmRevInfo.majorRev >= 6)
326 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
327 && p_Params->setNumOfOpenDmas
328 && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
329 RETURN_ERROR(
330 MAJOR,
331 E_INVALID_VALUE,
332 ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
333#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
334
335 /****************************************/
336 /* Offline & HC Ports */
337 /****************************************/
338 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
339 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
340 {
341#ifndef FM_FRAME_END_PARAMS_FOR_OP
342 if ((p_FmPort->fmRevInfo.majorRev < 6) &&
343 (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
344 /* this is an indication that user called config for this mode which is not supported in this integration */
345 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
346#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
347
348#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
349 if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
350 (p_FmPort->fmRevInfo.majorRev >= 6))) &&
351 (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
352 /* this is an indication that user called config for this mode which is not supported in this integration */
353 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
354#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
355 }
356
357 /****************************************/
358 /* All ports */
359 /****************************************/
360 /* Check that not larger than 16 */
361 if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
362 && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
363 RETURN_ERROR(
364 MAJOR,
365 E_INVALID_VALUE,
366 ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
367
368 if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
369 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
370
371 /* common BMI registers values */
372 if (p_Params->setNumOfTasks
373 && ((!p_FmPort->tasks.num)
374 || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
375 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
376 ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
377 if (p_Params->setNumOfTasks
378 && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
379 RETURN_ERROR(
380 MAJOR,
381 E_INVALID_VALUE,
382 ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
383 if (p_Params->setNumOfOpenDmas
384 && ((!p_FmPort->openDmas.num)
385 || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
386 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
387 ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
388 if (p_Params->setNumOfOpenDmas
389 && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
390 RETURN_ERROR(
391 MAJOR,
392 E_INVALID_VALUE,
393 ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
394 if (p_Params->setSizeOfFifo
395 && (!p_FmPort->fifoBufs.num
396 || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
397 RETURN_ERROR(
398 MAJOR,
399 E_INVALID_VALUE,
400 ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
401 if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
402 RETURN_ERROR(
403 MAJOR, E_INVALID_VALUE,
404 ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
405
406#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
407 if (p_FmPort->fmRevInfo.majorRev == 4)
408 if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
409 /* this is an indication that user called config for this mode which is not supported in this integration */
410 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
411#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
412
413 return E_OK;
414}
415
416static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
417{
418 uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
419
420 /*************************/
421 /* TX PORTS */
422 /*************************/
423 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
424 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
425 {
426 minFifoSizeRequired =
427 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
428 + (3 * BMI_FIFO_UNITS));
429 if (!p_FmPort->imEn)
430 minFifoSizeRequired +=
431 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
432 * BMI_FIFO_UNITS;
433
434 optFifoSizeForB2B = minFifoSizeRequired;
435
436 /* Add some margin for back-to-back capability to improve performance,
437 allows the hardware to pipeline new frame dma while the previous
438 frame not yet transmitted. */
439 if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
440 optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
441 else
442 optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
443 }
444
445 /*************************/
446 /* RX IM PORTS */
447 /*************************/
448 else
449 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
450 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
451 && p_FmPort->imEn)
452 {
453 optFifoSizeForB2B =
454 minFifoSizeRequired =
455 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
456 + (4 * BMI_FIFO_UNITS));
457 }
458
459 /*************************/
460 /* RX non-IM PORTS */
461 /*************************/
462 else
463 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
464 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
465 && !p_FmPort->imEn)
466 {
467 if (p_FmPort->fmRevInfo.majorRev == 4)
468 {
469 if (p_FmPort->rxPoolsParams.numOfPools == 1)
470 minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
471 else
472 minFifoSizeRequired =
473 (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
474 + (7 * BMI_FIFO_UNITS));
475 }
476 else
477 {
478#if (DPAA_VERSION >= 11)
479 minFifoSizeRequired =
480 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
481 + (5 * BMI_FIFO_UNITS));
482 /* 4 according to spec + 1 for FOF>0 */
483#else
484 minFifoSizeRequired = (uint32_t)
485 (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
486 + (7*BMI_FIFO_UNITS));
487#endif /* (DPAA_VERSION >= 11) */
488 }
489
490 optFifoSizeForB2B = minFifoSizeRequired;
491
492 /* Add some margin for back-to-back capability to improve performance,
493 allows the hardware to pipeline new frame dma while the previous
494 frame not yet transmitted. */
495 if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
496 optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
497 else
498 optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
499 }
500
501 /* For O/H ports, check fifo size and update if necessary */
502 else
503 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
504 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
505 {
506#if (DPAA_VERSION >= 11)
507 optFifoSizeForB2B =
508 minFifoSizeRequired =
509 (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
510 + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
511 + 5) * BMI_FIFO_UNITS));
512 /* 4 according to spec + 1 for FOF>0 */
513#else
514 optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
515#endif /* (DPAA_VERSION >= 11) */
516 }
517
518 ASSERT_COND(minFifoSizeRequired > 0);
519 ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
520
521 /* Verify the size */
522 if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
523 DBG(INFO,
524 ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
525 else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
526 DBG(INFO,
527 ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
528
529 return E_OK;
530}
531
532static void FmPortDriverParamFree(t_FmPort *p_FmPort)
533{
534 if (p_FmPort->p_FmPortDriverParam)
535 {
536 XX_Free(p_FmPort->p_FmPortDriverParam);
537 p_FmPort->p_FmPortDriverParam = NULL;
538 }
539}
540
541static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
542{
543 t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
544 t_FmBufPoolDepletion *p_BufPoolDepletion =
545 &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
546 uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
547 uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
548 int i = 0, j = 0, err;
549 struct fman_port_bpools bpools;
550
551 memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
552 memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
553 memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
554
555 FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
556 sizesArray);
557
558 /* Prepare flibs bpools structure */
559 memset(&bpools, 0, sizeof(struct fman_port_bpools));
560 bpools.count = p_ExtBufPools->numOfPoolsUsed;
561 bpools.counters_enable = TRUE;
562 for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
563 {
564 bpools.bpool[i].bpid = orderedArray[i];
565 bpools.bpool[i].size = sizesArray[orderedArray[i]];
566 /* functionality available only for some derivatives (limited by config) */
567 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
568 for (j = 0;
569 j
570 < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
571 j++)
572 if (orderedArray[i]
573 == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
574 {
575 bpools.bpool[i].is_backup = TRUE;
576 break;
577 }
578 }
579
580 /* save pools parameters for later use */
581 p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
582 p_FmPort->rxPoolsParams.largestBufSize =
583 sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
584 p_FmPort->rxPoolsParams.secondLargestBufSize =
585 sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
586
587 /* FMBM_RMPD reg. - pool depletion */
588 if (p_BufPoolDepletion->poolsGrpModeEnable)
589 {
590 bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
591 for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
592 {
593 if (p_BufPoolDepletion->poolsToConsider[i])
594 {
595 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
596 {
597 if (i == orderedArray[j])
598 {
599 bpools.bpool[j].grp_bp_depleted = TRUE;
600 break;
601 }
602 }
603 }
604 }
605 }
606
607 if (p_BufPoolDepletion->singlePoolModeEnable)
608 {
609 for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
610 {
611 if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
612 {
613 for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
614 {
615 if (i == orderedArray[j])
616 {
617 bpools.bpool[j].single_bp_depleted = TRUE;
618 break;
619 }
620 }
621 }
622 }
623 }
624
625#if (DPAA_VERSION >= 11)
626 /* fill QbbPEV */
627 if (p_BufPoolDepletion->poolsGrpModeEnable
628 || p_BufPoolDepletion->singlePoolModeEnable)
629 {
630 for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
631 {
632 if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
633 {
634 bpools.bpool[i].pfc_priorities_en = TRUE;
635 }
636 }
637 }
638#endif /* (DPAA_VERSION >= 11) */
639
640 /* Issue flibs function */
641 err = fman_port_set_bpools(&p_FmPort->port, &bpools);
642 if (err != 0)
643 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
644
645 if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
646 XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
647
648 return E_OK;
649}
650
651static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
652{
653 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
654 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
655 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
656 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
657 FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
658 return E_OK;
659}
660
661static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
662{
663 t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
664 struct fman_port_params portParams;
665 uint32_t tmpVal;
666 t_Error err;
667
668 /* Set up flibs parameters and issue init function */
669
670 memset(&portParams, 0, sizeof(struct fman_port_params));
671 portParams.discard_mask = p_DriverParams->errorsToDiscard;
672 portParams.dflt_fqid = p_DriverParams->dfltFqid;
673 portParams.err_fqid = p_DriverParams->errFqid;
674 portParams.deq_sp = p_DriverParams->deqSubPortal;
675 portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
676 switch (p_FmPort->portType)
677 {
678 case (e_FM_PORT_TYPE_RX_10G):
679 case (e_FM_PORT_TYPE_RX):
680 portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
681 if (!p_FmPort->imEn)
682 {
683 if (p_DriverParams->forwardReuseIntContext)
684 p_DriverParams->dfltCfg.rx_fd_bits =
685 (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
686 }
687 break;
688
689 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
690 portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
691 break;
692 break;
693
694 default:
695 break;
696 }
697
698 tmpVal =
699 (uint32_t)(
700 (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
701 / OFFSET_UNITS + 1) :
702 (p_FmPort->internalBufferOffset / OFFSET_UNITS));
703 p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
704 p_DriverParams->dfltCfg.int_buf_start_margin =
705 p_FmPort->internalBufferOffset;
706
707 p_DriverParams->dfltCfg.ext_buf_start_margin =
708 p_DriverParams->bufMargins.startMargins;
709 p_DriverParams->dfltCfg.ext_buf_end_margin =
710 p_DriverParams->bufMargins.endMargins;
711
712 p_DriverParams->dfltCfg.ic_ext_offset =
713 p_DriverParams->intContext.extBufOffset;
714 p_DriverParams->dfltCfg.ic_int_offset =
715 p_DriverParams->intContext.intContextOffset;
716 p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
717
718 p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
719 p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
720 p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
721
722 p_DriverParams->dfltCfg.perf_cnt_params.task_val =
723 (uint8_t)p_FmPort->tasks.num;
724 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
725 p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
726 else
727 p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
728 p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
729 (uint8_t)p_FmPort->openDmas.num;
730 p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
731
732 if (0
733 != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
734 &portParams))
735 RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
736
737 if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
738 RETURN_ERROR(MAJOR, err, NO_MSG);
739 else
740 {
741 // from QMIInit
742 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
743 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
744 {
745 if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
746 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
747 FALSE);
748 else
749 FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
750 TRUE);
751 }
752 }
753 /* The code bellow is a trick so the FM will not release the buffer
754 to BM nor will try to enqueue the frame to QM */
755 if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
756 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
757 {
758 if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
759 {
760 /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
761 * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
762 * buffers to BM regardless of fmbm_tfene
763 */
764 WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
765 WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
766 NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
767 }
768 }
769
770 return E_OK;
771}
772
773static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
774{
775 UNUSED(p_FmPort);
776
777 switch (counter)
778 {
779 case (e_FM_PORT_COUNTERS_CYCLE):
780 case (e_FM_PORT_COUNTERS_TASK_UTIL):
781 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
782 case (e_FM_PORT_COUNTERS_DMA_UTIL):
783 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
784 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
785 case (e_FM_PORT_COUNTERS_FRAME):
786 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
787 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
788 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
789 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
790 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
791 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
792 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
793 case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
794 return TRUE;
795 default:
796 return FALSE;
797 }
798}
799
800static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
801{
802 UNUSED(p_FmPort);
803
804 switch (counter)
805 {
806 case (e_FM_PORT_COUNTERS_CYCLE):
807 case (e_FM_PORT_COUNTERS_TASK_UTIL):
808 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
809 case (e_FM_PORT_COUNTERS_DMA_UTIL):
810 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
811 case (e_FM_PORT_COUNTERS_FRAME):
812 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
813 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
814 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
815 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
816 return TRUE;
817 default:
818 return FALSE;
819 }
820}
821
822static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
823{
824 switch (counter)
825 {
826 case (e_FM_PORT_COUNTERS_CYCLE):
827 case (e_FM_PORT_COUNTERS_TASK_UTIL):
828 case (e_FM_PORT_COUNTERS_DMA_UTIL):
829 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
830 case (e_FM_PORT_COUNTERS_FRAME):
831 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
832 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
833 case (e_FM_PORT_COUNTERS_WRED_DISCARD):
834 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
835 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
836 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
837 return TRUE;
838 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
839 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
840 return FALSE;
841 else
842 return TRUE;
843 default:
844 return FALSE;
845 }
846}
847
848static t_Error BmiPortCheckAndGetCounterType(
849 t_FmPort *p_FmPort, e_FmPortCounters counter,
850 enum fman_port_stats_counters *p_StatsType,
851 enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
852{
853 volatile uint32_t *p_Reg;
854 bool isValid;
855
856 switch (p_FmPort->portType)
857 {
858 case (e_FM_PORT_TYPE_RX_10G):
859 case (e_FM_PORT_TYPE_RX):
860 p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
861 isValid = CheckRxBmiCounter(p_FmPort, counter);
862 break;
863 case (e_FM_PORT_TYPE_TX_10G):
864 case (e_FM_PORT_TYPE_TX):
865 p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
866 isValid = CheckTxBmiCounter(p_FmPort, counter);
867 break;
868 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
869 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
870 p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
871 isValid = CheckOhBmiCounter(p_FmPort, counter);
872 break;
873 default:
874 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
875 }
876
877 if (!isValid)
878 RETURN_ERROR(MINOR, E_INVALID_STATE,
879 ("Requested counter is not available for this port type"));
880
881 /* check that counters are enabled */
882 switch (counter)
883 {
884 case (e_FM_PORT_COUNTERS_CYCLE):
885 case (e_FM_PORT_COUNTERS_TASK_UTIL):
886 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
887 case (e_FM_PORT_COUNTERS_DMA_UTIL):
888 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
889 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
890 /* performance counters - may be read when disabled */
891 *p_IsStats = FALSE;
892 break;
893 case (e_FM_PORT_COUNTERS_FRAME):
894 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
895 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
896 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
897 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
898 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
899 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
900 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
901 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
902 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
903 case (e_FM_PORT_COUNTERS_WRED_DISCARD):
904 *p_IsStats = TRUE;
905 if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
906 RETURN_ERROR(MINOR, E_INVALID_STATE,
907 ("Requested counter was not enabled"));
908 break;
909 default:
910 break;
911 }
912
913 /* Set counter */
914 switch (counter)
915 {
916 case (e_FM_PORT_COUNTERS_CYCLE):
917 *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
918 break;
919 case (e_FM_PORT_COUNTERS_TASK_UTIL):
920 *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
921 break;
922 case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
923 *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
924 break;
925 case (e_FM_PORT_COUNTERS_DMA_UTIL):
926 *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
927 break;
928 case (e_FM_PORT_COUNTERS_FIFO_UTIL):
929 *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
930 break;
931 case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
932 *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
933 break;
934 case (e_FM_PORT_COUNTERS_FRAME):
935 *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
936 break;
937 case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
938 *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
939 break;
940 case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
941 *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
942 break;
943 case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
944 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
945 break;
946 case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
947 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
948 break;
949 case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
950 *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
951 break;
952 case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
953 *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
954 break;
955 case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
956 *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
957 break;
958 case (e_FM_PORT_COUNTERS_WRED_DISCARD):
959 *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
960 break;
961 case (e_FM_PORT_COUNTERS_LENGTH_ERR):
962 *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
963 break;
964 case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
965 *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
966 break;
967 default:
968 break;
969 }
970
971 return E_OK;
972}
973
974static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
975 t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
976 uint32_t *p_SoftSeqAttachReg)
977{
978 uint8_t hdrNum, Ipv4HdrNum;
979 u_FmPcdHdrPrsOpts *p_prsOpts;
980 uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
981
982 if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
983 || IS_SPECIAL_HEADER(p_HdrParams->hdr))
984 RETURN_ERROR(
985 MAJOR, E_NOT_SUPPORTED,
986 ("No additional parameters for private or special headers."));
987
988 if (p_HdrParams->errDisable)
989 tmpReg |= PRS_HDR_ERROR_DIS;
990
991 /* Set parser options */
992 if (p_HdrParams->usePrsOpts)
993 {
994 p_prsOpts = &p_HdrParams->prsOpts;
995 switch (p_HdrParams->hdr)
996 {
997 case (HEADER_TYPE_MPLS):
998 if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
999 tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
1000 hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
1001 if (hdrNum == ILLEGAL_HDR_NUM)
1002 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1003 Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1004 if (hdrNum < Ipv4HdrNum)
1005 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1006 ("Header must be equal or higher than IPv4"));
1007 tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
1008 << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1009 break;
1010 case (HEADER_TYPE_PPPoE):
1011 if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
1012 tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
1013 break;
1014 case (HEADER_TYPE_IPv6):
1015 if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
1016 tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
1017 break;
1018 case (HEADER_TYPE_TCP):
1019 if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
1020 tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
1021 else
1022 tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
1023 break;
1024 case (HEADER_TYPE_UDP):
1025 if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
1026 tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
1027 else
1028 tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
1029 break;
1030 default:
1031 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
1032 }
1033 }
1034
1035 /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
1036 if (p_HdrParams->swPrsEnable)
1037 {
1038 tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
1039 p_HdrParams->indexPerHdr);
1040 if (tmpPrsOffset == ILLEGAL_BASE)
1041 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1042 tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
1043 }
1044 *p_SoftSeqAttachReg = tmpReg;
1045
1046 return E_OK;
1047}
1048
1049static uint32_t GetPortSchemeBindParams(
1050 t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
1051{
1052 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1053 uint32_t walking1Mask = 0x80000000, tmp;
1054 uint8_t idx = 0;
1055
1056 p_SchemeBind->netEnvId = p_FmPort->netEnvId;
1057 p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
1058 p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
1059 p_SchemeBind->numOfSchemes = 0;
1060 tmp = p_FmPort->schemesPerPortVector;
1061 if (tmp)
1062 {
1063 while (tmp)
1064 {
1065 if (tmp & walking1Mask)
1066 {
1067 p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
1068 p_SchemeBind->numOfSchemes++;
1069 tmp &= ~walking1Mask;
1070 }
1071 walking1Mask >>= 1;
1072 idx++;
1073 }
1074 }
1075
1076 return tmp;
1077}
1078
1079static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
1080{
1081 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1082 volatile uint32_t *p_BmiCfgReg = NULL;
1083 uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
1084 uint32_t lcv, walking1Mask = 0x80000000;
1085 uint8_t cnt = 0;
1086
1087 ASSERT_COND(p_FmPort);
1088 ASSERT_COND(p_FmPort->h_FmPcd);
1089 ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
1090
1091 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1092 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
1093 return;
1094
1095 p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
1096 /* get LCV for MACSEC */
1097 if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
1098 != 0)
1099 {
1100 while (!(lcv & walking1Mask))
1101 {
1102 cnt++;
1103 walking1Mask >>= 1;
1104 }
1105
1106 macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
1107 WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
1108 }
1109}
1110
1111static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
1112{
1113 t_Error err = E_OK;
1114 uint32_t tmpReg;
1115 volatile uint32_t *p_BmiNia = NULL;
1116 volatile uint32_t *p_BmiPrsNia = NULL;
1117 volatile uint32_t *p_BmiPrsStartOffset = NULL;
1118 volatile uint32_t *p_BmiInitPrsResult = NULL;
1119 volatile uint32_t *p_BmiCcBase = NULL;
1120 uint16_t hdrNum, L3HdrNum, greHdrNum;
1121 int i;
1122 bool isEmptyClsPlanGrp;
1123 uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
1124 uint16_t absoluteProfileId;
1125 uint8_t physicalSchemeId;
1126 uint32_t ccTreePhysOffset;
1127 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1128 uint32_t initialSwPrs = 0;
1129
1130 ASSERT_COND(p_FmPort);
1131 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1132
1133 if (p_FmPort->imEn)
1134 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1135 ("available for non-independant mode ports only"));
1136
1137 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1138 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1139 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1140 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1141 ("available for Rx and offline parsing ports only"));
1142
1143 p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
1144
1145 p_FmPort->pcdEngines = 0;
1146
1147 /* initialize p_FmPort->pcdEngines field in port's structure */
1148 switch (p_PcdParams->pcdSupport)
1149 {
1150 case (e_FM_PORT_PCD_SUPPORT_NONE):
1151 RETURN_ERROR(
1152 MAJOR,
1153 E_INVALID_STATE,
1154 ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
1155 case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1156 p_FmPort->pcdEngines |= FM_PCD_PRS;
1157 break;
1158 case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
1159 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1160 break;
1161 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1162 p_FmPort->pcdEngines |= FM_PCD_PRS;
1163 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1164 break;
1165 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1166 p_FmPort->pcdEngines |= FM_PCD_PRS;
1167 p_FmPort->pcdEngines |= FM_PCD_KG;
1168 break;
1169 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1170 p_FmPort->pcdEngines |= FM_PCD_PRS;
1171 p_FmPort->pcdEngines |= FM_PCD_CC;
1172 p_FmPort->pcdEngines |= FM_PCD_KG;
1173 break;
1174 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1175 p_FmPort->pcdEngines |= FM_PCD_PRS;
1176 p_FmPort->pcdEngines |= FM_PCD_KG;
1177 p_FmPort->pcdEngines |= FM_PCD_CC;
1178 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1179 break;
1180 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1181 p_FmPort->pcdEngines |= FM_PCD_PRS;
1182 p_FmPort->pcdEngines |= FM_PCD_CC;
1183 break;
1184 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1185 p_FmPort->pcdEngines |= FM_PCD_PRS;
1186 p_FmPort->pcdEngines |= FM_PCD_CC;
1187 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1188 break;
1189 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1190 p_FmPort->pcdEngines |= FM_PCD_PRS;
1191 p_FmPort->pcdEngines |= FM_PCD_KG;
1192 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1193 break;
1194 case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
1195 p_FmPort->pcdEngines |= FM_PCD_CC;
1196 break;
1197#ifdef FM_CAPWAP_SUPPORT
1198 case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
1199 p_FmPort->pcdEngines |= FM_PCD_CC;
1200 p_FmPort->pcdEngines |= FM_PCD_KG;
1201 break;
1202 case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
1203 p_FmPort->pcdEngines |= FM_PCD_CC;
1204 p_FmPort->pcdEngines |= FM_PCD_KG;
1205 p_FmPort->pcdEngines |= FM_PCD_PLCR;
1206 break;
1207#endif /* FM_CAPWAP_SUPPORT */
1208
1209 default:
1210 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
1211 }
1212
1213 if ((p_FmPort->pcdEngines & FM_PCD_PRS)
1214 && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
1215 > FM_PCD_PRS_NUM_OF_HDRS))
1216 RETURN_ERROR(
1217 MAJOR,
1218 E_INVALID_VALUE,
1219 ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
1220
1221 /* check that parameters exist for each and only each defined engine */
1222 if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
1223 || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
1224 != !!p_PcdParams->p_KgParams)
1225 || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
1226 != !!p_PcdParams->p_CcParams))
1227 RETURN_ERROR(
1228 MAJOR,
1229 E_INVALID_STATE,
1230 ("PCD initialization structure is not consistent with pcdSupport"));
1231
1232 /* get PCD registers pointers */
1233 switch (p_FmPort->portType)
1234 {
1235 case (e_FM_PORT_TYPE_RX_10G):
1236 case (e_FM_PORT_TYPE_RX):
1237 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1238 p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
1239 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1240 p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
1241 p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
1242 break;
1243 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1244 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1245 p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
1246 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1247 p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
1248 p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
1249 break;
1250 default:
1251 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1252 }
1253
1254 /* set PCD port parameter */
1255 if (p_FmPort->pcdEngines & FM_PCD_CC)
1256 {
1257 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
1258 p_PcdParams->p_CcParams->h_CcTree,
1259 &ccTreePhysOffset, p_FmPort);
1260 if (err)
1261 RETURN_ERROR(MAJOR, err, NO_MSG);
1262
1263 WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
1264 p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
1265 }
1266
1267 if (p_FmPort->pcdEngines & FM_PCD_KG)
1268 {
1269 if (p_PcdParams->p_KgParams->numOfSchemes == 0)
1270 RETURN_ERROR(
1271 MAJOR,
1272 E_INVALID_VALUE,
1273 ("For ports using Keygen, at least one scheme must be bound. "));
1274
1275 err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
1276 p_FmPort->hardwarePortId,
1277 p_FmPort->netEnvId,
1278 p_FmPort->optArray,
1279 &p_FmPort->clsPlanGrpId,
1280 &isEmptyClsPlanGrp);
1281 if (err)
1282 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
1283 ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
1284
1285 p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
1286
1287 schemeBind.netEnvId = p_FmPort->netEnvId;
1288 schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
1289 schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
1290 schemeBind.useClsPlan = p_FmPort->useClsPlan;
1291
1292 /* for each scheme */
1293 for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1294 {
1295 ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
1296 physicalSchemeId = FmPcdKgGetSchemeId(
1297 p_PcdParams->p_KgParams->h_Schemes[i]);
1298 schemeBind.schemesIds[i] = physicalSchemeId;
1299 /* build vector */
1300 p_FmPort->schemesPerPortVector |= 1
1301 << (31 - (uint32_t)physicalSchemeId);
1302#if (DPAA_VERSION >= 11)
1303 /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
1304 if !VSPE - in port, for relevant scheme VSPE can not be set*/
1305 if (!p_FmPort->vspe
1306 && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
1307 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1308 ("VSPE is not at port level"));
1309#endif /* (DPAA_VERSION >= 11) */
1310 }
1311
1312 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1313 if (err)
1314 RETURN_ERROR(MAJOR, err, NO_MSG);
1315 }
1316
1317 /***************************/
1318 /* configure NIA after BMI */
1319 /***************************/
1320 /* rfne may contain FDCS bits, so first we read them. */
1321 p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
1322
1323 /* If policer is used directly after BMI or PRS */
1324 if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
1325 && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
1326 || (p_PcdParams->pcdSupport
1327 == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
1328 {
1329 if (!p_PcdParams->p_PlcrParams->h_Profile)
1330 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1331 ("Profile should be initialized"));
1332
1333 absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
1334 p_PcdParams->p_PlcrParams->h_Profile);
1335
1336 if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
1337 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1338 ("Private port profile not valid."));
1339
1340 tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
1341
1342 if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
1343 /* update BMI HPNIA */
1344 WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
1345 else
1346 /* e_FM_PCD_SUPPORT_PLCR_ONLY */
1347 /* update BMI NIA */
1348 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
1349 }
1350
1351 /* if CC is used directly after BMI */
1352 if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
1353#ifdef FM_CAPWAP_SUPPORT
1354 || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
1355 || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
1356#endif /* FM_CAPWAP_SUPPORT */
1357 )
1358 {
1359 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1360 RETURN_ERROR(
1361 MAJOR,
1362 E_INVALID_OPERATION,
1363 ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
1364 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
1365 /* check that prs start offset == RIM[FOF] */
1366 }
1367
1368 if (p_FmPort->pcdEngines & FM_PCD_PRS)
1369 {
1370 ASSERT_COND(p_PcdParams->p_PrsParams);
1371#if (DPAA_VERSION >= 11)
1372 if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
1373 hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
1374 else
1375 {
1376#endif /* (DPAA_VERSION >= 11) */
1377 /* if PRS is used it is always first */
1378 hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
1379 if (hdrNum == ILLEGAL_HDR_NUM)
1380 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
1381#if (DPAA_VERSION >= 11)
1382 }
1383#endif /* (DPAA_VERSION >= 11) */
1384 p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
1385 /* set after parser NIA */
1386 tmpReg = 0;
1387 switch (p_PcdParams->pcdSupport)
1388 {
1389 case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
1390 WRITE_UINT32(*p_BmiPrsNia,
1391 GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
1392 break;
1393 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
1394 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
1395 tmpReg = NIA_KG_CC_EN;
1396 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
1397 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
1398 if (p_PcdParams->p_KgParams->directScheme)
1399 {
1400 physicalSchemeId = FmPcdKgGetSchemeId(
1401 p_PcdParams->p_KgParams->h_DirectScheme);
1402 /* check that this scheme was bound to this port */
1403 for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
1404 if (p_PcdParams->p_KgParams->h_DirectScheme
1405 == p_PcdParams->p_KgParams->h_Schemes[i])
1406 break;
1407 if (i == p_PcdParams->p_KgParams->numOfSchemes)
1408 RETURN_ERROR(
1409 MAJOR,
1410 E_INVALID_VALUE,
1411 ("Direct scheme is not one of the port selected schemes."));
1412 tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
1413 }
1414 WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
1415 break;
1416 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
1417 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
1418 WRITE_UINT32(*p_BmiPrsNia,
1419 (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
1420 break;
1421 case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
1422 break;
1423 default:
1424 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
1425 }
1426
1427 /* set start parsing offset */
1428 WRITE_UINT32(*p_BmiPrsStartOffset,
1429 p_PcdParams->p_PrsParams->parsingOffset);
1430
1431 /************************************/
1432 /* Parser port parameters */
1433 /************************************/
1434 /* stop before configuring */
1435 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1436 /* wait for parser to be in idle state */
1437 while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1438 ;
1439
1440 /* set soft seq attachment register */
1441 memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
1442
1443 /* set protocol options */
1444 for (i = 0; p_FmPort->optArray[i]; i++)
1445 switch (p_FmPort->optArray[i])
1446 {
1447 case (ETH_BROADCAST):
1448 hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1449 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
1450 break;
1451 case (ETH_MULTICAST):
1452 hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
1453 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
1454 break;
1455 case (VLAN_STACKED):
1456 hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
1457 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
1458 break;
1459 case (MPLS_STACKED):
1460 hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1461 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
1462 break;
1463 case (IPV4_BROADCAST_1):
1464 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1465 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
1466 break;
1467 case (IPV4_MULTICAST_1):
1468 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1469 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
1470 break;
1471 case (IPV4_UNICAST_2):
1472 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1473 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
1474 break;
1475 case (IPV4_MULTICAST_BROADCAST_2):
1476 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1477 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
1478 break;
1479 case (IPV6_MULTICAST_1):
1480 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1481 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
1482 break;
1483 case (IPV6_UNICAST_2):
1484 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1485 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
1486 break;
1487 case (IPV6_MULTICAST_2):
1488 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1489 tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
1490 break;
1491 }
1492
1493 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1494 HEADER_TYPE_UDP_ENCAP_ESP))
1495 {
1496 if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
1497 RETURN_ERROR(
1498 MINOR, E_INVALID_VALUE,
1499 ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
1500
1501 p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
1502 HEADER_TYPE_UDP;
1503 p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
1504 TRUE;
1505 p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
1506 }
1507
1508 /* set MPLS default next header - HW reset workaround */
1509 hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
1510 tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
1511 L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
1512 tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
1513
1514 /* for GRE, disable errors */
1515 greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
1516 tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
1517
1518 /* For UDP remove PAD from L4 checksum calculation */
1519 hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
1520 tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
1521 /* For TCP remove PAD from L4 checksum calculation */
1522 hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
1523 tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
1524
1525 /* config additional params for specific headers */
1526 for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
1527 i++)
1528 {
1529 /* case for using sw parser as the initial NIA address, before
1530 * HW parsing
1531 */
1532 if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
1533 p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
1534 {
1535 initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
1536 p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
1537 if (initialSwPrs == ILLEGAL_BASE)
1538 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1539
1540 /* clear parser first HXS */
1541 p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
1542 /* rewrite with soft parser start */
1543 p_FmPort->savedBmiNia |= initialSwPrs;
1544 continue;
1545 }
1546
1547 hdrNum =
1548 GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
1549 if (hdrNum == ILLEGAL_HDR_NUM)
1550 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1551 if (hdrNum == NO_HDR_NUM)
1552 RETURN_ERROR(
1553 MAJOR, E_INVALID_VALUE,
1554 ("Private headers may not use additional parameters"));
1555
1556 err = AdditionalPrsParams(
1557 p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
1558 &tmpHxs[hdrNum]);
1559 if (err)
1560 RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
1561 }
1562
1563 /* Check if ip-reassembly port - need to link sw-parser code */
1564 if (p_FmPort->h_IpReassemblyManip)
1565 {
1566 /* link to sw parser code for IP Frag - only if no other code is applied. */
1567 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
1568 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1569 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
1570 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1571 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1572 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
1573 } else {
1574 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
1575 {
1576 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1577 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1578 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1579 } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1580 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
1581 {
1582 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1583 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1584 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
1585 }
1586 }
1587
1588#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
1589 if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
1590 HEADER_TYPE_UDP_LITE))
1591 {
1592 /* link to sw parser code for udp lite - only if no other code is applied. */
1593 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1594 if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
1595 tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
1596 }
1597#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
1598 for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
1599 {
1600 /* For all header set LCV as taken from netEnv*/
1601 WRITE_UINT32(
1602 p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
1603 FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
1604 /* set HXS register according to default+Additional params+protocol options */
1605 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
1606 tmpHxs[i]);
1607 }
1608
1609 /* set tpid. */
1610 tmpReg = PRS_TPID_DFLT;
1611 if (p_PcdParams->p_PrsParams->setVlanTpid1)
1612 {
1613 tmpReg &= PRS_TPID2_MASK;
1614 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
1615 << PRS_PCTPID_SHIFT;
1616 }
1617 if (p_PcdParams->p_PrsParams->setVlanTpid2)
1618 {
1619 tmpReg &= PRS_TPID1_MASK;
1620 tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
1621 }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
1622
1623 /* enable parser */
1624 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
1625
1626 if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
1627 p_FmPort->privateInfo =
1628 p_PcdParams->p_PrsParams->prsResultPrivateInfo;
1629
1630 } /* end parser */
1631 else {
1632 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
1633 && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1634 {
1635 hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
1636 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
1637 (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
1638 }
1639
1640 WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1641
1642 p_FmPort->privateInfo = 0;
1643 }
1644
1645 FmPortCheckNApplyMacsec(p_FmPort);
1646
1647 WRITE_UINT32(
1648 *p_BmiPrsStartOffset,
1649 GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
1650
1651 /* set initial parser result - used for all engines */
1652 for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
1653 {
1654 if (!i)
1655 WRITE_UINT32(
1656 *(p_BmiInitPrsResult),
1657 (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
1658 else
1659 {
1660 if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
1661 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
1662 else
1663 WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
1664 }
1665 }
1666
1667 return E_OK;
1668}
1669
1670static t_Error DeletePcd(t_FmPort *p_FmPort)
1671{
1672 t_Error err = E_OK;
1673 volatile uint32_t *p_BmiNia = NULL;
1674 volatile uint32_t *p_BmiPrsStartOffset = NULL;
1675
1676 ASSERT_COND(p_FmPort);
1677 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1678
1679 if (p_FmPort->imEn)
1680 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1681 ("available for non-independant mode ports only"));
1682
1683 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
1684 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
1685 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
1686 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1687 ("available for Rx and offline parsing ports only"));
1688
1689 if (!p_FmPort->pcdEngines)
1690 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
1691
1692 /* get PCD registers pointers */
1693 switch (p_FmPort->portType)
1694 {
1695 case (e_FM_PORT_TYPE_RX_10G):
1696 case (e_FM_PORT_TYPE_RX):
1697 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1698 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
1699 break;
1700 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1701 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1702 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
1703 break;
1704 default:
1705 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
1706 }
1707
1708 if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1709 != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1710 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
1711 ("port has to be detached previousely"));
1712
1713 WRITE_UINT32(*p_BmiPrsStartOffset, 0);
1714
1715 /* "cut" PCD out of the port's flow - go to BMI */
1716 /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
1717
1718 if (p_FmPort->pcdEngines & FM_PCD_PRS)
1719 {
1720 /* stop parser */
1721 WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
1722 /* wait for parser to be in idle state */
1723 while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
1724 ;
1725 }
1726
1727 if (p_FmPort->pcdEngines & FM_PCD_KG)
1728 {
1729 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
1730
1731 /* unbind all schemes */
1732 p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
1733 &schemeBind);
1734
1735 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
1736 if (err)
1737 RETURN_ERROR(MAJOR, err, NO_MSG);
1738
1739 err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
1740 p_FmPort->hardwarePortId,
1741 p_FmPort->clsPlanGrpId);
1742 if (err)
1743 RETURN_ERROR(MAJOR, err, NO_MSG);
1744 p_FmPort->useClsPlan = FALSE;
1745 }
1746
1747 if (p_FmPort->pcdEngines & FM_PCD_CC)
1748 {
1749 /* unbind - we need to get the treeId too */
1750 err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
1751 if (err)
1752 RETURN_ERROR(MAJOR, err, NO_MSG);
1753 }
1754
1755 p_FmPort->pcdEngines = 0;
1756
1757 return E_OK;
1758}
1759
1760static t_Error AttachPCD(t_FmPort *p_FmPort)
1761{
1762 volatile uint32_t *p_BmiNia = NULL;
1763
1764 ASSERT_COND(p_FmPort);
1765
1766 /* get PCD registers pointers */
1767 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1768 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1769 else
1770 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1771
1772 /* check that current NIA is BMI to BMI */
1773 if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
1774 != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
1775 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
1776 ("may be called only for ports in BMI-to-BMI state."));
1777
1778 if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1779 if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
1780 p_FmPort->orFmanCtrl) != E_OK)
1781 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1782
1783 if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
1784 {
1785 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1786 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
1787 p_FmPort->savedBmiCmne);
1788 else
1789 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
1790 p_FmPort->savedBmiCmne);
1791 }
1792
1793 if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1794 WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
1795 p_FmPort->savedQmiPnen);
1796
1797 if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1798 {
1799 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1800 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1801 p_FmPort->savedBmiFene);
1802 else
1803 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1804 p_FmPort->savedBmiFene);
1805 }
1806
1807 if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
1808 {
1809 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1810 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
1811 p_FmPort->savedBmiFpne);
1812 else
1813 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
1814 p_FmPort->savedBmiFpne);
1815 }
1816
1817 if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
1818 {
1819 ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
1820
1821 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
1822 p_FmPort->savedBmiOfp);
1823 }
1824
1825 WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
1826
1827 if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1828 {
1829 p_FmPort->origNonRxQmiRegsPndn =
1830 GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
1831 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1832 p_FmPort->savedNonRxQmiRegsPndn);
1833 }
1834
1835 return E_OK;
1836}
1837
1838static t_Error DetachPCD(t_FmPort *p_FmPort)
1839{
1840 volatile uint32_t *p_BmiNia = NULL;
1841
1842 ASSERT_COND(p_FmPort);
1843
1844 /* get PCD registers pointers */
1845 if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
1846 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
1847 p_FmPort->origNonRxQmiRegsPndn);
1848
1849 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1850 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
1851 else
1852 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
1853
1854 WRITE_UINT32(
1855 *p_BmiNia,
1856 (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
1857
1858 if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
1859 FmPcdHcSync(p_FmPort->h_FmPcd);
1860
1861 if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
1862 {
1863 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
1864 WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
1865 NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1866 else
1867 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
1868 NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
1869 }
1870
1871 if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
1872 WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
1873 NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
1874
1875 if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
1876 if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
1877 p_FmPort->orFmanCtrl) != E_OK)
1878 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
1879
1880 p_FmPort->requiredAction = 0;
1881
1882 return E_OK;
1883}
1884
1885/*****************************************************************************/
1886/* Inter-module API routines */
1887/*****************************************************************************/
1888void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
1889{
1890 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1891 volatile uint32_t *p_BmiCfgReg = NULL;
1892 uint32_t tmpReg;
1893
1894 SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
1895 SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
1896
1897 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
1898 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
1899 {
1900 REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
1901 return;
1902 }
1903
1904 p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
1905 tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
1906 tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
1907 tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
1908 & BMI_CMD_ATTR_MACCMD_SC_MASK);
1909
1910 WRITE_UINT32(*p_BmiCfgReg, tmpReg);
1911}
1912
1913uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
1914{
1915 return ((t_FmPort*)h_FmPort)->netEnvId;
1916}
1917
1918uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
1919{
1920 return ((t_FmPort*)h_FmPort)->hardwarePortId;
1921}
1922
1923uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
1924{
1925 return ((t_FmPort*)h_FmPort)->pcdEngines;
1926}
1927
1928#if (DPAA_VERSION >= 11)
1929t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
1930 void **p_Value)
1931{
1932 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1933 uint32_t muramPageOffset;
1934
1935 ASSERT_COND(p_FmPort);
1936 ASSERT_COND(p_Value);
1937
1938 if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
1939 {
1940 if (p_FmPort->gprFunc != gprFunc)
1941 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1942 ("gpr was assigned with different func"));
1943 }
1944 else
1945 {
1946 switch (gprFunc)
1947 {
1948 case (e_FM_PORT_GPR_MURAM_PAGE):
1949 p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
1950 256, 8);
1951 if (!p_FmPort->p_ParamsPage)
1952 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
1953
1954 IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
1955 muramPageOffset =
1956 (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
1957 - p_FmPort->fmMuramPhysBaseAddr);
1958 switch (p_FmPort->portType)
1959 {
1960 case (e_FM_PORT_TYPE_RX_10G):
1961 case (e_FM_PORT_TYPE_RX):
1962 WRITE_UINT32(
1963 p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
1964 muramPageOffset);
1965 break;
1966 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
1967 WRITE_UINT32(
1968 p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
1969 muramPageOffset);
1970 break;
1971 default:
1972 RETURN_ERROR(MAJOR, E_INVALID_STATE,
1973 ("Invalid port type"));
1974 }
1975 break;
1976 default:
1977 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1978 }
1979 p_FmPort->gprFunc = gprFunc;
1980 }
1981
1982 switch (p_FmPort->gprFunc)
1983 {
1984 case (e_FM_PORT_GPR_MURAM_PAGE):
1985 *p_Value = p_FmPort->p_ParamsPage;
1986 break;
1987 default:
1988 RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
1989 }
1990
1991 return E_OK;
1992}
1993#endif /* (DPAA_VERSION >= 11) */
1994
1995t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
1996 t_FmPortGetSetCcParams *p_CcParams)
1997{
1998 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
1999 int tmpInt;
1999 uint32_t tmpInt;
2000 volatile uint32_t *p_BmiPrsStartOffset = NULL;
2001
2002 /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
2003
2004 if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
2005 && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
2006 {
2007 p_CcParams->getCcParams.prOffset =
2008 (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
2009 p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
2010 }
2011 if (p_CcParams->getCcParams.type & HW_PORT_ID)
2012 {
2013 p_CcParams->getCcParams.hardwarePortId =
2014 (uint8_t)p_FmPort->hardwarePortId;
2015 p_CcParams->getCcParams.type &= ~HW_PORT_ID;
2016 }
2017 if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
2018 && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
2019 {
2020 p_CcParams->getCcParams.dataOffset =
2021 (uint16_t)p_FmPort->bufferOffsets.dataOffset;
2022 p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
2023 }
2024 if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
2025 {
2026 p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
2027 p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
2028 }
2029 if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
2030 {
2031 p_CcParams->getCcParams.numOfExtraTasks =
2032 (uint8_t)p_FmPort->tasks.extra;
2033 p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
2034 }
2035 if (p_CcParams->getCcParams.type & FM_REV)
2036 {
2037 p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
2038 p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
2039 p_CcParams->getCcParams.type &= ~FM_REV;
2040 }
2041 if (p_CcParams->getCcParams.type & DISCARD_MASK)
2042 {
2043 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2044 p_CcParams->getCcParams.discardMask =
2045 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
2046 else
2047 p_CcParams->getCcParams.discardMask =
2048 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
2049 p_CcParams->getCcParams.type &= ~DISCARD_MASK;
2050 }
2051 if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
2052 {
2053 p_CcParams->getCcParams.internalBufferOffset =
2054 p_FmPort->internalBufferOffset;
2055 p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
2056 }
2057 if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
2058 {
2059 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2060 p_CcParams->getCcParams.nia =
2061 GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
2062 else
2063 p_CcParams->getCcParams.nia =
2064 GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
2065 p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
2066 }
2067 if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
2068 {
2069 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2070 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2071 p_CcParams->getCcParams.nia =
2072 GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
2073 p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
2074 }
2075
2076 if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
2077 && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
2078 {
2079 p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
2080 p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
2081 }
2082
2083 if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
2084 && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
2085 {
2086 p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
2087 p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
2088 }
2089 else
2090 if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
2091 {
2092 if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
2093 RETURN_ERROR(MAJOR, E_INVALID_STATE,
2094 ("PNEN was defined previously different"));
2095 }
2096
2097 if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
2098 && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
2099 {
2100 p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
2101 p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
2102 }
2103 else
2104 if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
2105 {
2106 if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
2107 RETURN_ERROR(MAJOR, E_INVALID_STATE,
2108 ("PNDN was defined previously different"));
2109 }
2110
2111 if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
2112 && (p_CcParams->setCcParams.overwrite
2113 || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
2114 {
2115 p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
2116 p_FmPort->requiredAction |= UPDATE_NIA_FENE;
2117 }
2118 else
2119 if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
2120 {
2121 if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
2122 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2123 ("xFENE was defined previously different"));
2124 }
2125
2126 if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
2127 && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
2128 {
2129 p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
2130 p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
2131 }
2132 else
2133 if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
2134 {
2135 if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
2136 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2137 ("xFPNE was defined previously different"));
2138 }
2139
2140 if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
2141 && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
2142 {
2143 p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
2144 p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
2145 }
2146 else
2147 if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
2148 {
2149 if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
2150 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2151 ("xCMNE was defined previously different"));
2152 }
2153
2154 if ((p_CcParams->setCcParams.type & UPDATE_PSO)
2155 && !(p_FmPort->requiredAction & UPDATE_PSO))
2156 {
2157 /* get PCD registers pointers */
2158 switch (p_FmPort->portType)
2159 {
2160 case (e_FM_PORT_TYPE_RX_10G):
2161 case (e_FM_PORT_TYPE_RX):
2162 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
2163 break;
2164 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2165 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
2166 break;
2167 default:
2168 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2169 }
2170
2171 /* set start parsing offset */
2172 tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
2173 + p_CcParams->setCcParams.psoSize;
2174 if (tmpInt > 0)
2175 WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
2176
2177 p_FmPort->requiredAction |= UPDATE_PSO;
2178 p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
2179 }
2180 else
2181 if (p_CcParams->setCcParams.type & UPDATE_PSO)
2182 {
2183 if (p_FmPort->savedPrsStartOffset
2184 != p_CcParams->setCcParams.psoSize)
2185 RETURN_ERROR(
2186 MAJOR,
2187 E_INVALID_STATE,
2188 ("parser start offset was defoned previousley different"));
2189 }
2190
2191 if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
2192 && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
2193 {
2194 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2195 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2196 p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
2197 p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
2198 p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
2199 << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
2200 p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
2201 }
2202
2203 return E_OK;
2204}
2205/*********************** End of inter-module routines ************************/
2206
2207/****************************************/
2208/* API Init unit functions */
2209/****************************************/
2210
2211t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
2212{
2213 t_FmPort *p_FmPort;
2214 uintptr_t baseAddr = p_FmPortParams->baseAddr;
2215 uint32_t tmpReg;
2216
2217 /* Allocate FM structure */
2218 p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
2219 if (!p_FmPort)
2220 {
2221 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
2222 return NULL;
2223 }
2224 memset(p_FmPort, 0, sizeof(t_FmPort));
2225
2226 /* Allocate the FM driver's parameters structure */
2227 p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
2228 sizeof(t_FmPortDriverParam));
2229 if (!p_FmPort->p_FmPortDriverParam)
2230 {
2231 XX_Free(p_FmPort);
2232 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
2233 return NULL;
2234 }
2235 memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
2236
2237 /* Initialize FM port parameters which will be kept by the driver */
2238 p_FmPort->portType = p_FmPortParams->portType;
2239 p_FmPort->portId = p_FmPortParams->portId;
2240 p_FmPort->pcdEngines = FM_PCD_NONE;
2241 p_FmPort->f_Exception = p_FmPortParams->f_Exception;
2242 p_FmPort->h_App = p_FmPortParams->h_App;
2243 p_FmPort->h_Fm = p_FmPortParams->h_Fm;
2244
2245 /* get FM revision */
2246 FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
2247
2248 /* calculate global portId number */
2249 p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
2250 p_FmPortParams->portId,
2251 p_FmPort->fmRevInfo.majorRev,
2252 p_FmPort->fmRevInfo.minorRev);
2253
2254 if (p_FmPort->fmRevInfo.majorRev >= 6)
2255 {
2256 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2257 && (p_FmPortParams->portId != FM_OH_PORT_ID))
2258 DBG(WARNING,
2259 ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
2260 FM_OH_PORT_ID));
2261
2262 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2263 && (p_FmPortParams->portId == FM_OH_PORT_ID))
2264 DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
2265 }
2266
2267 /* Set up FM port parameters for initialization phase only */
2268
2269 /* First, fill in flibs struct */
2270 fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
2271 (enum fman_port_type)p_FmPort->portType);
2272 /* Overwrite some integration specific parameters */
2273 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
2274 DEFAULT_PORT_rxFifoPriElevationLevel;
2275 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
2276 DEFAULT_PORT_rxFifoThreshold;
2277
2278#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
2279 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
2280#else
2281 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
2282#endif
2283 if ((p_FmPort->fmRevInfo.majorRev == 6)
2284 && (p_FmPort->fmRevInfo.minorRev == 0))
2285 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
2286 else
2287 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
2288
2289 /* Excessive Threshold register - exists for pre-FMv3 chips only */
2290 if (p_FmPort->fmRevInfo.majorRev < 6)
2291 {
2292#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
2293 p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
2294 TRUE;
2295#endif
2296 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
2297 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
2298 }
2299 else
2300 {
2301 p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
2302 FALSE;
2303 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
2304 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
2305 }
2306 if (p_FmPort->fmRevInfo.majorRev == 4)
2307 p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
2308 else
2309 p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
2310
2311 /* Continue with other parameters */
2312 p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
2313 /* set memory map pointers */
2314 p_FmPort->p_FmPortQmiRegs =
2315 (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
2316 p_FmPort->p_FmPortBmiRegs =
2317 (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
2318 p_FmPort->p_FmPortPrsRegs =
2319 (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
2320
2321 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
2322 DEFAULT_PORT_bufferPrefixContent_privDataSize;
2323 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
2324 DEFAULT_PORT_bufferPrefixContent_passPrsResult;
2325 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
2326 DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
2327 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
2328 DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
2329 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
2330 DEFAULT_PORT_bufferPrefixContent_dataAlign;
2331 /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
2332 p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
2333 p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
2334 p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
2335 p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
2336 */
2337 p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
2338 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
2339 DEFAULT_PORT_cheksumLastBytesIgnore;
2340
2341 p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
2342 /* resource distribution. */
2343 p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
2344 * BMI_FIFO_UNITS;
2345 p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
2346 * BMI_FIFO_UNITS;
2347 p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
2348 p_FmPort->openDmas.extra =
2349 DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
2350 p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
2351 p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
2352
2353
2354#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
2355 if ((p_FmPort->fmRevInfo.majorRev == 6)
2356 && (p_FmPort->fmRevInfo.minorRev == 0)
2357 && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2358 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
2359 {
2360 p_FmPort->openDmas.num = 16;
2361 p_FmPort->openDmas.extra = 0;
2362 }
2363#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
2364
2365 /* Port type specific initialization: */
2366 switch (p_FmPort->portType)
2367 {
2368 case (e_FM_PORT_TYPE_RX):
2369 case (e_FM_PORT_TYPE_RX_10G):
2370 /* Initialize FM port parameters for initialization phase only */
2371 p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
2372 DEFAULT_PORT_cutBytesFromEnd;
2373 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
2374 p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
2375 DEFAULT_PORT_frmDiscardOverride;
2376
2377 tmpReg =
2378 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
2379 p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
2380 (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
2381 >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
2382 * BMI_FIFO_UNITS;
2383 p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
2384 & BMI_RX_FIFO_THRESHOLD_MASK)
2385 >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
2386
2387 p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
2388 DEFAULT_PORT_BufMargins_endMargins;
2389 p_FmPort->p_FmPortDriverParam->errorsToDiscard =
2390 DEFAULT_PORT_errorsToDiscard;
2391 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
2392 DEFAULT_PORT_forwardIntContextReuse;
2393#if (DPAA_VERSION >= 11)
2394 p_FmPort->p_FmPortDriverParam->noScatherGather =
2395 DEFAULT_PORT_noScatherGather;
2396#endif /* (DPAA_VERSION >= 11) */
2397 break;
2398
2399 case (e_FM_PORT_TYPE_TX):
2400 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
2401#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
2402 tmpReg = 0x00001013;
2403 WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
2404 tmpReg);
2405#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
2406 case (e_FM_PORT_TYPE_TX_10G):
2407 tmpReg =
2408 GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
2409 p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
2410 & BMI_TX_FIFO_MIN_FILL_MASK)
2411 >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
2412 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2413 (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
2414 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
2415 p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
2416 & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
2417 * BMI_FIFO_UNITS;
2418
2419 p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
2420 p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
2421 DEFAULT_PORT_deqPrefetchOption;
2422 p_FmPort->p_FmPortDriverParam->deqHighPriority =
2423 (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
2424 DEFAULT_PORT_deqHighPriority_10G);
2425 p_FmPort->p_FmPortDriverParam->deqByteCnt =
2426 (uint16_t)(
2427 (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
2428 DEFAULT_PORT_deqByteCnt_10G);
2429 break;
2430 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2431 p_FmPort->p_FmPortDriverParam->errorsToDiscard =
2432 DEFAULT_PORT_errorsToDiscard;
2433#if (DPAA_VERSION >= 11)
2434 p_FmPort->p_FmPortDriverParam->noScatherGather =
2435 DEFAULT_PORT_noScatherGather;
2436#endif /* (DPAA_VERSION >= 11) */
2437 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
2438 p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
2439 DEFAULT_PORT_deqPrefetchOption_HC;
2440 p_FmPort->p_FmPortDriverParam->deqHighPriority =
2441 DEFAULT_PORT_deqHighPriority_1G;
2442 p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
2443 p_FmPort->p_FmPortDriverParam->deqByteCnt =
2444 DEFAULT_PORT_deqByteCnt_1G;
2445
2446 tmpReg =
2447 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
2448 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2449 (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
2450 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
2451 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2452 && (p_FmPortParams->portId != FM_OH_PORT_ID))
2453 {
2454 /* Overwrite HC defaults */
2455 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2456 DEFAULT_PORT_fifoDeqPipelineDepth_OH;
2457 }
2458
2459#ifndef FM_FRAME_END_PARAMS_FOR_OP
2460 if (p_FmPort->fmRevInfo.majorRev < 6)
2461 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
2462#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
2463
2464#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
2465 if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
2466 (p_FmPort->fmRevInfo.majorRev >= 6)))
2467 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
2468#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
2469 break;
2470
2471 default:
2472 XX_Free(p_FmPort->p_FmPortDriverParam);
2473 XX_Free(p_FmPort);
2474 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2475 return NULL;
2476 }
2477#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
2478 if (p_FmPort->fmRevInfo.majorRev == 4)
2479 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
2480#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
2481
2482 p_FmPort->imEn = p_FmPortParams->independentModeEnable;
2483
2484 if (p_FmPort->imEn)
2485 {
2486 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
2487 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
2488 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2489 DEFAULT_PORT_fifoDeqPipelineDepth_IM;
2490 FmPortConfigIM(p_FmPort, p_FmPortParams);
2491 }
2492 else
2493 {
2494 switch (p_FmPort->portType)
2495 {
2496 case (e_FM_PORT_TYPE_RX):
2497 case (e_FM_PORT_TYPE_RX_10G):
2498 /* Initialize FM port parameters for initialization phase only */
2499 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
2500 &p_FmPortParams->specificParams.rxParams.extBufPools,
2501 sizeof(t_FmExtPools));
2502 p_FmPort->p_FmPortDriverParam->errFqid =
2503 p_FmPortParams->specificParams.rxParams.errFqid;
2504 p_FmPort->p_FmPortDriverParam->dfltFqid =
2505 p_FmPortParams->specificParams.rxParams.dfltFqid;
2506 p_FmPort->p_FmPortDriverParam->liodnOffset =
2507 p_FmPortParams->specificParams.rxParams.liodnOffset;
2508 break;
2509 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2510 case (e_FM_PORT_TYPE_TX):
2511 case (e_FM_PORT_TYPE_TX_10G):
2512 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
2513 p_FmPort->p_FmPortDriverParam->errFqid =
2514 p_FmPortParams->specificParams.nonRxParams.errFqid;
2515 p_FmPort->p_FmPortDriverParam->deqSubPortal =
2516 (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
2517 & QMI_DEQ_CFG_SUBPORTAL_MASK);
2518 p_FmPort->p_FmPortDriverParam->dfltFqid =
2519 p_FmPortParams->specificParams.nonRxParams.dfltFqid;
2520 break;
2521 default:
2522 XX_Free(p_FmPort->p_FmPortDriverParam);
2523 XX_Free(p_FmPort);
2524 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2525 return NULL;
2526 }
2527 }
2528
2529 memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
2530 if (Sprint(
2531 p_FmPort->name,
2532 "FM-%d-port-%s-%d",
2533 FmGetId(p_FmPort->h_Fm),
2534 ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
2535 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
2536 (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
2537 (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
2538 (p_FmPort->portType
2539 == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
2540 "10g-TX")))),
2541 p_FmPort->portId) == 0)
2542 {
2543 XX_Free(p_FmPort->p_FmPortDriverParam);
2544 XX_Free(p_FmPort);
2545 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2546 return NULL;
2547 }
2548
2549 p_FmPort->h_Spinlock = XX_InitSpinlock();
2550 if (!p_FmPort->h_Spinlock)
2551 {
2552 XX_Free(p_FmPort->p_FmPortDriverParam);
2553 XX_Free(p_FmPort);
2554 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2555 return NULL;
2556 }
2557
2558 return p_FmPort;
2559}
2560
2561t_FmPort *rx_port = 0;
2562t_FmPort *tx_port = 0;
2563
2564/**************************************************************************//**
2565 @Function FM_PORT_Init
2566
2567 @Description Initializes the FM module
2568
2569 @Param[in] h_FmPort - FM module descriptor
2570
2571 @Return E_OK on success; Error code otherwise.
2572 *//***************************************************************************/
2573t_Error FM_PORT_Init(t_Handle h_FmPort)
2574{
2575 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2576 t_FmPortDriverParam *p_DriverParams;
2577 t_Error errCode;
2578 t_FmInterModulePortInitParams fmParams;
2579 t_FmRevisionInfo revInfo;
2580
2581 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
2582 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2583
2584 errCode = FmSpBuildBufferStructure(
2585 &p_FmPort->p_FmPortDriverParam->intContext,
2586 &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
2587 &p_FmPort->p_FmPortDriverParam->bufMargins,
2588 &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
2589 if (errCode != E_OK)
2590 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2591#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
2592 if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
2593 (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2594 {
2595 p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
2596 if (!p_FmPort->fifoBufs.num)
2597 p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
2598 p_FmPort->fifoBufs.num += 4*KILOBYTE;
2599 }
2600#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
2601
2602 CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
2603
2604 p_DriverParams = p_FmPort->p_FmPortDriverParam;
2605
2606 /* Set up flibs port structure */
2607 memset(&p_FmPort->port, 0, sizeof(struct fman_port));
2608 p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
2609 FM_GetRevision(p_FmPort->h_Fm, &revInfo);
2610 p_FmPort->port.fm_rev_maj = revInfo.majorRev;
2611 p_FmPort->port.fm_rev_min = revInfo.minorRev;
2612 p_FmPort->port.bmi_regs =
2613 (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
2614 p_FmPort->port.qmi_regs =
2615 (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
2616 p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
2617 p_FmPort->port.im_en = p_FmPort->imEn;
2618 p_FmPort->p_FmPortPrsRegs =
2619 (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
2620
2621 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2622 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
2623 {
2624 /* Call the external Buffer routine which also checks fifo
2625 size and updates it if necessary */
2626 /* define external buffer pools and pool depletion*/
2627 errCode = SetExtBufferPools(p_FmPort);
2628 if (errCode)
2629 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2630 /* check if the largest external buffer pool is large enough */
2631 if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
2632 + p_DriverParams->bufMargins.endMargins
2633 > p_FmPort->rxPoolsParams.largestBufSize)
2634 RETURN_ERROR(
2635 MAJOR,
2636 E_INVALID_VALUE,
2637 ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", p_DriverParams->bufMargins.startMargins, p_DriverParams->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize));
2638 }
2639 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2640 {
2641 {
2642#ifdef FM_NO_OP_OBSERVED_POOLS
2643 t_FmRevisionInfo revInfo;
2644
2645 FM_GetRevision(p_FmPort->h_Fm, &revInfo);
2646 if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
2647#endif /* FM_NO_OP_OBSERVED_POOLS */
2648 {
2649 /* define external buffer pools */
2650 errCode = SetExtBufferPools(p_FmPort);
2651 if (errCode)
2652 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2653 }
2654 }
2655 }
2656
2657 /************************************************************/
2658 /* Call FM module routine for communicating parameters */
2659 /************************************************************/
2660 memset(&fmParams, 0, sizeof(fmParams));
2661 fmParams.hardwarePortId = p_FmPort->hardwarePortId;
2662 fmParams.portType = (e_FmPortType)p_FmPort->portType;
2663 fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
2664 fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
2665 fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
2666 fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
2667
2668 if (p_FmPort->fifoBufs.num)
2669 {
2670 errCode = VerifySizeOfFifo(p_FmPort);
2671 if (errCode != E_OK)
2672 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2673 }
2674 fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
2675 fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
2676 fmParams.independentMode = p_FmPort->imEn;
2677 fmParams.liodnOffset = p_DriverParams->liodnOffset;
2678 fmParams.liodnBase = p_DriverParams->liodnBase;
2679 fmParams.deqPipelineDepth =
2680 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
2681 fmParams.maxFrameLength = p_FmPort->maxFrameLength;
2682#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
2683 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
2684 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
2685 {
2686 if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
2687 (p_FmPort->fmRevInfo.majorRev >= 6)))
2688 /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
2689 * for deq threshold calculation.
2690 */
2691 fmParams.deqPipelineDepth = 2;
2692 }
2693#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
2694
2695 errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
2696 if (errCode)
2697 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2698
2699 /* get params for use in init */
2700 p_FmPort->fmMuramPhysBaseAddr =
2701 (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
2702 | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
2703 p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
2704
2705 errCode = InitLowLevelDriver(p_FmPort);
2706 if (errCode != E_OK)
2707 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2708
2709 FmPortDriverParamFree(p_FmPort);
2710
2711#if (DPAA_VERSION >= 11)
2712 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2713 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
2714 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
2715 {
2716 t_FmPcdCtrlParamsPage *p_ParamsPage;
2717
2718 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
2719 (void**)&p_ParamsPage);
2720 ASSERT_COND(p_ParamsPage);
2721
2722 WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
2723#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
2724 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2725 {
2726 WRITE_UINT32(
2727 p_ParamsPage->misc,
2728 (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
2729 WRITE_UINT32(
2730 p_ParamsPage->discardMask,
2731 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
2732 }
2733#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
2734#ifdef FM_ERROR_VSP_NO_MATCH_SW006
2735 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2736 WRITE_UINT32(
2737 p_ParamsPage->errorsDiscardMask,
2738 (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
2739 else
2740 WRITE_UINT32(
2741 p_ParamsPage->errorsDiscardMask,
2742 (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
2743#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
2744 }
2745#endif /* (DPAA_VERSION >= 11) */
2746
2747 if (p_FmPort->deepSleepVars.autoResMaxSizes)
2748 FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
2749 return E_OK;
2750}
2751
2752/**************************************************************************//**
2753 @Function FM_PORT_Free
2754
2755 @Description Frees all resources that were assigned to FM module.
2756
2757 Calling this routine invalidates the descriptor.
2758
2759 @Param[in] h_FmPort - FM module descriptor
2760
2761 @Return E_OK on success; Error code otherwise.
2762 *//***************************************************************************/
2763t_Error FM_PORT_Free(t_Handle h_FmPort)
2764{
2765 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2766 t_FmInterModulePortFreeParams fmParams;
2767
2768 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2769
2770 if (p_FmPort->pcdEngines)
2771 RETURN_ERROR(
2772 MAJOR,
2773 E_INVALID_STATE,
2774 ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
2775
2776 if (p_FmPort->enabled)
2777 {
2778 if (FM_PORT_Disable(p_FmPort) != E_OK)
2779 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
2780 }
2781
2782 if (p_FmPort->imEn)
2783 FmPortImFree(p_FmPort);
2784
2785 FmPortDriverParamFree(p_FmPort);
2786
2787 memset(&fmParams, 0, sizeof(fmParams));
2788 fmParams.hardwarePortId = p_FmPort->hardwarePortId;
2789 fmParams.portType = (e_FmPortType)p_FmPort->portType;
2790 fmParams.deqPipelineDepth =
2791 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
2792
2793 FmFreePortParams(p_FmPort->h_Fm, &fmParams);
2794
2795#if (DPAA_VERSION >= 11)
2796 if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
2797 != E_OK)
2798 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
2799
2800 if (p_FmPort->p_ParamsPage)
2801 FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
2802#endif /* (DPAA_VERSION >= 11) */
2803
2804 if (p_FmPort->h_Spinlock)
2805 XX_FreeSpinlock(p_FmPort->h_Spinlock);
2806
2807 XX_Free(p_FmPort);
2808
2809 return E_OK;
2810}
2811
2812/*************************************************/
2813/* API Advanced Init unit functions */
2814/*************************************************/
2815
2816t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
2817{
2818 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2819
2820 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2821 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2822
2823 p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
2824 memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
2825
2826 return E_OK;
2827}
2828
2829t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
2830{
2831 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2832
2833 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2834 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2835
2836 memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
2837 p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
2838 return E_OK;
2839}
2840
2841t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
2842{
2843 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2844
2845 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2846 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2847
2848 p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
2849 memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
2850
2851 return E_OK;
2852}
2853
2854t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
2855{
2856 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2857
2858 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2859 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2860 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2861 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2862 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
2863
2864 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
2865
2866 return E_OK;
2867}
2868
2869t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
2870{
2871 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2872
2873 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2874 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2875 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2876 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2877 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2878 ("not available for Rx ports"));
2879
2880 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
2881 (enum fman_port_deq_type)deqType;
2882
2883 return E_OK;
2884}
2885
2886t_Error FM_PORT_ConfigDeqPrefetchOption(
2887 t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
2888{
2889 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2890
2891 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2892 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2893 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2894 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2895 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2896 ("not available for Rx ports"));
2897 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
2898 (enum fman_port_deq_prefetch)deqPrefetchOption;
2899
2900 return E_OK;
2901}
2902
2903t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
2904 t_FmBackupBmPools *p_BackupBmPools)
2905{
2906 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2907
2908 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2909 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2910 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2911 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2912 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2913 ("available for Rx ports only"));
2914
2915 p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
2916 (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
2917 if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
2918 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
2919 memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
2920 sizeof(t_FmBackupBmPools));
2921
2922 return E_OK;
2923}
2924
2925t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
2926{
2927 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2928
2929 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2930 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2931 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2932 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2933 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2934 ("not available for Rx ports"));
2935
2936 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
2937
2938 return E_OK;
2939}
2940
2941t_Error FM_PORT_ConfigBufferPrefixContent(
2942 t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
2943{
2944 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2945
2946 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2947 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2948
2949 memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
2950 p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
2951 /* if dataAlign was not initialized by user, we return to driver's default */
2952 if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
2953 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
2954 DEFAULT_PORT_bufferPrefixContent_dataAlign;
2955
2956 return E_OK;
2957}
2958
2959t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
2960 uint8_t checksumLastBytesIgnore)
2961{
2962 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2963
2964 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2965 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2966
2967 p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
2968 checksumLastBytesIgnore;
2969
2970 return E_OK;
2971}
2972
2973t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
2974 uint8_t cutBytesFromEnd)
2975{
2976 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2977
2978 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2979 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2980 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2981 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2982 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2983 ("available for Rx ports only"));
2984
2985 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
2986
2987 return E_OK;
2988}
2989
2990t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
2991 t_FmBufPoolDepletion *p_BufPoolDepletion)
2992{
2993 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2994
2995 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2996 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2997 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2998 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2999 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3000 ("available for Rx ports only"));
3001
3002 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
3003 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
3004 sizeof(t_FmBufPoolDepletion));
3005
3006 return E_OK;
3007}
3008
3009t_Error FM_PORT_ConfigObservedPoolDepletion(
3010 t_Handle h_FmPort,
3011 t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
3012{
3013 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3014
3015 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3016 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3017 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3018 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3019 ("available for OP ports only"));
3020
3021 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
3022 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
3023 &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
3024 sizeof(t_FmBufPoolDepletion));
3025 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
3026 &p_FmPortObservedBufPoolDepletion->poolsParams,
3027 sizeof(t_FmExtPools));
3028
3029 return E_OK;
3030}
3031
3032t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
3033{
3034 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3035
3036 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3037 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3038
3039 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3040 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3041 ("available for OP ports only"));
3042
3043 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
3044 sizeof(t_FmExtPools));
3045
3046 return E_OK;
3047}
3048
3049t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
3050{
3051 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3052
3053 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3054 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3055 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3056 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3057 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3058 ("available for Tx ports only"));
3059
3060 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
3061
3062 return E_OK;
3063}
3064
3065t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
3066{
3067 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3068
3069 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3070 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3071 p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
3072
3073 return E_OK;
3074}
3075
3076t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
3077{
3078 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3079
3080 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3081 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3082
3083 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3084 || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3085 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3086 ("Not available for Tx ports"));
3087
3088 p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
3089
3090 return E_OK;
3091}
3092
3093t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
3094{
3095 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3096
3097 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3098 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3099 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3100 || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3101 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3102 ("Not available for Tx ports"));
3103
3104 p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
3105
3106 return E_OK;
3107}
3108
3109t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
3110 fmPortFrameErrSelect_t errs)
3111{
3112 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3113
3114 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3115 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3116 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3117 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
3118 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
3119 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3120 ("available for Rx and offline parsing ports only"));
3121
3122 p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
3123
3124 return E_OK;
3125}
3126
3127t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
3128{
3129 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3130
3131 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3132 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3133
3134 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
3135 (enum fman_port_dma_swap)swapData;
3136
3137 return E_OK;
3138}
3139
3140t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
3141 e_FmDmaCacheOption intContextCacheAttr)
3142{
3143 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3144
3145 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3146 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3147
3148 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
3149 (bool)(intContextCacheAttr == e_FM_DMA_STASH);
3150
3151 return E_OK;
3152}
3153
3154t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
3155 e_FmDmaCacheOption headerCacheAttr)
3156{
3157 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3158
3159 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3160 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3161
3162 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
3163 (bool)(headerCacheAttr == e_FM_DMA_STASH);
3164
3165 return E_OK;
3166}
3167
3168t_Error FM_PORT_ConfigDmaScatterGatherAttr(
3169 t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
3170{
3171 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3172
3173 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3174 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3175
3176 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
3177 (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
3178
3179 return E_OK;
3180}
3181
3182t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
3183{
3184 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3185
3186 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3187 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3188
3189 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3190 || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3191 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3192 ("Not available for Tx ports"));
3193
3194 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
3195
3196 return E_OK;
3197}
3198
3199#if (DPAA_VERSION >= 11)
3200t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
3201{
3202 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3203
3204 UNUSED(noScatherGather);
3205 UNUSED(p_FmPort);
3206
3207 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3208 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3209
3210 p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
3211
3212 return E_OK;
3213}
3214#endif /* (DPAA_VERSION >= 11) */
3215
3216t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
3217 bool forwardReuse)
3218{
3219 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3220
3221 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3222 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3223
3224 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3225 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3226 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3227 ("available for Rx ports only"));
3228
3229 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
3230
3231 return E_OK;
3232}
3233
3234t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
3235{
3236 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3237
3238 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3239 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3240
3241 p_FmPort->maxFrameLength = length;
3242
3243 return E_OK;
3244}
3245
3246#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
3247t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
3248{
3249 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3250
3251 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3252 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3253
3254 p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
3255
3256 return E_OK;
3257}
3258#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
3259
3260/****************************************************/
3261/* Hidden-DEBUG Only API */
3262/****************************************************/
3263
3264t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
3265 uint32_t minFillLevel)
3266{
3267 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3268
3269 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3270 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3271 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3272 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3273 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3274 ("available for Tx ports only"));
3275
3276 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
3277
3278 return E_OK;
3279}
3280
3281t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
3282 uint8_t deqPipelineDepth)
3283{
3284 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3285
3286 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3287 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3288
3289 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
3290 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
3291 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3292 ("Not available for Rx ports"));
3293
3294 if (p_FmPort->imEn)
3295 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3296 ("Not available for IM ports!"));
3297
3298 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
3299 deqPipelineDepth;
3300
3301 return E_OK;
3302}
3303
3304t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
3305 uint32_t fifoLowComfLevel)
3306{
3307 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3308
3309 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3310 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3311 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3312 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3313 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3314 ("available for Tx ports only"));
3315
3316 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
3317 fifoLowComfLevel;
3318
3319 return E_OK;
3320}
3321
3322t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
3323{
3324 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3325
3326 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3327 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3328 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3329 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3330 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3331 ("available for Rx ports only"));
3332
3333 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
3334
3335 return E_OK;
3336}
3337
3338t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
3339 uint32_t priElevationLevel)
3340{
3341 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3342
3343 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3344 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3345 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3346 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3347 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3348 ("available for Rx ports only"));
3349
3350 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
3351
3352 return E_OK;
3353}
3354/****************************************************/
3355/* API Run-time Control unit functions */
3356/****************************************************/
3357
3358t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
3359 t_FmPortRsrc *p_NumOfOpenDmas)
3360{
3361 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3362 t_Error err;
3363
3364 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3365 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3366
3367 if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
3368 RETURN_ERROR( MAJOR, E_INVALID_VALUE,
3369 ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
3370 if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
3371 RETURN_ERROR(
3372 MAJOR,
3373 E_INVALID_VALUE,
3374 ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
3375 err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3376 (uint8_t*)&p_NumOfOpenDmas->num,
3377 (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
3378 if (err)
3379 RETURN_ERROR(MAJOR, err, NO_MSG);
3380
3381 memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
3382
3383 return E_OK;
3384}
3385
3386t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
3387{
3388 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3389 t_Error err;
3390
3391 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3392 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3393
3394 /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
3395 ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
3396
3397 if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
3398 RETURN_ERROR(
3399 MAJOR, E_INVALID_VALUE,
3400 ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
3401 if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
3402 RETURN_ERROR(
3403 MAJOR,
3404 E_INVALID_VALUE,
3405 ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
3406
3407 err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3408 (uint8_t*)&p_NumOfTasks->num,
3409 (uint8_t*)&p_NumOfTasks->extra, FALSE);
3410 if (err)
3411 RETURN_ERROR(MAJOR, err, NO_MSG);
3412
3413 /* update driver's struct */
3414 memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
3415 return E_OK;
3416}
3417
3418t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
3419{
3420 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3421 t_Error err;
3422
3423 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3424 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3425
3426 if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
3427 RETURN_ERROR(
3428 MAJOR,
3429 E_INVALID_VALUE,
3430 ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
3431 if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
3432 RETURN_ERROR(
3433 MAJOR, E_INVALID_VALUE,
3434 ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
3435 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
3436 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
3437 {
3438 /* extra FIFO size (allowed only to Rx ports) */
3439 if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
3440 RETURN_ERROR(
3441 MAJOR,
3442 E_INVALID_VALUE,
3443 ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
3444 }
3445 else
3446 if (p_SizeOfFifo->extra)
3447 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
3448 (" No SizeOfFifo-extra for non Rx ports"));
3449
3450 memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
3451
3452 /* we do not change user's parameter */
3453 err = VerifySizeOfFifo(p_FmPort);
3454 if (err)
3455 RETURN_ERROR(MAJOR, err, NO_MSG);
3456
3457 err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3458 &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
3459 if (err)
3460 RETURN_ERROR(MAJOR, err, NO_MSG);
3461
3462 return E_OK;
3463}
3464
3465uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
3466{
3467 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3468
3469 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
3470 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3471 0);
3472
3473 return p_FmPort->bufferOffsets.dataOffset;
3474}
3475
3476uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
3477{
3478 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3479
3480 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3481 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3482 NULL);
3483
3484 if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
3485 return NULL;
3486
3487 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
3488}
3489
3490t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
3491{
3492 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3493
3494 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3495 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3496 NULL);
3497
3498 if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
3499 return NULL;
3500
3501 return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
3502}
3503
3504uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
3505{
3506 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3507
3508 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3509 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3510 NULL);
3511
3512 if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
3513 return NULL;
3514
3515 return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
3516}
3517
3518uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
3519{
3520 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3521
3522 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3523 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3524 NULL);
3525
3526 if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
3527 return NULL;
3528
3529 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
3530}
3531
3532t_Error FM_PORT_Disable(t_Handle h_FmPort)
3533{
3534 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3535 int err;
3536
3537 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3538 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3539
3540 if (p_FmPort->imEn)
3541 FmPortImDisable(p_FmPort);
3542
3543 err = fman_port_disable(&p_FmPort->port);
3544 if (err == -EBUSY)
3545 {
3546 DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
3547 p_FmPort->name));
3548 }
3549 else
3550 if (err != 0)
3551 {
3552 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
3553 }
3554
3555 p_FmPort->enabled = FALSE;
3556
3557 return E_OK;
3558}
3559
3560t_Error FM_PORT_Enable(t_Handle h_FmPort)
3561{
3562 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3563 int err;
3564
3565 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3566 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3567
3568 /* Used by FM_PORT_Free routine as indication
3569 if to disable port. Thus set it to TRUE prior
3570 to enabling itself. This way if part of enable
3571 process fails there will be still things
3572 to disable during Free. For example, if BMI
3573 enable succeeded but QMI failed, still BMI
3574 needs to be disabled by Free. */
3575 p_FmPort->enabled = TRUE;
3576
3577 if (p_FmPort->imEn)
3578 FmPortImEnable(p_FmPort);
3579
3580 err = fman_port_enable(&p_FmPort->port);
3581 if (err != 0)
3582 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
3583
3584 return E_OK;
3585}
3586
3587t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
3588{
3589 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3590 uint8_t factor, countUnitBit;
3591 uint16_t baseGran;
3592 struct fman_port_rate_limiter params;
3593 int err;
3594
3595 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3596 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3597
3598 switch (p_FmPort->portType)
3599 {
3600 case (e_FM_PORT_TYPE_TX_10G):
3601 case (e_FM_PORT_TYPE_TX):
3602 baseGran = BMI_RATE_LIMIT_GRAN_TX;
3603 break;
3604 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3605 baseGran = BMI_RATE_LIMIT_GRAN_OP;
3606 break;
3607 default:
3608 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3609 ("available for Tx and Offline parsing ports only"));
3610 }
3611
3612 countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
3613 /* normally, we use 1 usec as the reference count */
3614 factor = 1;
3615 /* if ratelimit is too small for a 1usec factor, multiply the factor */
3616 while (p_RateLimit->rateLimit < baseGran / factor)
3617 {
3618 if (countUnitBit == 31)
3619 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
3620
3621 countUnitBit++;
3622 factor <<= 1;
3623 }
3624 /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
3625 if (p_RateLimit->rateLimit
3626 > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
3627 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
3628
3629 if (!p_RateLimit->maxBurstSize
3630 || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
3631 RETURN_ERROR(
3632 MAJOR,
3633 E_INVALID_VALUE,
3634 ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
3635
3636 params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
3637 params.high_burst_size_gran = FALSE;
3638 params.burst_size = p_RateLimit->maxBurstSize;
3639 params.rate = p_RateLimit->rateLimit;
3640 params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
3641
3642 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3643 {
3644#ifndef FM_NO_ADVANCED_RATE_LIMITER
3645
3646 if ((p_FmPort->fmRevInfo.majorRev == 4)
3647 || (p_FmPort->fmRevInfo.majorRev >= 6))
3648 {
3649 params.high_burst_size_gran = TRUE;
3650 }
3651 else
3652#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
3653 {
3654 if (p_RateLimit->rateLimitDivider
3655 != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
3656 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
3657 ("FM_PORT_ConfigDualRateLimitScaleDown"));
3658
3659 if (p_RateLimit->maxBurstSize % 1000)
3660 {
3661 p_RateLimit->maxBurstSize =
3662 (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
3663 DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
3664 }
3665 else
3666 p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
3667 / 1000);
3668 }
3669 params.rate_factor =
3670 (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
3671 params.burst_size = p_RateLimit->maxBurstSize;
3672 }
3673
3674 err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
3675 if (err != 0)
3676 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
3677
3678 return E_OK;
3679}
3680
3681t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
3682{
3683 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3684 int err;
3685
3686 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3687 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3688
3689 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
3690 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
3691 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
3692 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3693 ("available for Tx and Offline parsing ports only"));
3694
3695 err = fman_port_delete_rate_limiter(&p_FmPort->port);
3696 if (err != 0)
3697 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
3698 return E_OK;
3699}
3700
3701t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
3702 uint8_t wq)
3703{
3704 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3705 uint32_t tmpReg;
3706 uint32_t wqTmpReg;
3707
3708 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3709 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3710
3711 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
3712 && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
3713 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3714 ("PFC mapping is available for Tx ports only"));
3715
3716 if (prio > 7)
3717 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
3718 ("PFC priority (%d) is out of range (0-7)", prio));
3719 if (wq > 7)
3720 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
3721 ("WQ (%d) is out of range (0-7)", wq));
3722
3723 tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
3724 tmpReg &= ~(0xf << ((7 - prio) * 4));
3725 wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
3726 tmpReg |= wqTmpReg;
3727
3728 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
3729 tmpReg);
3730
3731 return E_OK;
3732}
3733
3734t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
3735{
3736 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3737
3738 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3739 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3740
3741 fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
3742
3743 return E_OK;
3744}
3745
3746t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
3747{
3748 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3749 int err;
3750
3751 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3752 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3753
3754 err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
3755 if (err != 0)
3756 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
3757 return E_OK;
3758}
3759
3760t_Error FM_PORT_SetPerformanceCountersParams(
3761 t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
3762{
3763 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3764 struct fman_port_perf_cnt_params params;
3765 int err;
3766
3767 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3768
3769 /* check parameters */
3770 if (!p_FmPortPerformanceCnt->taskCompVal
3771 || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
3772 RETURN_ERROR(
3773 MAJOR,
3774 E_INVALID_VALUE,
3775 ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
3776 if (!p_FmPortPerformanceCnt->dmaCompVal
3777 || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
3778 RETURN_ERROR(
3779 MAJOR,
3780 E_INVALID_VALUE,
3781 ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
3782 if (!p_FmPortPerformanceCnt->fifoCompVal
3783 || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
3784 RETURN_ERROR(
3785 MAJOR,
3786 E_INVALID_VALUE,
3787 ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
3788 if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
3789 RETURN_ERROR(
3790 MAJOR,
3791 E_INVALID_VALUE,
3792 ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
3793
3794 switch (p_FmPort->portType)
3795 {
3796 case (e_FM_PORT_TYPE_RX_10G):
3797 case (e_FM_PORT_TYPE_RX):
3798 if (!p_FmPortPerformanceCnt->queueCompVal
3799 || (p_FmPortPerformanceCnt->queueCompVal
3800 > MAX_PERFORMANCE_RX_QUEUE_COMP))
3801 RETURN_ERROR(
3802 MAJOR,
3803 E_INVALID_VALUE,
3804 ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
3805 break;
3806 case (e_FM_PORT_TYPE_TX_10G):
3807 case (e_FM_PORT_TYPE_TX):
3808 if (!p_FmPortPerformanceCnt->queueCompVal
3809 || (p_FmPortPerformanceCnt->queueCompVal
3810 > MAX_PERFORMANCE_TX_QUEUE_COMP))
3811 RETURN_ERROR(
3812 MAJOR,
3813 E_INVALID_VALUE,
3814 ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
3815 break;
3816 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3817 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
3818 if (p_FmPortPerformanceCnt->queueCompVal)
3819 RETURN_ERROR(
3820 MAJOR,
3821 E_INVALID_VALUE,
3822 ("performanceCnt.queueCompVal is not relevant for H/O ports."));
3823 break;
3824 default:
3825 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
3826 }
3827
3828 params.task_val = p_FmPortPerformanceCnt->taskCompVal;
3829 params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
3830 params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
3831 params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
3832
3833 err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
3834 if (err != 0)
3835 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
3836
3837 return E_OK;
3838}
3839
3840t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
3841{
3842 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3843 t_FmPortPerformanceCnt currParams, savedParams;
3844 t_Error err;
3845 bool underTest, failed = FALSE;
3846
3847 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3848
3849 XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
3850 p_FmPort->portType, p_FmPort->portId);
3851
3852 currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
3853 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3854 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
3855 currParams.queueCompVal = 0;
3856 else
3857 currParams.queueCompVal = 1;
3858 currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
3859 currParams.fifoCompVal = p_FmPort->fifoBufs.num;
3860
3861 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3862 ClearPerfCnts(p_FmPort);
3863 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
3864 != E_OK)
3865 RETURN_ERROR(MAJOR, err, NO_MSG);
3866 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
3867 XX_UDelay(1000000);
3868 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3869 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
3870 {
3871 XX_Print(
3872 "Max num of defined port tasks (%d) utilized - Please enlarge\n",
3873 p_FmPort->tasks.num);
3874 failed = TRUE;
3875 }
3876 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
3877 {
3878 XX_Print(
3879 "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
3880 p_FmPort->openDmas.num);
3881 failed = TRUE;
3882 }
3883 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
3884 {
3885 XX_Print(
3886 "Max size of defined port fifo (%d) utilized - Please enlarge\n",
3887 p_FmPort->fifoBufs.num);
3888 failed = TRUE;
3889 }
3890 if (failed)
3891 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
3892
3893 memset(&savedParams, 0, sizeof(savedParams));
3894 while (TRUE)
3895 {
3896 underTest = FALSE;
3897 if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
3898 {
3899 currParams.taskCompVal--;
3900 underTest = TRUE;
3901 }
3902 if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
3903 {
3904 currParams.dmaCompVal--;
3905 underTest = TRUE;
3906 }
3907 if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
3908 && !savedParams.fifoCompVal)
3909 {
3910 currParams.fifoCompVal -= BMI_FIFO_UNITS;
3911 underTest = TRUE;
3912 }
3913 if (!underTest)
3914 break;
3915
3916 ClearPerfCnts(p_FmPort);
3917 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
3918 != E_OK)
3919 RETURN_ERROR(MAJOR, err, NO_MSG);
3920 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
3921 XX_UDelay(1000000);
3922 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3923
3924 if (!savedParams.taskCompVal
3925 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
3926 savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
3927 if (!savedParams.dmaCompVal
3928 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
3929 savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
3930 if (!savedParams.fifoCompVal
3931 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
3932 savedParams.fifoCompVal = currParams.fifoCompVal
3933 + (2 * BMI_FIFO_UNITS);
3934 }
3935
3936 XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
3937 savedParams.taskCompVal, savedParams.dmaCompVal,
3938 savedParams.fifoCompVal);
3939 return E_OK;
3940}
3941
3942t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
3943{
3944 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3945 int err;
3946
3947 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3948 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3949
3950 err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
3951 if (err != 0)
3952 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
3953 return E_OK;
3954}
3955
3956t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
3957{
3958 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3959 volatile uint32_t *p_ErrDiscard = NULL;
3960 int err;
3961
3962 UNUSED(p_ErrDiscard);
3963 err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
3964 if (err != 0)
3965 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
3966
3967#ifdef FM_ERROR_VSP_NO_MATCH_SW006
3968 if (p_FmPort->fmRevInfo.majorRev >= 6)
3969 {
3970 t_FmPcdCtrlParamsPage *p_ParamsPage;
3971
3972 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
3973 (void**)&p_ParamsPage);
3974 ASSERT_COND(p_ParamsPage);
3975 switch (p_FmPort->portType)
3976 {
3977 case (e_FM_PORT_TYPE_RX_10G):
3978 case (e_FM_PORT_TYPE_RX):
3979 p_ErrDiscard =
3980 &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
3981 break;
3982 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3983 p_ErrDiscard =
3984 &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
3985 break;
3986 default:
3987 RETURN_ERROR(
3988 MAJOR, E_INVALID_OPERATION,
3989 ("available for Rx and offline parsing ports only"));
3990 }
3991 WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
3992 GET_UINT32(*p_ErrDiscard) | errs);
3993 }
3994#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
3995
3996 return E_OK;
3997}
3998
3999t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
4000 bool enable)
4001{
4002 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4003 int err;
4004
4005 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4006 SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
4007 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4008
4009 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4010 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
4011 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4012 ("available for Rx ports only"));
4013
4014 err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
4015 if (err != 0)
4016 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
4017 return E_OK;
4018}
4019
4020t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
4021{
4022 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4023
4024 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4025 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
4026 p_BmiStats->cntCycle =
4027 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4028 /* fmbm_rccn */
4029 p_BmiStats->cntTaskUtil =
4030 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4031 /* fmbm_rtuc */
4032 p_BmiStats->cntQueueUtil =
4033 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
4034 /* fmbm_rrquc */
4035 p_BmiStats->cntDmaUtil =
4036 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4037 /* fmbm_rduc */
4038 p_BmiStats->cntFifoUtil =
4039 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4040 /* fmbm_rfuc */
4041 p_BmiStats->cntRxPauseActivation =
4042 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
4043 /* fmbm_rpac */
4044 p_BmiStats->cntFrame =
4045 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4046 /* fmbm_rfrc */
4047 p_BmiStats->cntDiscardFrame =
4048 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4049 /* fmbm_rfdc */
4050 p_BmiStats->cntDeallocBuf =
4051 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4052 /* fmbm_rbdc */
4053 p_BmiStats->cntRxBadFrame =
4054 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
4055 /* fmbm_rfbc */
4056 p_BmiStats->cntRxLargeFrame =
4057 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
4058 /* fmbm_rlfc */
4059 p_BmiStats->cntRxFilterFrame =
4060 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
4061 /* fmbm_rffc */
4062 p_BmiStats->cntRxListDmaErr =
4063 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
4064 /* fmbm_rfldec */
4065 p_BmiStats->cntRxOutOfBuffersDiscard =
4066 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
4067 /* fmbm_rodc */
4068 p_BmiStats->cntWredDiscard = 0;
4069 p_BmiStats->cntLengthErr = 0;
4070 p_BmiStats->cntUnsupportedFormat = 0;
4071 }
4072 else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
4073 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
4074 p_BmiStats->cntCycle =
4075 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4076 /* fmbm_tccn */
4077 p_BmiStats->cntTaskUtil =
4078 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4079 /* fmbm_ttuc */
4080 p_BmiStats->cntQueueUtil =
4081 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
4082 /* fmbm_ttcquc */
4083 p_BmiStats->cntDmaUtil =
4084 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4085 /* fmbm_tduc */
4086 p_BmiStats->cntFifoUtil =
4087 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4088 /* fmbm_tfuc */
4089 p_BmiStats->cntRxPauseActivation = 0;
4090 p_BmiStats->cntFrame =
4091 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4092 /* fmbm_tfrc */
4093 p_BmiStats->cntDiscardFrame =
4094 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4095 /* fmbm_tfdc */
4096 p_BmiStats->cntDeallocBuf =
4097 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4098 /* fmbm_tbdc */
4099 p_BmiStats->cntRxBadFrame = 0;
4100 p_BmiStats->cntRxLargeFrame = 0;
4101 p_BmiStats->cntRxFilterFrame = 0;
4102 p_BmiStats->cntRxListDmaErr = 0;
4103 p_BmiStats->cntRxOutOfBuffersDiscard = 0;
4104 p_BmiStats->cntWredDiscard = 0;
4105 p_BmiStats->cntLengthErr =
4106 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
4107 /* fmbm_tfledc */
4108 p_BmiStats->cntUnsupportedFormat =
4109 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
4110 /* fmbm_tfufdc */
4111 }
4112 else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
4113 p_BmiStats->cntCycle =
4114 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4115 /* fmbm_occn */
4116 p_BmiStats->cntTaskUtil =
4117 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4118 /* fmbm_otuc */
4119 p_BmiStats->cntQueueUtil = 0;
4120 p_BmiStats->cntDmaUtil =
4121 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4122 /* fmbm_oduc */
4123 p_BmiStats->cntFifoUtil =
4124 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4125 /* fmbm_ofuc*/
4126 p_BmiStats->cntRxPauseActivation = 0;
4127 p_BmiStats->cntFrame =
4128 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4129 /* fmbm_ofrc */
4130 p_BmiStats->cntDiscardFrame =
4131 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4132 /* fmbm_ofdc */
4133 p_BmiStats->cntDeallocBuf =
4134 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4135 /* fmbm_obdc*/
4136 p_BmiStats->cntRxBadFrame = 0;
4137 p_BmiStats->cntRxLargeFrame = 0;
4138 p_BmiStats->cntRxFilterFrame =
4139 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
4140 /* fmbm_offc */
4141 p_BmiStats->cntRxListDmaErr =
4142 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
4143 /* fmbm_ofldec */
4144 p_BmiStats->cntRxOutOfBuffersDiscard =
4145 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
4146 /* fmbm_rodc */
4147 p_BmiStats->cntWredDiscard =
4148 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
4149 /* fmbm_ofwdc */
4150 p_BmiStats->cntLengthErr =
4151 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
4152 /* fmbm_ofledc */
4153 p_BmiStats->cntUnsupportedFormat =
4154 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
4155 /* fmbm_ofufdc */
4156 }
4157 return E_OK;
4158}
4159
4160uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
4161{
4162 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4163 bool bmiCounter = FALSE;
4164 enum fman_port_stats_counters statsType;
4165 enum fman_port_perf_counters perfType;
4166 enum fman_port_qmi_counters queueType;
4167 bool isStats;
4168 t_Error errCode;
4169
4170 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
4171 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4172
4173 switch (counter)
4174 {
4175 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4176 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4177 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4178 /* check that counter is available for the port type */
4179 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4180 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4181 {
4182 REPORT_ERROR(MINOR, E_INVALID_STATE,
4183 ("Requested counter is not available for Rx ports"));
4184 return 0;
4185 }
4186 bmiCounter = FALSE;
4187 break;
4188 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4189 bmiCounter = FALSE;
4190 break;
4191 default: /* BMI counters (or error - will be checked in BMI routine )*/
4192 bmiCounter = TRUE;
4193 break;
4194 }
4195
4196 if (bmiCounter)
4197 {
4198 errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
4199 &perfType, &isStats);
4200 if (errCode != E_OK)
4201 {
4202 REPORT_ERROR(MINOR, errCode, NO_MSG);
4203 return 0;
4204 }
4205 if (isStats)
4206 return fman_port_get_stats_counter(&p_FmPort->port, statsType);
4207 else
4208 return fman_port_get_perf_counter(&p_FmPort->port, perfType);
4209 }
4210 else /* QMI counter */
4211 {
4212 /* check that counters are enabled */
4213 if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
4214 & QMI_PORT_CFG_EN_COUNTERS))
4215
4216 {
4217 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
4218 return 0;
4219 }
4220
4221 /* Set counter */
4222 switch (counter)
4223 {
4224 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4225 queueType = E_FMAN_PORT_ENQ_TOTAL;
4226 break;
4227 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4228 queueType = E_FMAN_PORT_DEQ_TOTAL;
4229 break;
4230 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4231 queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
4232 break;
4233 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4234 queueType = E_FMAN_PORT_DEQ_CONFIRM;
4235 break;
4236 default:
4237 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
4238 return 0;
4239 }
4240
4241 return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
4242 }
4243
4244 return 0;
4245}
4246
4247t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
4248 uint32_t value)
4249{
4250 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4251 bool bmiCounter = FALSE;
4252 enum fman_port_stats_counters statsType;
4253 enum fman_port_perf_counters perfType;
4254 enum fman_port_qmi_counters queueType;
4255 bool isStats;
4256 t_Error errCode;
4257
4258 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4259 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4260
4261 switch (counter)
4262 {
4263 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4264 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4265 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4266 /* check that counter is available for the port type */
4267 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4268 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4269 RETURN_ERROR(
4270 MINOR, E_INVALID_STATE,
4271 ("Requested counter is not available for Rx ports"));
4272 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4273 bmiCounter = FALSE;
4274 break;
4275 default: /* BMI counters (or error - will be checked in BMI routine )*/
4276 bmiCounter = TRUE;
4277 break;
4278 }
4279
4280 if (bmiCounter)
4281 {
4282 errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
4283 &perfType, &isStats);
4284 if (errCode != E_OK)
4285 {
4286 RETURN_ERROR(MINOR, errCode, NO_MSG);
4287 }
4288 if (isStats)
4289 fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
4290 else
4291 fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
4292 }
4293 else /* QMI counter */
4294 {
4295 /* check that counters are enabled */
4296 if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
4297 & QMI_PORT_CFG_EN_COUNTERS))
4298 {
4299 RETURN_ERROR(MINOR, E_INVALID_STATE,
4300 ("Requested counter was not enabled"));
4301 }
4302
4303 /* Set counter */
4304 switch (counter)
4305 {
4306 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4307 queueType = E_FMAN_PORT_ENQ_TOTAL;
4308 break;
4309 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4310 queueType = E_FMAN_PORT_DEQ_TOTAL;
4311 break;
4312 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4313 queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
4314 break;
4315 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4316 queueType = E_FMAN_PORT_DEQ_CONFIRM;
4317 break;
4318 default:
4319 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4320 ("Requested counter is not available"));
4321 }
4322
4323 fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
4324 }
4325
4326 return E_OK;
4327}
4328
4329uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
4330{
4331 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4332
4333 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
4334 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4335
4336 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
4337 && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4338 {
4339 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
4340 return 0;
4341 }
4342 return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
4343}
4344
4345t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
4346 uint32_t value)
4347{
4348 t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
4349
4350 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4351 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4352
4353 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
4354 && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4355 RETURN_ERROR( MINOR, E_INVALID_STATE,
4356 ("Requested counter is not available for non-Rx ports"));
4357
4358 fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
4359 return E_OK;
4360}
4361bool FM_PORT_IsStalled(t_Handle h_FmPort)
4362{
4363 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4364 t_Error err;
4365 bool isStalled;
4366
4367 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
4368 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
4369 FALSE);
4370
4371 err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
4372 if (err != E_OK)
4373 {
4374 REPORT_ERROR(MAJOR, err, NO_MSG);
4375 return TRUE;
4376 }
4377 return isStalled;
4378}
4379
4380t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
4381{
4382 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4383
4384 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4385 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4386
4387 return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
4388}
4389
4390t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
4391{
4392 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4393 int err;
4394
4395 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4396 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4397
4398 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4399 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
4400 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4401 ("available for Rx ports only"));
4402
4403 if (l4Checksum)
4404 err = fman_port_modify_rx_fd_bits(
4405 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
4406 TRUE);
4407 else
4408 err = fman_port_modify_rx_fd_bits(
4409 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
4410 FALSE);
4411 if (err != 0)
4412 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
4413
4414 return E_OK;
4415}
4416
4417/*****************************************************************************/
4418/* API Run-time PCD Control unit functions */
4419/*****************************************************************************/
4420
4421#if (DPAA_VERSION >= 11)
4422t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
4423{
4424 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4425 t_Error err = E_OK;
4426 volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
4427 uint32_t tmpReg = 0, tmp = 0;
4428 uint16_t hwStoragePrflId;
4429
4430 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4431 SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
4432 /*for numOfProfiles = 0 don't call this function*/
4433 SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
4434 /*dfltRelativeId should be in the range of numOfProfiles*/
4435 SANITY_CHECK_RETURN_ERROR(
4436 p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
4437 E_INVALID_VALUE);
4438 /*p_FmPort should be from Rx type or OP*/
4439 SANITY_CHECK_RETURN_ERROR(
4440 ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
4441 E_INVALID_VALUE);
4442 /*port should be disabled*/
4443 SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
4444 /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
4445 SANITY_CHECK_RETURN_ERROR(
4446 ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
4447 E_INVALID_VALUE);
4448 /*should be called before SetPCD - this port should be without PCD*/
4449 SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
4450
4451 /*alloc window of VSPs for this port*/
4452 err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
4453 p_FmPort->portId, p_VSPParams->numOfProfiles);
4454 if (err != E_OK)
4455 RETURN_ERROR(MAJOR, err, NO_MSG);
4456
4457 /*get absolute VSP ID for dfltRelative*/
4458 err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
4459 p_FmPort->portId,
4460 p_VSPParams->dfltRelativeId,
4461 &hwStoragePrflId);
4462 if (err != E_OK)
4463 RETURN_ERROR(MAJOR, err, NO_MSG);
4464
4465 /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
4466 switch (p_FmPort->portType)
4467 {
4468 case (e_FM_PORT_TYPE_RX_10G):
4469 case (e_FM_PORT_TYPE_RX):
4470 p_BmiStorageProfileId =
4471 &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
4472 p_BmiVspe =
4473 &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
4474
4475 tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
4476 tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
4477 WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
4478
4479 tmpReg = GET_UINT32(*p_BmiVspe);
4480 WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
4481
4482 p_BmiStorageProfileId =
4483 &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
4484 p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
4485 hwStoragePrflId = p_VSPParams->dfltRelativeId;
4486 break;
4487
4488 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4489 tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
4490 WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
4491 tmpReg);
4492
4493 p_BmiStorageProfileId =
4494 &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
4495 p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
4496 tmp |= BMI_EBD_EN;
4497 break;
4498
4499 default:
4500 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4501 ("available for Rx and offline parsing ports only"));
4502 }
4503
4504 p_FmPort->vspe = TRUE;
4505 p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
4506
4507 tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
4508 tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
4509 WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
4510
4511 tmpReg = GET_UINT32(*p_BmiVspe);
4512 WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
4513 return E_OK;
4514}
4515#endif /* (DPAA_VERSION >= 11) */
4516
4517t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
4518{
4519 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4520 t_Error err = E_OK;
4521
4522 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
4523 ASSERT_COND(p_FmPort->h_FmPcd);
4524
4525 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4526 {
4527 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4528 return ERROR_CODE(E_BUSY);
4529 }
4530
4531 if (numOfProfiles)
4532 {
4533 err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
4534 p_FmPort->hardwarePortId, numOfProfiles);
4535 if (err)
4536 RETURN_ERROR(MAJOR, err, NO_MSG);
4537 }
4538 /* set the port handle within the PCD policer, even if no profiles defined */
4539 FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
4540
4541 RELEASE_LOCK(p_FmPort->lock);
4542
4543 return E_OK;
4544}
4545
4546t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
4547{
4548 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4549 t_Error err = E_OK;
4550
4551 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4552 {
4553 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4554 return ERROR_CODE(E_BUSY);
4555 }
4556
4557 err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
4558
4559 RELEASE_LOCK(p_FmPort->lock);
4560
4561 if (err)
4562 RETURN_ERROR(MAJOR, err, NO_MSG);
4563
4564 return E_OK;
4565}
4566
4567t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
4568 t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
4569{
4570 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4571 volatile uint32_t *p_BmiHpnia = NULL;
4572 uint32_t tmpReg;
4573 uint8_t relativeSchemeId;
4574 uint8_t physicalSchemeId;
4575
4576 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4577 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4578 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
4579 E_INVALID_STATE);
4580
4581 tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
4582 switch (p_FmPort->portType)
4583 {
4584 case (e_FM_PORT_TYPE_RX_10G):
4585 case (e_FM_PORT_TYPE_RX):
4586 p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
4587 break;
4588 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4589 p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
4590 break;
4591 default:
4592 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4593 ("available for Rx and offline parsing ports only"));
4594 }
4595
4596 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4597 {
4598 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4599 return ERROR_CODE(E_BUSY);
4600 }
4601
4602 /* if we want to change to direct scheme, we need to check that this scheme is valid */
4603 if (p_FmPcdKgScheme->direct)
4604 {
4605 physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
4606 /* check that this scheme is bound to this port */
4607 if (!(p_FmPort->schemesPerPortVector
4608 & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
4609 {
4610 RELEASE_LOCK(p_FmPort->lock);
4611 RETURN_ERROR(
4612 MAJOR, E_INVALID_STATE,
4613 ("called with a scheme that is not bound to this port"));
4614 }
4615
4616 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
4617 physicalSchemeId);
4618 if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
4619 {
4620 RELEASE_LOCK(p_FmPort->lock);
4621 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
4622 ("called with invalid Scheme "));
4623 }
4624
4625 if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
4626 {
4627 RELEASE_LOCK(p_FmPort->lock);
4628 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4629 ("called with uninitialized Scheme "));
4630 }
4631
4632 WRITE_UINT32(
4633 *p_BmiHpnia,
4634 NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
4635 }
4636 else
4637 /* change to indirect scheme */
4638 WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
4639 RELEASE_LOCK(p_FmPort->lock);
4640
4641 return E_OK;
4642}
4643
4644t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
4645 t_Handle h_Profile)
4646{
4647 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4648 volatile uint32_t *p_BmiNia;
4649 volatile uint32_t *p_BmiHpnia;
4650 uint32_t tmpReg;
4651 uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
4652
4653 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4654 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4655 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
4656 E_INVALID_STATE);
4657
4658 /* check relevance of this routine - only when policer is used
4659 directly after BMI or Parser */
4660 if ((p_FmPort->pcdEngines & FM_PCD_KG)
4661 || (p_FmPort->pcdEngines & FM_PCD_CC))
4662 RETURN_ERROR(
4663 MAJOR,
4664 E_INVALID_STATE,
4665 ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
4666
4667 switch (p_FmPort->portType)
4668 {
4669 case (e_FM_PORT_TYPE_RX_10G):
4670 case (e_FM_PORT_TYPE_RX):
4671 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
4672 p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
4673 tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
4674 break;
4675 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4676 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
4677 p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
4678 tmpReg = 0;
4679 break;
4680 default:
4681 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4682 ("available for Rx and offline parsing ports only"));
4683 }
4684
4685 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4686 {
4687 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4688 return ERROR_CODE(E_BUSY);
4689 }
4690
4691 if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
4692 {
4693 RELEASE_LOCK(p_FmPort->lock);
4694 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
4695 }
4696
4697 tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
4698
4699 if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
4700 {
4701 /* update BMI HPNIA */
4702 WRITE_UINT32(*p_BmiHpnia, tmpReg);
4703 }
4704 else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
4705 {
4706 /* rfne may contain FDCS bits, so first we read them. */
4707 tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
4708 /* update BMI NIA */
4709 WRITE_UINT32(*p_BmiNia, tmpReg);
4710 }RELEASE_LOCK(p_FmPort->lock);
4711
4712 return E_OK;
4713}
4714
4715t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
4716{
4717 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4718 t_Error err = E_OK;
4719 volatile uint32_t *p_BmiCcBase = NULL;
4720 volatile uint32_t *p_BmiNia = NULL;
4721 uint32_t ccTreePhysOffset;
4722
4723 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4724 SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
4725
4726 if (p_FmPort->imEn)
4727 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4728 ("available for non-independent mode ports only"));
4729
4730 /* get PCD registers pointers */
4731 switch (p_FmPort->portType)
4732 {
4733 case (e_FM_PORT_TYPE_RX_10G):
4734 case (e_FM_PORT_TYPE_RX):
4735 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
4736 break;
4737 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4738 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
4739 break;
4740 default:
4741 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4742 ("available for Rx and offline parsing ports only"));
4743 }
4744
4745 /* check that current NIA is BMI to BMI */
4746 if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
4747 != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
4748 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4749 ("may be called only for ports in BMI-to-BMI state."));
4750
4751 if (p_FmPort->pcdEngines & FM_PCD_CC)
4752 {
4753 if (p_FmPort->h_IpReassemblyManip)
4754 {
4755 err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
4756 p_FmPort->h_IpReassemblyManip, FALSE);
4757 if (err != E_OK)
4758 {
4759 RETURN_ERROR(MAJOR, err, NO_MSG);
4760 }
4761 }
4762 else
4763 if (p_FmPort->h_CapwapReassemblyManip)
4764 {
4765 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
4766 p_FmPort->h_CapwapReassemblyManip,
4767 FALSE);
4768 if (err != E_OK)
4769 {
4770 RETURN_ERROR(MAJOR, err, NO_MSG);
4771 }
4772 }
4773 switch (p_FmPort->portType)
4774 {
4775 case (e_FM_PORT_TYPE_RX_10G):
4776 case (e_FM_PORT_TYPE_RX):
4777 p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
4778 break;
4779 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4780 p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
4781 break;
4782 default:
4783 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
4784 }
4785
4786 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4787 {
4788 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4789 return ERROR_CODE(E_BUSY);
4790 }
4791 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
4792 &ccTreePhysOffset, h_FmPort);
4793 if (err)
4794 {
4795 RELEASE_LOCK(p_FmPort->lock);
4796 RETURN_ERROR(MAJOR, err, NO_MSG);
4797 }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
4798
4799 p_FmPort->ccTreeId = h_CcTree;
4800 RELEASE_LOCK(p_FmPort->lock);
4801 }
4802 else
4803 RETURN_ERROR( MAJOR, E_INVALID_STATE,
4804 ("Coarse Classification not defined for this port."));
4805
4806 return E_OK;
4807}
4808
4809t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
4810{
4811 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4812 t_Error err = E_OK;
4813
4814 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4815 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4816
4817 if (p_FmPort->imEn)
4818 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4819 ("available for non-independent mode ports only"));
4820
4821 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4822 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4823 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4824 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4825 ("available for Rx and offline parsing ports only"));
4826
4827 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4828 {
4829 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4830 return ERROR_CODE(E_BUSY);
4831 }
4832
4833 if (p_FmPort->h_ReassemblyTree)
4834 p_FmPort->pcdEngines |= FM_PCD_CC;
4835
4836 err = AttachPCD(h_FmPort);
4837 RELEASE_LOCK(p_FmPort->lock);
4838
4839 return err;
4840}
4841
4842t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
4843{
4844 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4845 t_Error err = E_OK;
4846
4847 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4848 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4849
4850 if (p_FmPort->imEn)
4851 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4852 ("available for non-independent mode ports only"));
4853
4854 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4855 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4856 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4857 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4858 ("available for Rx and offline parsing ports only"));
4859
4860 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4861 {
4862 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4863 return ERROR_CODE(E_BUSY);
4864 }
4865
4866 err = DetachPCD(h_FmPort);
4867 if (err != E_OK)
4868 {
4869 RELEASE_LOCK(p_FmPort->lock);
4870 RETURN_ERROR(MAJOR, err, NO_MSG);
4871 }
4872
4873 if (p_FmPort->h_ReassemblyTree)
4874 p_FmPort->pcdEngines &= ~FM_PCD_CC;
4875 RELEASE_LOCK(p_FmPort->lock);
4876
4877 return E_OK;
4878}
4879
4880t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
4881{
4882 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4883 t_Error err = E_OK;
4884 t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
4885 t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
4886 t_FmPortPcdCcParams fmPortPcdCcParams;
4887 t_FmPortGetSetCcParams fmPortGetSetCcParams;
4888
4889 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4890 SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
4891 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4892
4893 if (p_FmPort->imEn)
4894 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4895 ("available for non-independent mode ports only"));
4896
4897 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4898 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4899 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4900 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4901 ("available for Rx and offline parsing ports only"));
4902
4903 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4904 {
4905 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4906 return ERROR_CODE(E_BUSY);
4907 }
4908
4909 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
4910 ASSERT_COND(p_FmPort->h_FmPcd);
4911
4912 if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
4913 RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
4914 ("Tree handle must be given if CC is required"));
4915
4916 memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
4917 p_PcdParams = &modifiedPcdParams;
4918 if ((p_PcdParams->h_IpReassemblyManip)
4919#if (DPAA_VERSION >= 11)
4920 || (p_PcdParams->h_CapwapReassemblyManip)
4921#endif /* (DPAA_VERSION >= 11) */
4922 )
4923 {
4924 if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4925 && (p_PcdParams->pcdSupport
4926 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
4927 && (p_PcdParams->pcdSupport
4928 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
4929 && (p_PcdParams->pcdSupport
4930 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
4931 {
4932 RELEASE_LOCK(p_FmPort->lock);
4933 RETURN_ERROR( MAJOR, E_INVALID_STATE,
4934 ("pcdSupport must have KG for supporting Reassembly"));
4935 }
4936 p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
4937#if (DPAA_VERSION >= 11)
4938 if ((p_PcdParams->h_IpReassemblyManip)
4939 && (p_PcdParams->h_CapwapReassemblyManip))
4940 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4941 ("Either IP-R or CAPWAP-R is allowed"));
4942 if ((p_PcdParams->h_CapwapReassemblyManip)
4943 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4944 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4945 ("CAPWAP-R is allowed only on offline-port"));
4946 if (p_PcdParams->h_CapwapReassemblyManip)
4947 p_FmPort->h_CapwapReassemblyManip =
4948 p_PcdParams->h_CapwapReassemblyManip;
4949#endif /* (DPAA_VERSION >= 11) */
4950
4951 if (!p_PcdParams->p_CcParams)
4952 {
4953 if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4954 || (p_PcdParams->pcdSupport
4955 == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
4956 {
4957 RELEASE_LOCK(p_FmPort->lock);
4958 RETURN_ERROR(
4959 MAJOR,
4960 E_INVALID_STATE,
4961 ("PCD initialization structure is not consistent with pcdSupport"));
4962 }
4963
4964 /* No user-tree, need to build internal tree */
4965 p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
4966 sizeof(t_FmPcdCcTreeParams));
4967 if (!p_FmPcdCcTreeParams)
4968 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
4969 memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
4970 p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
4971 p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
4972 p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
4973
4974 if (!p_FmPort->h_ReassemblyTree)
4975 {
4976 RELEASE_LOCK(p_FmPort->lock);
4977 XX_Free(p_FmPcdCcTreeParams);
4978 RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
4979 ("FM_PCD_CcBuildTree for Reassembly failed"));
4980 }
4981 if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4982 p_PcdParams->pcdSupport =
4983 e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
4984 else
4985 p_PcdParams->pcdSupport =
4986 e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
4987
4988 memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
4989 fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
4990 p_PcdParams->p_CcParams = &fmPortPcdCcParams;
4991 XX_Free(p_FmPcdCcTreeParams);
4992 }
4993
4994 if (p_FmPort->h_IpReassemblyManip)
4995 err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
4996 p_PcdParams->p_CcParams->h_CcTree,
4997 p_PcdParams->h_NetEnv,
4998 p_FmPort->h_IpReassemblyManip, TRUE);
4999#if (DPAA_VERSION >= 11)
5000 else
5001 if (p_FmPort->h_CapwapReassemblyManip)
5002 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
5003 p_PcdParams->p_CcParams->h_CcTree,
5004 p_PcdParams->h_NetEnv,
5005 p_FmPort->h_CapwapReassemblyManip,
5006 TRUE);
5007#endif /* (DPAA_VERSION >= 11) */
5008
5009 if (err != E_OK)
5010 {
5011 if (p_FmPort->h_ReassemblyTree)
5012 {
5013 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5014 p_FmPort->h_ReassemblyTree = NULL;
5015 }RELEASE_LOCK(p_FmPort->lock);
5016 RETURN_ERROR(MAJOR, err, NO_MSG);
5017 }
5018 }
5019
5020 if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
5021 {
5022 if (p_FmPort->h_ReassemblyTree)
5023 {
5024 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5025 p_FmPort->h_ReassemblyTree = NULL;
5026 }RELEASE_LOCK(p_FmPort->lock);
5027 DBG(TRACE, ("Try LockAll - BUSY"));
5028 return ERROR_CODE(E_BUSY);
5029 }
5030
5031 err = SetPcd(h_FmPort, p_PcdParams);
5032 if (err)
5033 {
5034 if (p_FmPort->h_ReassemblyTree)
5035 {
5036 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5037 p_FmPort->h_ReassemblyTree = NULL;
5038 }
5039 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5040 RELEASE_LOCK(p_FmPort->lock);
5041 RETURN_ERROR(MAJOR, err, NO_MSG);
5042 }
5043
5044 if ((p_FmPort->pcdEngines & FM_PCD_PRS)
5045 && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
5046 {
5047 err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
5048 p_FmPort->hardwarePortId, TRUE);
5049 if (err)
5050 {
5051 DeletePcd(p_FmPort);
5052 if (p_FmPort->h_ReassemblyTree)
5053 {
5054 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5055 p_FmPort->h_ReassemblyTree = NULL;
5056 }
5057 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5058 RELEASE_LOCK(p_FmPort->lock);
5059 RETURN_ERROR(MAJOR, err, NO_MSG);
5060 }
5061 p_FmPort->includeInPrsStatistics = TRUE;
5062 }
5063
5064 FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
5065
5066 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5067 {
5068 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
5069
5070 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
5071 {
5072#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
5073 if ((p_FmPort->fmRevInfo.majorRev < 6) &&
5074 (p_FmPort->pcdEngines & FM_PCD_KG))
5075 {
5076 int i;
5077 for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
5078 /* The following function must be locked */
5079 FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
5080 p_PcdParams->p_KgParams->h_Schemes[i],
5081 UPDATE_KG_NIA_CC_WA,
5082 0);
5083 }
5084#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
5085
5086#if (DPAA_VERSION >= 11)
5087 {
5088 t_FmPcdCtrlParamsPage *p_ParamsPage;
5089
5090 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
5091 (void**)&p_ParamsPage);
5092 ASSERT_COND(p_ParamsPage);
5093 WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
5094 p_FmPort->savedBmiNia);
5095 }
5096#endif /* (DPAA_VERSION >= 11) */
5097
5098 /* Set post-bmi-fetch nia */
5099 p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
5100 p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
5101 | NIA_ENG_FM_CTL);
5102
5103 /* Set pre-bmi-fetch nia */
5104 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
5105#if (DPAA_VERSION >= 11)
5106 fmPortGetSetCcParams.setCcParams.nia =
5107 (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
5108#else
5109 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
5110#endif /* (DPAA_VERSION >= 11) */
5111 if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
5112 != E_OK)
5113 {
5114 DeletePcd(p_FmPort);
5115 if (p_FmPort->h_ReassemblyTree)
5116 {
5117 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5118 p_FmPort->h_ReassemblyTree = NULL;
5119 }
5120 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5121 RELEASE_LOCK(p_FmPort->lock);
5122 RETURN_ERROR(MAJOR, err, NO_MSG);
5123 }
5124 }
5125
5126 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5127
5128 /* Set pop-to-next-step nia */
5129#if (DPAA_VERSION == 10)
5130 if (p_FmPort->fmRevInfo.majorRev < 6)
5131 {
5132 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
5133 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
5134 }
5135 else
5136 {
5137#endif /* (DPAA_VERSION == 10) */
5138 fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
5139#if (DPAA_VERSION == 10)
5140 }
5141#endif /* (DPAA_VERSION == 10) */
5142 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5143 != E_OK)
5144 {
5145 DeletePcd(p_FmPort);
5146 if (p_FmPort->h_ReassemblyTree)
5147 {
5148 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5149 p_FmPort->h_ReassemblyTree = NULL;
5150 }RELEASE_LOCK(p_FmPort->lock);
5151 RETURN_ERROR(MAJOR, err, NO_MSG);
5152 }
5153
5154 /* Set post-bmi-prepare-to-enq nia */
5155 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
5156 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
5157 | NIA_ENG_FM_CTL);
5158 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5159 != E_OK)
5160 {
5161 DeletePcd(p_FmPort);
5162 if (p_FmPort->h_ReassemblyTree)
5163 {
5164 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5165 p_FmPort->h_ReassemblyTree = NULL;
5166 }RELEASE_LOCK(p_FmPort->lock);
5167 RETURN_ERROR(MAJOR, err, NO_MSG);
5168 }
5169
5170 if ((p_FmPort->h_IpReassemblyManip)
5171 || (p_FmPort->h_CapwapReassemblyManip))
5172 {
5173#if (DPAA_VERSION == 10)
5174 if (p_FmPort->fmRevInfo.majorRev < 6)
5175 {
5176 /* Overwrite post-bmi-prepare-to-enq nia */
5177 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
5178 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
5179 fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
5180 }
5181 else
5182 {
5183#endif /* (DPAA_VERSION == 10) */
5184 /* Set the ORR bit (for order-restoration) */
5185 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
5186 fmPortGetSetCcParams.setCcParams.nia =
5187 fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
5188#if (DPAA_VERSION == 10)
5189 }
5190#endif /* (DPAA_VERSION == 10) */
5191 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5192 != E_OK)
5193 {
5194 DeletePcd(p_FmPort);
5195 if (p_FmPort->h_ReassemblyTree)
5196 {
5197 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5198 p_FmPort->h_ReassemblyTree = NULL;
5199 }RELEASE_LOCK(p_FmPort->lock);
5200 RETURN_ERROR(MAJOR, err, NO_MSG);
5201 }
5202 }
5203 }
5204 else
5205 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5206
5207#if (DPAA_VERSION >= 11)
5208 {
5209 t_FmPcdCtrlParamsPage *p_ParamsPage;
5210
5211 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
5212
5213 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
5214 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5215 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
5216 | NIA_ENG_FM_CTL;
5217 else
5218 fmPortGetSetCcParams.setCcParams.nia =
5219 NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
5220 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5221 != E_OK)
5222 {
5223 DeletePcd(p_FmPort);
5224 if (p_FmPort->h_ReassemblyTree)
5225 {
5226 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5227 p_FmPort->h_ReassemblyTree = NULL;
5228 }RELEASE_LOCK(p_FmPort->lock);
5229 RETURN_ERROR(MAJOR, err, NO_MSG);
5230 }
5231
5232 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
5233 (void**)&p_ParamsPage);
5234 ASSERT_COND(p_ParamsPage);
5235
5236 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5237 WRITE_UINT32(
5238 p_ParamsPage->misc,
5239 GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
5240
5241 if ((p_FmPort->h_IpReassemblyManip)
5242 || (p_FmPort->h_CapwapReassemblyManip))
5243 {
5244 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
5245 WRITE_UINT32(
5246 p_ParamsPage->discardMask,
5247 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
5248 else
5249 WRITE_UINT32(
5250 p_ParamsPage->discardMask,
5251 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
5252 }
5253#ifdef FM_ERROR_VSP_NO_MATCH_SW006
5254 if (p_FmPort->vspe)
5255 WRITE_UINT32(
5256 p_ParamsPage->misc,
5257 GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
5258#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
5259 }
5260#endif /* (DPAA_VERSION >= 11) */
5261
5262 err = AttachPCD(h_FmPort);
5263 if (err)
5264 {
5265 DeletePcd(p_FmPort);
5266 if (p_FmPort->h_ReassemblyTree)
5267 {
5268 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5269 p_FmPort->h_ReassemblyTree = NULL;
5270 }RELEASE_LOCK(p_FmPort->lock);
5271 RETURN_ERROR(MAJOR, err, NO_MSG);
5272 }
5273
5274 RELEASE_LOCK(p_FmPort->lock);
5275
5276 return err;
5277}
5278
5279t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
5280{
5281 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5282 t_Error err = E_OK;
5283
5284 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
5285 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5286
5287 if (p_FmPort->imEn)
5288 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
5289 ("available for non-independant mode ports only"));
5290
5291 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5292 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5293 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5294 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
5295 ("available for Rx and offline parsing ports only"));
5296
5297 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5298 {
5299 DBG(TRACE, ("FM Port Try Lock - BUSY"));
5300 return ERROR_CODE(E_BUSY);
5301 }
5302
5303 err = DetachPCD(h_FmPort);
5304 if (err)
5305 {
5306 RELEASE_LOCK(p_FmPort->lock);
5307 RETURN_ERROR(MAJOR, err, NO_MSG);
5308 }
5309
5310 FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
5311
5312 /* we do it anyway, instead of checking if included */
5313 if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
5314 {
5315 FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
5316 p_FmPort->hardwarePortId, FALSE);
5317 p_FmPort->includeInPrsStatistics = FALSE;
5318 }
5319
5320 if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
5321 {
5322 RELEASE_LOCK(p_FmPort->lock);
5323 DBG(TRACE, ("Try LockAll - BUSY"));
5324 return ERROR_CODE(E_BUSY);
5325 }
5326
5327 err = DeletePcd(h_FmPort);
5328 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5329 if (err)
5330 {
5331 RELEASE_LOCK(p_FmPort->lock);
5332 RETURN_ERROR(MAJOR, err, NO_MSG);
5333 }
5334
5335 if (p_FmPort->h_ReassemblyTree)
5336 {
5337 err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5338 if (err)
5339 {
5340 RELEASE_LOCK(p_FmPort->lock);
5341 RETURN_ERROR(MAJOR, err, NO_MSG);
5342 }
5343 p_FmPort->h_ReassemblyTree = NULL;
5344 }RELEASE_LOCK(p_FmPort->lock);
5345
5346 return err;
5347}
5348
5349t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
5350 t_FmPcdPortSchemesParams *p_PortScheme)
5351{
5352 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5353 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
5354 t_Error err = E_OK;
5355 uint32_t tmpScmVec = 0;
5356 int i;
5357
5358 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5359 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5360 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
5361 E_INVALID_STATE);
5362
5363 schemeBind.netEnvId = p_FmPort->netEnvId;
5364 schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
5365 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
5366 schemeBind.useClsPlan = p_FmPort->useClsPlan;
5367 for (i = 0; i < schemeBind.numOfSchemes; i++)
5368 {
5369 schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
5370 p_PortScheme->h_Schemes[i]);
5371 /* build vector */
5372 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
5373 }
5374
5375 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5376 {
5377 DBG(TRACE, ("FM Port Try Lock - BUSY"));
5378 return ERROR_CODE(E_BUSY);
5379 }
5380
5381 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
5382 if (err == E_OK)
5383 p_FmPort->schemesPerPortVector |= tmpScmVec;
5384
5385#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
5386 if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
5387 (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
5388 (p_FmPort->fmRevInfo.majorRev < 6))
5389 {
5390 for (i=0; i<p_PortScheme->numOfSchemes; i++)
5391 FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
5392 }
5393#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
5394
5395 RELEASE_LOCK(p_FmPort->lock);
5396
5397 return err;
5398}
5399
5400t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
5401 t_FmPcdPortSchemesParams *p_PortScheme)
5402{
5403 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5404 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
5405 t_Error err = E_OK;
5406 uint32_t tmpScmVec = 0;
5407 int i;
5408
5409 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5410 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5411 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
5412 E_INVALID_STATE);
5413
5414 schemeBind.netEnvId = p_FmPort->netEnvId;
5415 schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
5416 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
5417 for (i = 0; i < schemeBind.numOfSchemes; i++)
5418 {
5419 schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
5420 p_PortScheme->h_Schemes[i]);
5421 /* build vector */
5422 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
5423 }
5424
5425 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5426 {
5427 DBG(TRACE, ("FM Port Try Lock - BUSY"));
5428 return ERROR_CODE(E_BUSY);
5429 }
5430
5431 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
5432 if (err == E_OK)
5433 p_FmPort->schemesPerPortVector &= ~tmpScmVec;
5434 RELEASE_LOCK(p_FmPort->lock);
5435
5436 return err;
5437}
5438
5439t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
5440 t_FmPortCongestionGrps *p_CongestionGrps)
5441{
5442 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5443 uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
5444 uint8_t mod, index;
5445 uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
5446 int err;
5447#if (DPAA_VERSION >= 11)
5448 int j;
5449#endif /* (DPAA_VERSION >= 11) */
5450
5451 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5452
5453 /* un-necessary check of the indexes; probably will be needed in the future when there
5454 will be more CGs available ....
5455 for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5456 if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
5457 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
5458 */
5459
5460#ifdef FM_NO_OP_OBSERVED_CGS
5461 if ((p_FmPort->fmRevInfo.majorRev != 4) &&
5462 (p_FmPort->fmRevInfo.majorRev < 6))
5463 {
5464 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
5465 (p_FmPort->portType != e_FM_PORT_TYPE_RX))
5466 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
5467 }
5468 else
5469#endif /* FM_NO_OP_OBSERVED_CGS */
5470 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5471 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5472 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5473 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5474 ("Available for Rx & OP ports only"));
5475
5476 /* Prepare groups map array */
5477 memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
5478 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5479 {
5480 index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
5481 mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
5482 if (p_FmPort->fmRevInfo.majorRev != 4)
5483 grpsMap[7 - index] |= (uint32_t)(1 << mod);
5484 else
5485 grpsMap[0] |= (uint32_t)(1 << mod);
5486 }
5487
5488 memset(&priorityTmpArray, 0,
5489 FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
5490
5491 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5492 {
5493#if (DPAA_VERSION >= 11)
5494 for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
5495 if (p_CongestionGrps->pfcPrioritiesEn[i][j])
5496 priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
5497 (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
5498#endif /* (DPAA_VERSION >= 11) */
5499 }
5500
5501#if (DPAA_VERSION >= 11)
5502 for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
5503 {
5504 err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
5505 priorityTmpArray[i]);
5506 if (err)
5507 return err;
5508 }
5509#endif /* (DPAA_VERSION >= 11) */
5510
5511 err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
5512 if (err != 0)
5513 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
5514
5515 return E_OK;
5516}
5517
5518t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
5519 t_FmPortCongestionGrps *p_CongestionGrps)
5520{
5521 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5522 uint8_t mod, index;
5523 uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
5524 int err;
5525
5526 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5527
5528 {
5529#ifdef FM_NO_OP_OBSERVED_CGS
5530 t_FmRevisionInfo revInfo;
5531
5532 FM_GetRevision(p_FmPort->h_Fm, &revInfo);
5533 if (revInfo.majorRev != 4)
5534 {
5535 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
5536 (p_FmPort->portType != e_FM_PORT_TYPE_RX))
5537 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
5538 }
5539 else
5540#endif /* FM_NO_OP_OBSERVED_CGS */
5541 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5542 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5543 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5544 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5545 ("Available for Rx & OP ports only"));
5546 }
5547
5548 /* Prepare groups map array */
5549 memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
5550 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5551 {
5552 index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
5553 mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
5554 if (p_FmPort->fmRevInfo.majorRev != 4)
5555 grpsMap[7 - index] |= (uint32_t)(1 << mod);
5556 else
5557 grpsMap[0] |= (uint32_t)(1 << mod);
5558 }
5559
5560#if (DPAA_VERSION >= 11)
5561 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5562 {
5563 t_Error err = FmSetCongestionGroupPFCpriority(
5564 p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
5565 0);
5566 if (err)
5567 return err;
5568 }
5569#endif /* (DPAA_VERSION >= 11) */
5570
5571 err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
5572 if (err != 0)
5573 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
5574 ("fman_port_remove_congestion_grps"));
5575 return E_OK;
5576}
5577
5578#if (DPAA_VERSION >= 11)
5579t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
5580 uint32_t *p_Ipv4OptionsCount)
5581{
5582 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5583
5584 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5585 SANITY_CHECK_RETURN_ERROR(
5586 (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
5587 E_INVALID_VALUE);
5588 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
5589 SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
5590
5591 *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
5592
5593 return E_OK;
5594}
5595#endif /* (DPAA_VERSION >= 11) */
5596
5597t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
5598 t_FmPortDsarTablesSizes *params)
5599{
5600 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5601 p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
5602 sizeof(struct t_FmPortDsarTablesSizes));
5603 memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
5604 sizeof(struct t_FmPortDsarTablesSizes));
5605 return E_OK;
5606}
5607
5608static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
5609{
5610 uint32_t *param_page;
5611 t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
5612 t_ArCommonDesc *ArCommonDescPtr;
5613 uint32_t size = sizeof(t_ArCommonDesc);
5614 // ARP
5615 // should put here if (params->max_num_of_arp_entries)?
5616 size = ROUND_UP(size,4);
5617 size += sizeof(t_DsarArpDescriptor);
5618 size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
5619 size += sizeof(t_DsarArpStatistics);
5620 //ICMPV4
5621 size = ROUND_UP(size,4);
5622 size += sizeof(t_DsarIcmpV4Descriptor);
5623 size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
5624 size += sizeof(t_DsarIcmpV4Statistics);
5625 //ICMPV6
5626 size = ROUND_UP(size,4);
5627 size += sizeof(t_DsarIcmpV6Descriptor);
5628 size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
5629 size += sizeof(t_DsarIcmpV6Statistics);
5630 //ND
5631 size = ROUND_UP(size,4);
5632 size += sizeof(t_DsarNdDescriptor);
5633 size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
5634 size += sizeof(t_DsarIcmpV6Statistics);
5635 //SNMP
5636 size = ROUND_UP(size,4);
5637 size += sizeof(t_DsarSnmpDescriptor);
5638 size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
5639 * params->maxNumOfSnmpIPV4Entries;
5640 size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
5641 * params->maxNumOfSnmpIPV6Entries;
5642 size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
5643 size += params->maxNumOfSnmpOidChar;
5644 size += sizeof(t_DsarIcmpV6Statistics);
5645 //filters
5646 size = ROUND_UP(size,4);
5647 size += params->maxNumOfIpProtFiltering;
5648 size = ROUND_UP(size,4);
5649 size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
5650 size = ROUND_UP(size,4);
5651 size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
5652
5653 // add here for more protocols
5654
5655 // statistics
5656 size = ROUND_UP(size,4);
5657 size += sizeof(t_ArStatistics);
5658
5659 ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
5660
5661 param_page =
5662 XX_PhysToVirt(
5663 p_FmPort->fmMuramPhysBaseAddr
5664 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
5665 WRITE_UINT32(
5666 *param_page,
5667 (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
5668 return E_OK;
5669}
5670
5671t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
5672{
5673 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5674 return p_FmPort->deepSleepVars.autoResMaxSizes;
5675}
5676
5677struct arOffsets
5678{
5679 uint32_t arp;
5680 uint32_t nd;
5681 uint32_t icmpv4;
5682 uint32_t icmpv6;
5683 uint32_t snmp;
5684 uint32_t stats;
5685 uint32_t filtIp;
5686 uint32_t filtUdp;
5687 uint32_t filtTcp;
5688};
5689
5690static uint32_t AR_ComputeOffsets(struct arOffsets* of,
5691 struct t_FmPortDsarParams *params,
5692 t_FmPort *p_FmPort)
5693{
5694 uint32_t size = sizeof(t_ArCommonDesc);
5695 // ARP
5696 if (params->p_AutoResArpInfo)
5697 {
5698 size = ROUND_UP(size,4);
5699 of->arp = size;
5700 size += sizeof(t_DsarArpDescriptor);
5701 size += sizeof(t_DsarArpBindingEntry)
5702 * params->p_AutoResArpInfo->tableSize;
5703 size += sizeof(t_DsarArpStatistics);
5704 }
5705 // ICMPV4
5706 if (params->p_AutoResEchoIpv4Info)
5707 {
5708 size = ROUND_UP(size,4);
5709 of->icmpv4 = size;
5710 size += sizeof(t_DsarIcmpV4Descriptor);
5711 size += sizeof(t_DsarIcmpV4BindingEntry)
5712 * params->p_AutoResEchoIpv4Info->tableSize;
5713 size += sizeof(t_DsarIcmpV4Statistics);
5714 }
5715 // ICMPV6
5716 if (params->p_AutoResEchoIpv6Info)
5717 {
5718 size = ROUND_UP(size,4);
5719 of->icmpv6 = size;
5720 size += sizeof(t_DsarIcmpV6Descriptor);
5721 size += sizeof(t_DsarIcmpV6BindingEntry)
5722 * params->p_AutoResEchoIpv6Info->tableSize;
5723 size += sizeof(t_DsarIcmpV6Statistics);
5724 }
5725 // ND
5726 if (params->p_AutoResNdpInfo)
5727 {
5728 size = ROUND_UP(size,4);
5729 of->nd = size;
5730 size += sizeof(t_DsarNdDescriptor);
5731 size += sizeof(t_DsarIcmpV6BindingEntry)
5732 * (params->p_AutoResNdpInfo->tableSizeAssigned
5733 + params->p_AutoResNdpInfo->tableSizeTmp);
5734 size += sizeof(t_DsarIcmpV6Statistics);
5735 }
5736 // SNMP
5737 if (params->p_AutoResSnmpInfo)
5738 {
5739 size = ROUND_UP(size,4);
5740 of->snmp = size;
5741 size += sizeof(t_DsarSnmpDescriptor);
5742 size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
5743 * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
5744 size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
5745 * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
5746 size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
5747 size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
5748 size += sizeof(t_DsarIcmpV6Statistics);
5749 }
5750 //filters
5751 size = ROUND_UP(size,4);
5752 if (params->p_AutoResFilteringInfo)
5753 {
5754 of->filtIp = size;
5755 size += params->p_AutoResFilteringInfo->ipProtTableSize;
5756 size = ROUND_UP(size,4);
5757 of->filtUdp = size;
5758 size += params->p_AutoResFilteringInfo->udpPortsTableSize
5759 * sizeof(t_PortTblEntry);
5760 size = ROUND_UP(size,4);
5761 of->filtTcp = size;
5762 size += params->p_AutoResFilteringInfo->tcpPortsTableSize
5763 * sizeof(t_PortTblEntry);
5764 }
5765 // add here for more protocols
5766 // statistics
5767 size = ROUND_UP(size,4);
5768 of->stats = size;
5769 size += sizeof(t_ArStatistics);
5770 return size;
5771}
5772
5773uint32_t* ARDesc;
5774void PrsEnable(t_Handle p_FmPcd);
5775void PrsDisable(t_Handle p_FmPcd);
5776int PrsIsEnabled(t_Handle p_FmPcd);
5777t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
5778
5779static t_Error DsarCheckParams(t_FmPortDsarParams *params,
5780 t_FmPortDsarTablesSizes *sizes)
5781{
5782 bool macInit = FALSE;
5783 uint8_t mac[6];
5784 int i = 0;
5785
5786 // check table sizes
5787 if (params->p_AutoResArpInfo
5788 && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
5789 RETURN_ERROR(
5790 MAJOR, E_INVALID_VALUE,
5791 ("DSAR: Arp table size exceeds the configured maximum size."));
5792 if (params->p_AutoResEchoIpv4Info
5793 && sizes->maxNumOfEchoIpv4Entries
5794 < params->p_AutoResEchoIpv4Info->tableSize)
5795 RETURN_ERROR(
5796 MAJOR,
5797 E_INVALID_VALUE,
5798 ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
5799 if (params->p_AutoResNdpInfo
5800 && sizes->maxNumOfNdpEntries
5801 < params->p_AutoResNdpInfo->tableSizeAssigned
5802 + params->p_AutoResNdpInfo->tableSizeTmp)
5803 RETURN_ERROR(
5804 MAJOR, E_INVALID_VALUE,
5805 ("DSAR: NDP table size exceeds the configured maximum size."));
5806 if (params->p_AutoResEchoIpv6Info
5807 && sizes->maxNumOfEchoIpv6Entries
5808 < params->p_AutoResEchoIpv6Info->tableSize)
5809 RETURN_ERROR(
5810 MAJOR,
5811 E_INVALID_VALUE,
5812 ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
5813 if (params->p_AutoResSnmpInfo
5814 && sizes->maxNumOfSnmpOidEntries
5815 < params->p_AutoResSnmpInfo->oidsTblSize)
5816 RETURN_ERROR(
5817 MAJOR,
5818 E_INVALID_VALUE,
5819 ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
5820 if (params->p_AutoResSnmpInfo
5821 && sizes->maxNumOfSnmpIPV4Entries
5822 < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
5823 RETURN_ERROR(
5824 MAJOR,
5825 E_INVALID_VALUE,
5826 ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
5827 if (params->p_AutoResSnmpInfo
5828 && sizes->maxNumOfSnmpIPV6Entries
5829 < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
5830 RETURN_ERROR(
5831 MAJOR,
5832 E_INVALID_VALUE,
5833 ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
5834 if (params->p_AutoResFilteringInfo)
5835 {
5836 if (sizes->maxNumOfIpProtFiltering
5837 < params->p_AutoResFilteringInfo->ipProtTableSize)
5838 RETURN_ERROR(
5839 MAJOR,
5840 E_INVALID_VALUE,
5841 ("DSAR: ip filter table size exceeds the configured maximum size."));
5842 if (sizes->maxNumOfTcpPortFiltering
5843 < params->p_AutoResFilteringInfo->udpPortsTableSize)
5844 RETURN_ERROR(
5845 MAJOR,
5846 E_INVALID_VALUE,
5847 ("DSAR: udp filter table size exceeds the configured maximum size."));
5848 if (sizes->maxNumOfUdpPortFiltering
5849 < params->p_AutoResFilteringInfo->tcpPortsTableSize)
5850 RETURN_ERROR(
5851 MAJOR,
5852 E_INVALID_VALUE,
5853 ("DSAR: tcp filter table size exceeds the configured maximum size."));
5854 }
5855 /* check only 1 MAC address is configured (this is what ucode currently supports) */
5856 if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
5857 {
5858 memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
5859 i = 1;
5860 macInit = TRUE;
5861
5862 for (; i < params->p_AutoResArpInfo->tableSize; i++)
5863 if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
5864 RETURN_ERROR(
5865 MAJOR, E_INVALID_VALUE,
5866 ("DSAR: Only 1 mac address is currently supported."));
5867 }
5868 if (params->p_AutoResEchoIpv4Info
5869 && params->p_AutoResEchoIpv4Info->tableSize)
5870 {
5871 i = 0;
5872 if (!macInit)
5873 {
5874 memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
5875 6);
5876 i = 1;
5877 macInit = TRUE;
5878 }
5879 for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
5880 if (memcmp(mac,
5881 params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
5882 RETURN_ERROR(
5883 MAJOR, E_INVALID_VALUE,
5884 ("DSAR: Only 1 mac address is currently supported."));
5885 }
5886 if (params->p_AutoResEchoIpv6Info
5887 && params->p_AutoResEchoIpv6Info->tableSize)
5888 {
5889 i = 0;
5890 if (!macInit)
5891 {
5892 memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
5893 6);
5894 i = 1;
5895 macInit = TRUE;
5896 }
5897 for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
5898 if (memcmp(mac,
5899 params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
5900 RETURN_ERROR(
5901 MAJOR, E_INVALID_VALUE,
5902 ("DSAR: Only 1 mac address is currently supported."));
5903 }
5904 if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
5905 {
5906 i = 0;
5907 if (!macInit)
5908 {
5909 memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
5910 6);
5911 i = 1;
5912 macInit = TRUE;
5913 }
5914 for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
5915 if (memcmp(mac,
5916 params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
5917 6))
5918 RETURN_ERROR(
5919 MAJOR, E_INVALID_VALUE,
5920 ("DSAR: Only 1 mac address is currently supported."));
5921 }
5922 if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
5923 {
5924 i = 0;
5925 if (!macInit)
5926 {
5927 memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
5928 i = 1;
5929 }
5930 for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
5931 if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
5932 6))
5933 RETURN_ERROR(
5934 MAJOR, E_INVALID_VALUE,
5935 ("DSAR: Only 1 mac address is currently supported."));
5936 }
5937 return E_OK;
5938}
5939
5940static int GetBERLen(uint8_t* buf)
5941{
5942 if (*buf & 0x80)
5943 {
5944 if ((*buf & 0x7F) == 1)
5945 return buf[1];
5946 else
5947 return *(uint16_t*)&buf[1]; // assuming max len is 2
5948 }
5949 else
5950 return buf[0];
5951}
5952#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
5953
5954#ifdef TODO_SOC_SUSPEND // XXX
5955#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
5956#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
5957#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
5958static int fm_soc_suspend(void)
5959{
5960 uint32_t *fmclk, tmp32;
5961 fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
5962 tmp32 = GET_UINT32(*fmclk);
5963 WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
5964 tmp32 = GET_UINT32(*fmclk);
5965 iounmap(fmclk);
5966 return 0;
5967}
5968
5969void fm_clk_down(void)
5970{
5971 uint32_t *fmclk, tmp32;
5972 fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
5973 tmp32 = GET_UINT32(*fmclk);
5974 WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
5975 tmp32 = GET_UINT32(*fmclk);
5976 iounmap(fmclk);
5977}
5978#endif
5979
5980#if 0
5981t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
5982{
5983 int i, j;
5984 t_Error err;
5985 uint32_t nia;
5986 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5987 t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
5988 t_DsarArpDescriptor *ArpDescriptor;
5989 t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
5990 t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
5991 t_DsarNdDescriptor* NDDescriptor;
5992
5993 uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
5994 uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
5995 t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
5996 struct arOffsets* of;
5997 uint8_t tmp = 0;
5998 t_FmGetSetParams fmGetSetParams;
5999 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6000 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6001 fmGetSetParams.setParams.sleep = 1;
6002
6003 err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
6004 if (err != E_OK)
6005 return err;
6006
6007 p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
6008 of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
6009 IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
6010
6011 // common
6012 WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
6013 nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
6014 if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
6015 WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
6016 else
6017 WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
6018 WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
6019
6020 // ARP
6021 if (params->p_AutoResArpInfo)
6022 {
6023 t_DsarArpBindingEntry* arp_bindings;
6024 ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
6025 WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
6026 arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
6027 if (params->p_AutoResArpInfo->enableConflictDetection)
6028 WRITE_UINT16(ArpDescriptor->control, 1);
6029 else
6030 WRITE_UINT16(ArpDescriptor->control, 0);
6031 if (params->p_AutoResArpInfo->tableSize)
6032 {
6033 t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
6034 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
6035 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
6036 WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
6037
6038 for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
6039 {
6040 WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
6041 if (arp_entry[i].isVlan)
6042 WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
6043 }
6044 WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
6045 }
6046 WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
6047 sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
6048 }
6049
6050 // ICMPV4
6051 if (params->p_AutoResEchoIpv4Info)
6052 {
6053 t_DsarIcmpV4BindingEntry* icmpv4_bindings;
6054 ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
6055 WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
6056 icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
6057 WRITE_UINT16(ICMPV4Descriptor->control, 0);
6058 if (params->p_AutoResEchoIpv4Info->tableSize)
6059 {
6060 t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
6061 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
6062 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
6063 WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
6064
6065 for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
6066 {
6067 WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
6068 if (arp_entry[i].isVlan)
6069 WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
6070 }
6071 WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
6072 }
6073 WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
6074 sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
6075 }
6076
6077 // ICMPV6
6078 if (params->p_AutoResEchoIpv6Info)
6079 {
6080 t_DsarIcmpV6BindingEntry* icmpv6_bindings;
6081 ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
6082 WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
6083 icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
6084 WRITE_UINT16(ICMPV6Descriptor->control, 0);
6085 if (params->p_AutoResEchoIpv6Info->tableSize)
6086 {
6087 t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
6088 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
6089 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
6090 WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
6091
6092 for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
6093 {
6094 for (j = 0; j < 4; j++)
6095 WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6096 if (ndp_entry[i].isVlan)
6097 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6098 }
6099 WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
6100 }
6101 WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
6102 sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
6103 }
6104
6105 // ND
6106 if (params->p_AutoResNdpInfo)
6107 {
6108 t_DsarIcmpV6BindingEntry* icmpv6_bindings;
6109 NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
6110 WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
6111 icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
6112 if (params->p_AutoResNdpInfo->enableConflictDetection)
6113 WRITE_UINT16(NDDescriptor->control, 1);
6114 else
6115 WRITE_UINT16(NDDescriptor->control, 0);
6116 if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
6117 {
6118 t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
6119 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
6120 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
6121 WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
6122 + params->p_AutoResNdpInfo->tableSizeTmp);
6123
6124 for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
6125 {
6126 for (j = 0; j < 4; j++)
6127 WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6128 if (ndp_entry[i].isVlan)
6129 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6130 }
6131 ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
6132 for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
6133 {
6134 for (j = 0; j < 4; j++)
6135 WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6136 if (ndp_entry[i].isVlan)
6137 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6138 }
6139 WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
6140 }
6141 WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
6142 * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
6143 - fmMuramVirtBaseAddr);
6144 WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
6145 }
6146
6147 // SNMP
6148 if (params->p_AutoResSnmpInfo)
6149 {
6150 t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
6151 t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
6152 t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
6153 t_OidsTblEntry* snmpOid;
6154 uint8_t *charPointer;
6155 int len;
6156 t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
6157 WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
6158 WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
6159 WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
6160 snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
6161 if (snmpSrc->numOfIpv4Addresses)
6162 {
6163 t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
6164 WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
6165 for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
6166 {
6167 WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
6168 if (snmpIpv4AddrSrc[i].isVlan)
6169 WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
6170 }
6171 WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
6172 }
6173 snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
6174 + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
6175 if (snmpSrc->numOfIpv6Addresses)
6176 {
6177 t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
6178 WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
6179 for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
6180 {
6181 for (j = 0; j < 4; j++)
6182 WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
6183 if (snmpIpv6AddrSrc[i].isVlan)
6184 WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
6185 }
6186 WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
6187 }
6188 snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
6189 + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
6190 charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
6191 + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
6192 len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
6193 Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
6194 WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6195 charPointer += len;
6196 len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
6197 Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
6198 WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6199 charPointer += len;
6200 WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
6201 WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
6202 for (i = 0; i < snmpSrc->oidsTblSize; i++)
6203 {
6204 WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
6205 WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
6206 Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
6207 WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6208 charPointer += snmpSrc->p_OidsTbl[i].oidSize;
6209 if (snmpSrc->p_OidsTbl[i].resSize <= 4)
6210 WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
6211 else
6212 {
6213 Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
6214 WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6215 charPointer += snmpSrc->p_OidsTbl[i].resSize;
6216 }
6217 snmpOid++;
6218 }
6219 charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
6220 WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6221 }
6222
6223 // filtering
6224 if (params->p_AutoResFilteringInfo)
6225 {
6226 if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
6227 tmp |= IP_PROT_TBL_PASS_MASK;
6228 if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
6229 tmp |= UDP_PORT_TBL_PASS_MASK;
6230 if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
6231 tmp |= TCP_PORT_TBL_PASS_MASK;
6232 WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
6233 WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
6234
6235 // ip filtering
6236 if (params->p_AutoResFilteringInfo->ipProtTableSize)
6237 {
6238 uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
6239 WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
6240 for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
6241 WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
6242 WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
6243 }
6244
6245 // udp filtering
6246 if (params->p_AutoResFilteringInfo->udpPortsTableSize)
6247 {
6248 t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
6249 WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
6250 for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
6251 {
6252 WRITE_UINT32(udp_tbl[i].Ports,
6253 (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
6254 params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
6255 WRITE_UINT32(udp_tbl[i].PortsMask,
6256 (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
6257 params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
6258 }
6259 WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
6260 }
6261
6262 // tcp filtering
6263 if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
6264 {
6265 t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
6266 WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
6267 for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
6268 {
6269 WRITE_UINT32(tcp_tbl[i].Ports,
6270 (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
6271 params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
6272 WRITE_UINT32(tcp_tbl[i].PortsMask,
6273 (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
6274 params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
6275 }
6276 WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
6277 }
6278 }
6279 // common stats
6280 WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
6281
6282 // get into Deep Sleep sequence:
6283
6284 // Ensures that FMan do not enter the idle state. This is done by programing
6285 // FMDPSLPCR[FM_STOP] to one.
6286 fm_soc_suspend();
6287
6288 ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
6289 return E_OK;
6290
6291}
6292
6293void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
6294t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
6295{
6296 t_FmGetSetParams fmGetSetParams;
6297 t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
6298 t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
6299 t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
6300 t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
6301 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6302 fmGetSetParams.setParams.type = UPDATE_FM_CLD;
6303 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6304
6305 /* Issue graceful stop to HC port */
6306 FM_PORT_Disable(p_FmPortHc);
6307
6308 // config tx port
6309 p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
6310 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN);
6311 // ????
6312 p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
6313 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
6314 // Stage 7:echo
6315 p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
6316 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
6317 if (!PrsIsEnabled(h_FmPcd))
6318 {
6319 p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
6320 PrsEnable(h_FmPcd);
6321 }
6322 else
6323 p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
6324
6325 p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
6326 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
6327
6328 // save rcfg for restoring: accumulate mode is changed by ucode
6329 p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
6330 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
6331 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6332 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6333 fmGetSetParams.setParams.sleep = 1;
6334 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6335
6336// ***** issue external request sync command
6337 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6338 fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
6339 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6340 // get
6341 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6342 fmGetSetParams.getParams.type = GET_FMFP_EXTC;
6343 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6344 if (fmGetSetParams.getParams.fmfp_extc != 0)
6345 {
6346 // clear
6347 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6348 fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
6349 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6350}
6351
6352 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6353 fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
6354 do
6355 {
6356 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6357 } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
6358 if (fmGetSetParams.getParams.fm_npi != 0)
6359 XX_Print("FM: Sync did not finish\n");
6360
6361 // check that all stoped
6362 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6363 fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
6364 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6365 while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
6366 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6367 if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
6368 XX_Print("FM: Sleeping\n");
6369// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
6370
6371 return E_OK;
6372}
6373
6374void FM_PORT_Dsar_DumpRegs()
6375{
6376 uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
6377 DUMP_MEMORY(hh, 0x220);
6378}
6379
6380void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
6381{
6382 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
6383 t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
6384 t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
6385 t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
6386 t_FmGetSetParams fmGetSetParams;
6387 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6388 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6389 fmGetSetParams.setParams.sleep = 0;
6390 if (p_FmPort->deepSleepVars.autoResOffsets)
6391 {
6392 XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
6393 p_FmPort->deepSleepVars.autoResOffsets = 0;
6394 }
6395
6396 if (p_FmPort->deepSleepVars.dsarEnabledParser)
6397 PrsDisable(FmGetPcd(p_FmPort->h_Fm));
6398 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
6399 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
6400 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
6401 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6402 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
6403 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
6404 FM_PORT_Enable(p_FmPortHc);
6405}
6406
6407bool FM_PORT_IsInDsar(t_Handle h_FmPort)
6408{
6409 t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
6410 return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
6411}
6412
6413t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
6414{
6415 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
6416 struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
6417 uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
6418 uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
6419 t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
6420 t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
6421 t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6422 t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
6423 t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
6424 t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
6425 t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6426 t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
6427 t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
6428 t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
6429 t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6430 stats->arpArCnt = arp_stats->arCnt;
6431 stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
6432 stats->ndpArCnt = nd_stats->arCnt;
6433 stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
6434 stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
6435 stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
6436 return E_OK;
6437}
6438#endif
2000 volatile uint32_t *p_BmiPrsStartOffset = NULL;
2001
2002 /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
2003
2004 if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
2005 && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
2006 {
2007 p_CcParams->getCcParams.prOffset =
2008 (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
2009 p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
2010 }
2011 if (p_CcParams->getCcParams.type & HW_PORT_ID)
2012 {
2013 p_CcParams->getCcParams.hardwarePortId =
2014 (uint8_t)p_FmPort->hardwarePortId;
2015 p_CcParams->getCcParams.type &= ~HW_PORT_ID;
2016 }
2017 if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
2018 && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
2019 {
2020 p_CcParams->getCcParams.dataOffset =
2021 (uint16_t)p_FmPort->bufferOffsets.dataOffset;
2022 p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
2023 }
2024 if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
2025 {
2026 p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
2027 p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
2028 }
2029 if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
2030 {
2031 p_CcParams->getCcParams.numOfExtraTasks =
2032 (uint8_t)p_FmPort->tasks.extra;
2033 p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
2034 }
2035 if (p_CcParams->getCcParams.type & FM_REV)
2036 {
2037 p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
2038 p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
2039 p_CcParams->getCcParams.type &= ~FM_REV;
2040 }
2041 if (p_CcParams->getCcParams.type & DISCARD_MASK)
2042 {
2043 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2044 p_CcParams->getCcParams.discardMask =
2045 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
2046 else
2047 p_CcParams->getCcParams.discardMask =
2048 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
2049 p_CcParams->getCcParams.type &= ~DISCARD_MASK;
2050 }
2051 if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
2052 {
2053 p_CcParams->getCcParams.internalBufferOffset =
2054 p_FmPort->internalBufferOffset;
2055 p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
2056 }
2057 if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
2058 {
2059 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2060 p_CcParams->getCcParams.nia =
2061 GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
2062 else
2063 p_CcParams->getCcParams.nia =
2064 GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
2065 p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
2066 }
2067 if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
2068 {
2069 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2070 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2071 p_CcParams->getCcParams.nia =
2072 GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
2073 p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
2074 }
2075
2076 if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
2077 && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
2078 {
2079 p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
2080 p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
2081 }
2082
2083 if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
2084 && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
2085 {
2086 p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
2087 p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
2088 }
2089 else
2090 if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
2091 {
2092 if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
2093 RETURN_ERROR(MAJOR, E_INVALID_STATE,
2094 ("PNEN was defined previously different"));
2095 }
2096
2097 if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
2098 && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
2099 {
2100 p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
2101 p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
2102 }
2103 else
2104 if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
2105 {
2106 if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
2107 RETURN_ERROR(MAJOR, E_INVALID_STATE,
2108 ("PNDN was defined previously different"));
2109 }
2110
2111 if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
2112 && (p_CcParams->setCcParams.overwrite
2113 || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
2114 {
2115 p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
2116 p_FmPort->requiredAction |= UPDATE_NIA_FENE;
2117 }
2118 else
2119 if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
2120 {
2121 if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
2122 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2123 ("xFENE was defined previously different"));
2124 }
2125
2126 if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
2127 && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
2128 {
2129 p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
2130 p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
2131 }
2132 else
2133 if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
2134 {
2135 if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
2136 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2137 ("xFPNE was defined previously different"));
2138 }
2139
2140 if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
2141 && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
2142 {
2143 p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
2144 p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
2145 }
2146 else
2147 if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
2148 {
2149 if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
2150 RETURN_ERROR( MAJOR, E_INVALID_STATE,
2151 ("xCMNE was defined previously different"));
2152 }
2153
2154 if ((p_CcParams->setCcParams.type & UPDATE_PSO)
2155 && !(p_FmPort->requiredAction & UPDATE_PSO))
2156 {
2157 /* get PCD registers pointers */
2158 switch (p_FmPort->portType)
2159 {
2160 case (e_FM_PORT_TYPE_RX_10G):
2161 case (e_FM_PORT_TYPE_RX):
2162 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
2163 break;
2164 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2165 p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
2166 break;
2167 default:
2168 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2169 }
2170
2171 /* set start parsing offset */
2172 tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
2173 + p_CcParams->setCcParams.psoSize;
2174 if (tmpInt > 0)
2175 WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
2176
2177 p_FmPort->requiredAction |= UPDATE_PSO;
2178 p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
2179 }
2180 else
2181 if (p_CcParams->setCcParams.type & UPDATE_PSO)
2182 {
2183 if (p_FmPort->savedPrsStartOffset
2184 != p_CcParams->setCcParams.psoSize)
2185 RETURN_ERROR(
2186 MAJOR,
2187 E_INVALID_STATE,
2188 ("parser start offset was defoned previousley different"));
2189 }
2190
2191 if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
2192 && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
2193 {
2194 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2195 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2196 p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
2197 p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
2198 p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
2199 << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
2200 p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
2201 }
2202
2203 return E_OK;
2204}
2205/*********************** End of inter-module routines ************************/
2206
2207/****************************************/
2208/* API Init unit functions */
2209/****************************************/
2210
2211t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
2212{
2213 t_FmPort *p_FmPort;
2214 uintptr_t baseAddr = p_FmPortParams->baseAddr;
2215 uint32_t tmpReg;
2216
2217 /* Allocate FM structure */
2218 p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
2219 if (!p_FmPort)
2220 {
2221 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
2222 return NULL;
2223 }
2224 memset(p_FmPort, 0, sizeof(t_FmPort));
2225
2226 /* Allocate the FM driver's parameters structure */
2227 p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
2228 sizeof(t_FmPortDriverParam));
2229 if (!p_FmPort->p_FmPortDriverParam)
2230 {
2231 XX_Free(p_FmPort);
2232 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
2233 return NULL;
2234 }
2235 memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
2236
2237 /* Initialize FM port parameters which will be kept by the driver */
2238 p_FmPort->portType = p_FmPortParams->portType;
2239 p_FmPort->portId = p_FmPortParams->portId;
2240 p_FmPort->pcdEngines = FM_PCD_NONE;
2241 p_FmPort->f_Exception = p_FmPortParams->f_Exception;
2242 p_FmPort->h_App = p_FmPortParams->h_App;
2243 p_FmPort->h_Fm = p_FmPortParams->h_Fm;
2244
2245 /* get FM revision */
2246 FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
2247
2248 /* calculate global portId number */
2249 p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
2250 p_FmPortParams->portId,
2251 p_FmPort->fmRevInfo.majorRev,
2252 p_FmPort->fmRevInfo.minorRev);
2253
2254 if (p_FmPort->fmRevInfo.majorRev >= 6)
2255 {
2256 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2257 && (p_FmPortParams->portId != FM_OH_PORT_ID))
2258 DBG(WARNING,
2259 ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
2260 FM_OH_PORT_ID));
2261
2262 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2263 && (p_FmPortParams->portId == FM_OH_PORT_ID))
2264 DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
2265 }
2266
2267 /* Set up FM port parameters for initialization phase only */
2268
2269 /* First, fill in flibs struct */
2270 fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
2271 (enum fman_port_type)p_FmPort->portType);
2272 /* Overwrite some integration specific parameters */
2273 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
2274 DEFAULT_PORT_rxFifoPriElevationLevel;
2275 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
2276 DEFAULT_PORT_rxFifoThreshold;
2277
2278#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
2279 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
2280#else
2281 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
2282#endif
2283 if ((p_FmPort->fmRevInfo.majorRev == 6)
2284 && (p_FmPort->fmRevInfo.minorRev == 0))
2285 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
2286 else
2287 p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
2288
2289 /* Excessive Threshold register - exists for pre-FMv3 chips only */
2290 if (p_FmPort->fmRevInfo.majorRev < 6)
2291 {
2292#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
2293 p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
2294 TRUE;
2295#endif
2296 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
2297 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
2298 }
2299 else
2300 {
2301 p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
2302 FALSE;
2303 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
2304 p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
2305 }
2306 if (p_FmPort->fmRevInfo.majorRev == 4)
2307 p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
2308 else
2309 p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
2310
2311 /* Continue with other parameters */
2312 p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
2313 /* set memory map pointers */
2314 p_FmPort->p_FmPortQmiRegs =
2315 (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
2316 p_FmPort->p_FmPortBmiRegs =
2317 (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
2318 p_FmPort->p_FmPortPrsRegs =
2319 (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
2320
2321 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
2322 DEFAULT_PORT_bufferPrefixContent_privDataSize;
2323 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
2324 DEFAULT_PORT_bufferPrefixContent_passPrsResult;
2325 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
2326 DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
2327 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
2328 DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
2329 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
2330 DEFAULT_PORT_bufferPrefixContent_dataAlign;
2331 /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
2332 p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
2333 p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
2334 p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
2335 p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
2336 */
2337 p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
2338 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
2339 DEFAULT_PORT_cheksumLastBytesIgnore;
2340
2341 p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
2342 /* resource distribution. */
2343 p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
2344 * BMI_FIFO_UNITS;
2345 p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
2346 * BMI_FIFO_UNITS;
2347 p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
2348 p_FmPort->openDmas.extra =
2349 DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
2350 p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
2351 p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
2352
2353
2354#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
2355 if ((p_FmPort->fmRevInfo.majorRev == 6)
2356 && (p_FmPort->fmRevInfo.minorRev == 0)
2357 && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2358 || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
2359 {
2360 p_FmPort->openDmas.num = 16;
2361 p_FmPort->openDmas.extra = 0;
2362 }
2363#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
2364
2365 /* Port type specific initialization: */
2366 switch (p_FmPort->portType)
2367 {
2368 case (e_FM_PORT_TYPE_RX):
2369 case (e_FM_PORT_TYPE_RX_10G):
2370 /* Initialize FM port parameters for initialization phase only */
2371 p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
2372 DEFAULT_PORT_cutBytesFromEnd;
2373 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
2374 p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
2375 DEFAULT_PORT_frmDiscardOverride;
2376
2377 tmpReg =
2378 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
2379 p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
2380 (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
2381 >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
2382 * BMI_FIFO_UNITS;
2383 p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
2384 & BMI_RX_FIFO_THRESHOLD_MASK)
2385 >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
2386
2387 p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
2388 DEFAULT_PORT_BufMargins_endMargins;
2389 p_FmPort->p_FmPortDriverParam->errorsToDiscard =
2390 DEFAULT_PORT_errorsToDiscard;
2391 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
2392 DEFAULT_PORT_forwardIntContextReuse;
2393#if (DPAA_VERSION >= 11)
2394 p_FmPort->p_FmPortDriverParam->noScatherGather =
2395 DEFAULT_PORT_noScatherGather;
2396#endif /* (DPAA_VERSION >= 11) */
2397 break;
2398
2399 case (e_FM_PORT_TYPE_TX):
2400 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
2401#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
2402 tmpReg = 0x00001013;
2403 WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
2404 tmpReg);
2405#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
2406 case (e_FM_PORT_TYPE_TX_10G):
2407 tmpReg =
2408 GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
2409 p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
2410 & BMI_TX_FIFO_MIN_FILL_MASK)
2411 >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
2412 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2413 (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
2414 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
2415 p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
2416 & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
2417 * BMI_FIFO_UNITS;
2418
2419 p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
2420 p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
2421 DEFAULT_PORT_deqPrefetchOption;
2422 p_FmPort->p_FmPortDriverParam->deqHighPriority =
2423 (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
2424 DEFAULT_PORT_deqHighPriority_10G);
2425 p_FmPort->p_FmPortDriverParam->deqByteCnt =
2426 (uint16_t)(
2427 (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
2428 DEFAULT_PORT_deqByteCnt_10G);
2429 break;
2430 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2431 p_FmPort->p_FmPortDriverParam->errorsToDiscard =
2432 DEFAULT_PORT_errorsToDiscard;
2433#if (DPAA_VERSION >= 11)
2434 p_FmPort->p_FmPortDriverParam->noScatherGather =
2435 DEFAULT_PORT_noScatherGather;
2436#endif /* (DPAA_VERSION >= 11) */
2437 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
2438 p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
2439 DEFAULT_PORT_deqPrefetchOption_HC;
2440 p_FmPort->p_FmPortDriverParam->deqHighPriority =
2441 DEFAULT_PORT_deqHighPriority_1G;
2442 p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
2443 p_FmPort->p_FmPortDriverParam->deqByteCnt =
2444 DEFAULT_PORT_deqByteCnt_1G;
2445
2446 tmpReg =
2447 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
2448 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2449 (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
2450 >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
2451 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
2452 && (p_FmPortParams->portId != FM_OH_PORT_ID))
2453 {
2454 /* Overwrite HC defaults */
2455 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2456 DEFAULT_PORT_fifoDeqPipelineDepth_OH;
2457 }
2458
2459#ifndef FM_FRAME_END_PARAMS_FOR_OP
2460 if (p_FmPort->fmRevInfo.majorRev < 6)
2461 p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
2462#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
2463
2464#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
2465 if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
2466 (p_FmPort->fmRevInfo.majorRev >= 6)))
2467 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
2468#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
2469 break;
2470
2471 default:
2472 XX_Free(p_FmPort->p_FmPortDriverParam);
2473 XX_Free(p_FmPort);
2474 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2475 return NULL;
2476 }
2477#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
2478 if (p_FmPort->fmRevInfo.majorRev == 4)
2479 p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
2480#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
2481
2482 p_FmPort->imEn = p_FmPortParams->independentModeEnable;
2483
2484 if (p_FmPort->imEn)
2485 {
2486 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
2487 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
2488 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
2489 DEFAULT_PORT_fifoDeqPipelineDepth_IM;
2490 FmPortConfigIM(p_FmPort, p_FmPortParams);
2491 }
2492 else
2493 {
2494 switch (p_FmPort->portType)
2495 {
2496 case (e_FM_PORT_TYPE_RX):
2497 case (e_FM_PORT_TYPE_RX_10G):
2498 /* Initialize FM port parameters for initialization phase only */
2499 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
2500 &p_FmPortParams->specificParams.rxParams.extBufPools,
2501 sizeof(t_FmExtPools));
2502 p_FmPort->p_FmPortDriverParam->errFqid =
2503 p_FmPortParams->specificParams.rxParams.errFqid;
2504 p_FmPort->p_FmPortDriverParam->dfltFqid =
2505 p_FmPortParams->specificParams.rxParams.dfltFqid;
2506 p_FmPort->p_FmPortDriverParam->liodnOffset =
2507 p_FmPortParams->specificParams.rxParams.liodnOffset;
2508 break;
2509 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
2510 case (e_FM_PORT_TYPE_TX):
2511 case (e_FM_PORT_TYPE_TX_10G):
2512 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
2513 p_FmPort->p_FmPortDriverParam->errFqid =
2514 p_FmPortParams->specificParams.nonRxParams.errFqid;
2515 p_FmPort->p_FmPortDriverParam->deqSubPortal =
2516 (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
2517 & QMI_DEQ_CFG_SUBPORTAL_MASK);
2518 p_FmPort->p_FmPortDriverParam->dfltFqid =
2519 p_FmPortParams->specificParams.nonRxParams.dfltFqid;
2520 break;
2521 default:
2522 XX_Free(p_FmPort->p_FmPortDriverParam);
2523 XX_Free(p_FmPort);
2524 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
2525 return NULL;
2526 }
2527 }
2528
2529 memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
2530 if (Sprint(
2531 p_FmPort->name,
2532 "FM-%d-port-%s-%d",
2533 FmGetId(p_FmPort->h_Fm),
2534 ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
2535 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
2536 (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
2537 (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
2538 (p_FmPort->portType
2539 == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
2540 "10g-TX")))),
2541 p_FmPort->portId) == 0)
2542 {
2543 XX_Free(p_FmPort->p_FmPortDriverParam);
2544 XX_Free(p_FmPort);
2545 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2546 return NULL;
2547 }
2548
2549 p_FmPort->h_Spinlock = XX_InitSpinlock();
2550 if (!p_FmPort->h_Spinlock)
2551 {
2552 XX_Free(p_FmPort->p_FmPortDriverParam);
2553 XX_Free(p_FmPort);
2554 REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
2555 return NULL;
2556 }
2557
2558 return p_FmPort;
2559}
2560
2561t_FmPort *rx_port = 0;
2562t_FmPort *tx_port = 0;
2563
2564/**************************************************************************//**
2565 @Function FM_PORT_Init
2566
2567 @Description Initializes the FM module
2568
2569 @Param[in] h_FmPort - FM module descriptor
2570
2571 @Return E_OK on success; Error code otherwise.
2572 *//***************************************************************************/
2573t_Error FM_PORT_Init(t_Handle h_FmPort)
2574{
2575 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2576 t_FmPortDriverParam *p_DriverParams;
2577 t_Error errCode;
2578 t_FmInterModulePortInitParams fmParams;
2579 t_FmRevisionInfo revInfo;
2580
2581 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
2582 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2583
2584 errCode = FmSpBuildBufferStructure(
2585 &p_FmPort->p_FmPortDriverParam->intContext,
2586 &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
2587 &p_FmPort->p_FmPortDriverParam->bufMargins,
2588 &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
2589 if (errCode != E_OK)
2590 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2591#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
2592 if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
2593 (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2594 {
2595 p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
2596 if (!p_FmPort->fifoBufs.num)
2597 p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
2598 p_FmPort->fifoBufs.num += 4*KILOBYTE;
2599 }
2600#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
2601
2602 CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
2603
2604 p_DriverParams = p_FmPort->p_FmPortDriverParam;
2605
2606 /* Set up flibs port structure */
2607 memset(&p_FmPort->port, 0, sizeof(struct fman_port));
2608 p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
2609 FM_GetRevision(p_FmPort->h_Fm, &revInfo);
2610 p_FmPort->port.fm_rev_maj = revInfo.majorRev;
2611 p_FmPort->port.fm_rev_min = revInfo.minorRev;
2612 p_FmPort->port.bmi_regs =
2613 (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
2614 p_FmPort->port.qmi_regs =
2615 (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
2616 p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
2617 p_FmPort->port.im_en = p_FmPort->imEn;
2618 p_FmPort->p_FmPortPrsRegs =
2619 (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
2620
2621 if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2622 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
2623 {
2624 /* Call the external Buffer routine which also checks fifo
2625 size and updates it if necessary */
2626 /* define external buffer pools and pool depletion*/
2627 errCode = SetExtBufferPools(p_FmPort);
2628 if (errCode)
2629 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2630 /* check if the largest external buffer pool is large enough */
2631 if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
2632 + p_DriverParams->bufMargins.endMargins
2633 > p_FmPort->rxPoolsParams.largestBufSize)
2634 RETURN_ERROR(
2635 MAJOR,
2636 E_INVALID_VALUE,
2637 ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", p_DriverParams->bufMargins.startMargins, p_DriverParams->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize));
2638 }
2639 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2640 {
2641 {
2642#ifdef FM_NO_OP_OBSERVED_POOLS
2643 t_FmRevisionInfo revInfo;
2644
2645 FM_GetRevision(p_FmPort->h_Fm, &revInfo);
2646 if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
2647#endif /* FM_NO_OP_OBSERVED_POOLS */
2648 {
2649 /* define external buffer pools */
2650 errCode = SetExtBufferPools(p_FmPort);
2651 if (errCode)
2652 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2653 }
2654 }
2655 }
2656
2657 /************************************************************/
2658 /* Call FM module routine for communicating parameters */
2659 /************************************************************/
2660 memset(&fmParams, 0, sizeof(fmParams));
2661 fmParams.hardwarePortId = p_FmPort->hardwarePortId;
2662 fmParams.portType = (e_FmPortType)p_FmPort->portType;
2663 fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
2664 fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
2665 fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
2666 fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
2667
2668 if (p_FmPort->fifoBufs.num)
2669 {
2670 errCode = VerifySizeOfFifo(p_FmPort);
2671 if (errCode != E_OK)
2672 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2673 }
2674 fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
2675 fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
2676 fmParams.independentMode = p_FmPort->imEn;
2677 fmParams.liodnOffset = p_DriverParams->liodnOffset;
2678 fmParams.liodnBase = p_DriverParams->liodnBase;
2679 fmParams.deqPipelineDepth =
2680 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
2681 fmParams.maxFrameLength = p_FmPort->maxFrameLength;
2682#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
2683 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
2684 (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
2685 {
2686 if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
2687 (p_FmPort->fmRevInfo.majorRev >= 6)))
2688 /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
2689 * for deq threshold calculation.
2690 */
2691 fmParams.deqPipelineDepth = 2;
2692 }
2693#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
2694
2695 errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
2696 if (errCode)
2697 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2698
2699 /* get params for use in init */
2700 p_FmPort->fmMuramPhysBaseAddr =
2701 (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
2702 | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
2703 p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
2704
2705 errCode = InitLowLevelDriver(p_FmPort);
2706 if (errCode != E_OK)
2707 RETURN_ERROR(MAJOR, errCode, NO_MSG);
2708
2709 FmPortDriverParamFree(p_FmPort);
2710
2711#if (DPAA_VERSION >= 11)
2712 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2713 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
2714 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
2715 {
2716 t_FmPcdCtrlParamsPage *p_ParamsPage;
2717
2718 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
2719 (void**)&p_ParamsPage);
2720 ASSERT_COND(p_ParamsPage);
2721
2722 WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
2723#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
2724 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2725 {
2726 WRITE_UINT32(
2727 p_ParamsPage->misc,
2728 (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
2729 WRITE_UINT32(
2730 p_ParamsPage->discardMask,
2731 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
2732 }
2733#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
2734#ifdef FM_ERROR_VSP_NO_MATCH_SW006
2735 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
2736 WRITE_UINT32(
2737 p_ParamsPage->errorsDiscardMask,
2738 (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
2739 else
2740 WRITE_UINT32(
2741 p_ParamsPage->errorsDiscardMask,
2742 (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
2743#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
2744 }
2745#endif /* (DPAA_VERSION >= 11) */
2746
2747 if (p_FmPort->deepSleepVars.autoResMaxSizes)
2748 FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
2749 return E_OK;
2750}
2751
2752/**************************************************************************//**
2753 @Function FM_PORT_Free
2754
2755 @Description Frees all resources that were assigned to FM module.
2756
2757 Calling this routine invalidates the descriptor.
2758
2759 @Param[in] h_FmPort - FM module descriptor
2760
2761 @Return E_OK on success; Error code otherwise.
2762 *//***************************************************************************/
2763t_Error FM_PORT_Free(t_Handle h_FmPort)
2764{
2765 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2766 t_FmInterModulePortFreeParams fmParams;
2767
2768 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2769
2770 if (p_FmPort->pcdEngines)
2771 RETURN_ERROR(
2772 MAJOR,
2773 E_INVALID_STATE,
2774 ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
2775
2776 if (p_FmPort->enabled)
2777 {
2778 if (FM_PORT_Disable(p_FmPort) != E_OK)
2779 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
2780 }
2781
2782 if (p_FmPort->imEn)
2783 FmPortImFree(p_FmPort);
2784
2785 FmPortDriverParamFree(p_FmPort);
2786
2787 memset(&fmParams, 0, sizeof(fmParams));
2788 fmParams.hardwarePortId = p_FmPort->hardwarePortId;
2789 fmParams.portType = (e_FmPortType)p_FmPort->portType;
2790 fmParams.deqPipelineDepth =
2791 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
2792
2793 FmFreePortParams(p_FmPort->h_Fm, &fmParams);
2794
2795#if (DPAA_VERSION >= 11)
2796 if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
2797 != E_OK)
2798 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
2799
2800 if (p_FmPort->p_ParamsPage)
2801 FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
2802#endif /* (DPAA_VERSION >= 11) */
2803
2804 if (p_FmPort->h_Spinlock)
2805 XX_FreeSpinlock(p_FmPort->h_Spinlock);
2806
2807 XX_Free(p_FmPort);
2808
2809 return E_OK;
2810}
2811
2812/*************************************************/
2813/* API Advanced Init unit functions */
2814/*************************************************/
2815
2816t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
2817{
2818 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2819
2820 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2821 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2822
2823 p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
2824 memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
2825
2826 return E_OK;
2827}
2828
2829t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
2830{
2831 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2832
2833 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2834 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2835
2836 memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
2837 p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
2838 return E_OK;
2839}
2840
2841t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
2842{
2843 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2844
2845 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2846 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2847
2848 p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
2849 memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
2850
2851 return E_OK;
2852}
2853
2854t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
2855{
2856 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2857
2858 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2859 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2860 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2861 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2862 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
2863
2864 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
2865
2866 return E_OK;
2867}
2868
2869t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
2870{
2871 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2872
2873 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2874 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2875 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2876 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2877 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2878 ("not available for Rx ports"));
2879
2880 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
2881 (enum fman_port_deq_type)deqType;
2882
2883 return E_OK;
2884}
2885
2886t_Error FM_PORT_ConfigDeqPrefetchOption(
2887 t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
2888{
2889 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2890
2891 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2892 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2893 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2894 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2895 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2896 ("not available for Rx ports"));
2897 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
2898 (enum fman_port_deq_prefetch)deqPrefetchOption;
2899
2900 return E_OK;
2901}
2902
2903t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
2904 t_FmBackupBmPools *p_BackupBmPools)
2905{
2906 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2907
2908 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2909 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2910 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2911 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2912 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2913 ("available for Rx ports only"));
2914
2915 p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
2916 (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
2917 if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
2918 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
2919 memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
2920 sizeof(t_FmBackupBmPools));
2921
2922 return E_OK;
2923}
2924
2925t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
2926{
2927 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2928
2929 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2930 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2931 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
2932 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
2933 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2934 ("not available for Rx ports"));
2935
2936 p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
2937
2938 return E_OK;
2939}
2940
2941t_Error FM_PORT_ConfigBufferPrefixContent(
2942 t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
2943{
2944 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2945
2946 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2947 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2948
2949 memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
2950 p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
2951 /* if dataAlign was not initialized by user, we return to driver's default */
2952 if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
2953 p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
2954 DEFAULT_PORT_bufferPrefixContent_dataAlign;
2955
2956 return E_OK;
2957}
2958
2959t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
2960 uint8_t checksumLastBytesIgnore)
2961{
2962 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2963
2964 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2965 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2966
2967 p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
2968 checksumLastBytesIgnore;
2969
2970 return E_OK;
2971}
2972
2973t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
2974 uint8_t cutBytesFromEnd)
2975{
2976 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2977
2978 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2979 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2980 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2981 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2982 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
2983 ("available for Rx ports only"));
2984
2985 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
2986
2987 return E_OK;
2988}
2989
2990t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
2991 t_FmBufPoolDepletion *p_BufPoolDepletion)
2992{
2993 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
2994
2995 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
2996 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
2997 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
2998 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
2999 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3000 ("available for Rx ports only"));
3001
3002 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
3003 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
3004 sizeof(t_FmBufPoolDepletion));
3005
3006 return E_OK;
3007}
3008
3009t_Error FM_PORT_ConfigObservedPoolDepletion(
3010 t_Handle h_FmPort,
3011 t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
3012{
3013 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3014
3015 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3016 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3017 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3018 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3019 ("available for OP ports only"));
3020
3021 p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
3022 memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
3023 &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
3024 sizeof(t_FmBufPoolDepletion));
3025 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
3026 &p_FmPortObservedBufPoolDepletion->poolsParams,
3027 sizeof(t_FmExtPools));
3028
3029 return E_OK;
3030}
3031
3032t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
3033{
3034 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3035
3036 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3037 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3038
3039 if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3040 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3041 ("available for OP ports only"));
3042
3043 memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
3044 sizeof(t_FmExtPools));
3045
3046 return E_OK;
3047}
3048
3049t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
3050{
3051 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3052
3053 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3054 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3055 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3056 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3057 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3058 ("available for Tx ports only"));
3059
3060 p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
3061
3062 return E_OK;
3063}
3064
3065t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
3066{
3067 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3068
3069 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3070 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3071 p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
3072
3073 return E_OK;
3074}
3075
3076t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
3077{
3078 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3079
3080 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3081 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3082
3083 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3084 || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3085 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3086 ("Not available for Tx ports"));
3087
3088 p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
3089
3090 return E_OK;
3091}
3092
3093t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
3094{
3095 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3096
3097 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3098 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3099 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3100 || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3101 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3102 ("Not available for Tx ports"));
3103
3104 p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
3105
3106 return E_OK;
3107}
3108
3109t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
3110 fmPortFrameErrSelect_t errs)
3111{
3112 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3113
3114 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3115 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3116 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3117 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
3118 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
3119 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3120 ("available for Rx and offline parsing ports only"));
3121
3122 p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
3123
3124 return E_OK;
3125}
3126
3127t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
3128{
3129 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3130
3131 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3132 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3133
3134 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
3135 (enum fman_port_dma_swap)swapData;
3136
3137 return E_OK;
3138}
3139
3140t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
3141 e_FmDmaCacheOption intContextCacheAttr)
3142{
3143 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3144
3145 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3146 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3147
3148 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
3149 (bool)(intContextCacheAttr == e_FM_DMA_STASH);
3150
3151 return E_OK;
3152}
3153
3154t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
3155 e_FmDmaCacheOption headerCacheAttr)
3156{
3157 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3158
3159 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3160 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3161
3162 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
3163 (bool)(headerCacheAttr == e_FM_DMA_STASH);
3164
3165 return E_OK;
3166}
3167
3168t_Error FM_PORT_ConfigDmaScatterGatherAttr(
3169 t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
3170{
3171 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3172
3173 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3174 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3175
3176 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
3177 (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
3178
3179 return E_OK;
3180}
3181
3182t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
3183{
3184 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3185
3186 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3187 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3188
3189 if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
3190 || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
3191 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3192 ("Not available for Tx ports"));
3193
3194 p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
3195
3196 return E_OK;
3197}
3198
3199#if (DPAA_VERSION >= 11)
3200t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
3201{
3202 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3203
3204 UNUSED(noScatherGather);
3205 UNUSED(p_FmPort);
3206
3207 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3208 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3209
3210 p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
3211
3212 return E_OK;
3213}
3214#endif /* (DPAA_VERSION >= 11) */
3215
3216t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
3217 bool forwardReuse)
3218{
3219 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3220
3221 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3222 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3223
3224 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3225 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3226 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3227 ("available for Rx ports only"));
3228
3229 p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
3230
3231 return E_OK;
3232}
3233
3234t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
3235{
3236 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3237
3238 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3239 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3240
3241 p_FmPort->maxFrameLength = length;
3242
3243 return E_OK;
3244}
3245
3246#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
3247t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
3248{
3249 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3250
3251 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3252 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3253
3254 p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
3255
3256 return E_OK;
3257}
3258#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
3259
3260/****************************************************/
3261/* Hidden-DEBUG Only API */
3262/****************************************************/
3263
3264t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
3265 uint32_t minFillLevel)
3266{
3267 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3268
3269 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3270 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3271 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3272 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3273 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3274 ("available for Tx ports only"));
3275
3276 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
3277
3278 return E_OK;
3279}
3280
3281t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
3282 uint8_t deqPipelineDepth)
3283{
3284 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3285
3286 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3287 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3288
3289 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
3290 || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
3291 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3292 ("Not available for Rx ports"));
3293
3294 if (p_FmPort->imEn)
3295 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3296 ("Not available for IM ports!"));
3297
3298 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
3299 deqPipelineDepth;
3300
3301 return E_OK;
3302}
3303
3304t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
3305 uint32_t fifoLowComfLevel)
3306{
3307 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3308
3309 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3310 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3311 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
3312 && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
3313 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3314 ("available for Tx ports only"));
3315
3316 p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
3317 fifoLowComfLevel;
3318
3319 return E_OK;
3320}
3321
3322t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
3323{
3324 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3325
3326 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3327 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3328 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3329 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3330 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3331 ("available for Rx ports only"));
3332
3333 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
3334
3335 return E_OK;
3336}
3337
3338t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
3339 uint32_t priElevationLevel)
3340{
3341 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3342
3343 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3344 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3345 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
3346 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
3347 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3348 ("available for Rx ports only"));
3349
3350 p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
3351
3352 return E_OK;
3353}
3354/****************************************************/
3355/* API Run-time Control unit functions */
3356/****************************************************/
3357
3358t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
3359 t_FmPortRsrc *p_NumOfOpenDmas)
3360{
3361 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3362 t_Error err;
3363
3364 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3365 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3366
3367 if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
3368 RETURN_ERROR( MAJOR, E_INVALID_VALUE,
3369 ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
3370 if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
3371 RETURN_ERROR(
3372 MAJOR,
3373 E_INVALID_VALUE,
3374 ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
3375 err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3376 (uint8_t*)&p_NumOfOpenDmas->num,
3377 (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
3378 if (err)
3379 RETURN_ERROR(MAJOR, err, NO_MSG);
3380
3381 memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
3382
3383 return E_OK;
3384}
3385
3386t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
3387{
3388 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3389 t_Error err;
3390
3391 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3392 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3393
3394 /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
3395 ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
3396
3397 if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
3398 RETURN_ERROR(
3399 MAJOR, E_INVALID_VALUE,
3400 ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
3401 if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
3402 RETURN_ERROR(
3403 MAJOR,
3404 E_INVALID_VALUE,
3405 ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
3406
3407 err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3408 (uint8_t*)&p_NumOfTasks->num,
3409 (uint8_t*)&p_NumOfTasks->extra, FALSE);
3410 if (err)
3411 RETURN_ERROR(MAJOR, err, NO_MSG);
3412
3413 /* update driver's struct */
3414 memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
3415 return E_OK;
3416}
3417
3418t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
3419{
3420 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3421 t_Error err;
3422
3423 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3424 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3425
3426 if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
3427 RETURN_ERROR(
3428 MAJOR,
3429 E_INVALID_VALUE,
3430 ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
3431 if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
3432 RETURN_ERROR(
3433 MAJOR, E_INVALID_VALUE,
3434 ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
3435 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
3436 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
3437 {
3438 /* extra FIFO size (allowed only to Rx ports) */
3439 if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
3440 RETURN_ERROR(
3441 MAJOR,
3442 E_INVALID_VALUE,
3443 ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
3444 }
3445 else
3446 if (p_SizeOfFifo->extra)
3447 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
3448 (" No SizeOfFifo-extra for non Rx ports"));
3449
3450 memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
3451
3452 /* we do not change user's parameter */
3453 err = VerifySizeOfFifo(p_FmPort);
3454 if (err)
3455 RETURN_ERROR(MAJOR, err, NO_MSG);
3456
3457 err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
3458 &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
3459 if (err)
3460 RETURN_ERROR(MAJOR, err, NO_MSG);
3461
3462 return E_OK;
3463}
3464
3465uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
3466{
3467 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3468
3469 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
3470 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3471 0);
3472
3473 return p_FmPort->bufferOffsets.dataOffset;
3474}
3475
3476uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
3477{
3478 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3479
3480 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3481 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3482 NULL);
3483
3484 if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
3485 return NULL;
3486
3487 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
3488}
3489
3490t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
3491{
3492 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3493
3494 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3495 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3496 NULL);
3497
3498 if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
3499 return NULL;
3500
3501 return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
3502}
3503
3504uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
3505{
3506 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3507
3508 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3509 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3510 NULL);
3511
3512 if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
3513 return NULL;
3514
3515 return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
3516}
3517
3518uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
3519{
3520 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3521
3522 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
3523 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
3524 NULL);
3525
3526 if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
3527 return NULL;
3528
3529 return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
3530}
3531
3532t_Error FM_PORT_Disable(t_Handle h_FmPort)
3533{
3534 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3535 int err;
3536
3537 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3538 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3539
3540 if (p_FmPort->imEn)
3541 FmPortImDisable(p_FmPort);
3542
3543 err = fman_port_disable(&p_FmPort->port);
3544 if (err == -EBUSY)
3545 {
3546 DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
3547 p_FmPort->name));
3548 }
3549 else
3550 if (err != 0)
3551 {
3552 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
3553 }
3554
3555 p_FmPort->enabled = FALSE;
3556
3557 return E_OK;
3558}
3559
3560t_Error FM_PORT_Enable(t_Handle h_FmPort)
3561{
3562 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3563 int err;
3564
3565 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3566 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3567
3568 /* Used by FM_PORT_Free routine as indication
3569 if to disable port. Thus set it to TRUE prior
3570 to enabling itself. This way if part of enable
3571 process fails there will be still things
3572 to disable during Free. For example, if BMI
3573 enable succeeded but QMI failed, still BMI
3574 needs to be disabled by Free. */
3575 p_FmPort->enabled = TRUE;
3576
3577 if (p_FmPort->imEn)
3578 FmPortImEnable(p_FmPort);
3579
3580 err = fman_port_enable(&p_FmPort->port);
3581 if (err != 0)
3582 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
3583
3584 return E_OK;
3585}
3586
3587t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
3588{
3589 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3590 uint8_t factor, countUnitBit;
3591 uint16_t baseGran;
3592 struct fman_port_rate_limiter params;
3593 int err;
3594
3595 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3596 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3597
3598 switch (p_FmPort->portType)
3599 {
3600 case (e_FM_PORT_TYPE_TX_10G):
3601 case (e_FM_PORT_TYPE_TX):
3602 baseGran = BMI_RATE_LIMIT_GRAN_TX;
3603 break;
3604 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3605 baseGran = BMI_RATE_LIMIT_GRAN_OP;
3606 break;
3607 default:
3608 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3609 ("available for Tx and Offline parsing ports only"));
3610 }
3611
3612 countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
3613 /* normally, we use 1 usec as the reference count */
3614 factor = 1;
3615 /* if ratelimit is too small for a 1usec factor, multiply the factor */
3616 while (p_RateLimit->rateLimit < baseGran / factor)
3617 {
3618 if (countUnitBit == 31)
3619 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
3620
3621 countUnitBit++;
3622 factor <<= 1;
3623 }
3624 /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
3625 if (p_RateLimit->rateLimit
3626 > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
3627 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
3628
3629 if (!p_RateLimit->maxBurstSize
3630 || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
3631 RETURN_ERROR(
3632 MAJOR,
3633 E_INVALID_VALUE,
3634 ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
3635
3636 params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
3637 params.high_burst_size_gran = FALSE;
3638 params.burst_size = p_RateLimit->maxBurstSize;
3639 params.rate = p_RateLimit->rateLimit;
3640 params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
3641
3642 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3643 {
3644#ifndef FM_NO_ADVANCED_RATE_LIMITER
3645
3646 if ((p_FmPort->fmRevInfo.majorRev == 4)
3647 || (p_FmPort->fmRevInfo.majorRev >= 6))
3648 {
3649 params.high_burst_size_gran = TRUE;
3650 }
3651 else
3652#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
3653 {
3654 if (p_RateLimit->rateLimitDivider
3655 != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
3656 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
3657 ("FM_PORT_ConfigDualRateLimitScaleDown"));
3658
3659 if (p_RateLimit->maxBurstSize % 1000)
3660 {
3661 p_RateLimit->maxBurstSize =
3662 (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
3663 DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
3664 }
3665 else
3666 p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
3667 / 1000);
3668 }
3669 params.rate_factor =
3670 (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
3671 params.burst_size = p_RateLimit->maxBurstSize;
3672 }
3673
3674 err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
3675 if (err != 0)
3676 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
3677
3678 return E_OK;
3679}
3680
3681t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
3682{
3683 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3684 int err;
3685
3686 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3687 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
3688
3689 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
3690 || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
3691 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
3692 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
3693 ("available for Tx and Offline parsing ports only"));
3694
3695 err = fman_port_delete_rate_limiter(&p_FmPort->port);
3696 if (err != 0)
3697 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
3698 return E_OK;
3699}
3700
3701t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
3702 uint8_t wq)
3703{
3704 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3705 uint32_t tmpReg;
3706 uint32_t wqTmpReg;
3707
3708 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3709 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3710
3711 if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
3712 && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
3713 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
3714 ("PFC mapping is available for Tx ports only"));
3715
3716 if (prio > 7)
3717 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
3718 ("PFC priority (%d) is out of range (0-7)", prio));
3719 if (wq > 7)
3720 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
3721 ("WQ (%d) is out of range (0-7)", wq));
3722
3723 tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
3724 tmpReg &= ~(0xf << ((7 - prio) * 4));
3725 wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
3726 tmpReg |= wqTmpReg;
3727
3728 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
3729 tmpReg);
3730
3731 return E_OK;
3732}
3733
3734t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
3735{
3736 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3737
3738 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3739 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3740
3741 fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
3742
3743 return E_OK;
3744}
3745
3746t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
3747{
3748 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3749 int err;
3750
3751 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3752 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3753
3754 err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
3755 if (err != 0)
3756 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
3757 return E_OK;
3758}
3759
3760t_Error FM_PORT_SetPerformanceCountersParams(
3761 t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
3762{
3763 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3764 struct fman_port_perf_cnt_params params;
3765 int err;
3766
3767 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3768
3769 /* check parameters */
3770 if (!p_FmPortPerformanceCnt->taskCompVal
3771 || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
3772 RETURN_ERROR(
3773 MAJOR,
3774 E_INVALID_VALUE,
3775 ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
3776 if (!p_FmPortPerformanceCnt->dmaCompVal
3777 || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
3778 RETURN_ERROR(
3779 MAJOR,
3780 E_INVALID_VALUE,
3781 ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
3782 if (!p_FmPortPerformanceCnt->fifoCompVal
3783 || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
3784 RETURN_ERROR(
3785 MAJOR,
3786 E_INVALID_VALUE,
3787 ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
3788 if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
3789 RETURN_ERROR(
3790 MAJOR,
3791 E_INVALID_VALUE,
3792 ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
3793
3794 switch (p_FmPort->portType)
3795 {
3796 case (e_FM_PORT_TYPE_RX_10G):
3797 case (e_FM_PORT_TYPE_RX):
3798 if (!p_FmPortPerformanceCnt->queueCompVal
3799 || (p_FmPortPerformanceCnt->queueCompVal
3800 > MAX_PERFORMANCE_RX_QUEUE_COMP))
3801 RETURN_ERROR(
3802 MAJOR,
3803 E_INVALID_VALUE,
3804 ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
3805 break;
3806 case (e_FM_PORT_TYPE_TX_10G):
3807 case (e_FM_PORT_TYPE_TX):
3808 if (!p_FmPortPerformanceCnt->queueCompVal
3809 || (p_FmPortPerformanceCnt->queueCompVal
3810 > MAX_PERFORMANCE_TX_QUEUE_COMP))
3811 RETURN_ERROR(
3812 MAJOR,
3813 E_INVALID_VALUE,
3814 ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
3815 break;
3816 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3817 case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
3818 if (p_FmPortPerformanceCnt->queueCompVal)
3819 RETURN_ERROR(
3820 MAJOR,
3821 E_INVALID_VALUE,
3822 ("performanceCnt.queueCompVal is not relevant for H/O ports."));
3823 break;
3824 default:
3825 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
3826 }
3827
3828 params.task_val = p_FmPortPerformanceCnt->taskCompVal;
3829 params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
3830 params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
3831 params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
3832
3833 err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
3834 if (err != 0)
3835 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
3836
3837 return E_OK;
3838}
3839
3840t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
3841{
3842 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3843 t_FmPortPerformanceCnt currParams, savedParams;
3844 t_Error err;
3845 bool underTest, failed = FALSE;
3846
3847 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3848
3849 XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
3850 p_FmPort->portType, p_FmPort->portId);
3851
3852 currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
3853 if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
3854 || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
3855 currParams.queueCompVal = 0;
3856 else
3857 currParams.queueCompVal = 1;
3858 currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
3859 currParams.fifoCompVal = p_FmPort->fifoBufs.num;
3860
3861 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3862 ClearPerfCnts(p_FmPort);
3863 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
3864 != E_OK)
3865 RETURN_ERROR(MAJOR, err, NO_MSG);
3866 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
3867 XX_UDelay(1000000);
3868 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3869 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
3870 {
3871 XX_Print(
3872 "Max num of defined port tasks (%d) utilized - Please enlarge\n",
3873 p_FmPort->tasks.num);
3874 failed = TRUE;
3875 }
3876 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
3877 {
3878 XX_Print(
3879 "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
3880 p_FmPort->openDmas.num);
3881 failed = TRUE;
3882 }
3883 if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
3884 {
3885 XX_Print(
3886 "Max size of defined port fifo (%d) utilized - Please enlarge\n",
3887 p_FmPort->fifoBufs.num);
3888 failed = TRUE;
3889 }
3890 if (failed)
3891 RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
3892
3893 memset(&savedParams, 0, sizeof(savedParams));
3894 while (TRUE)
3895 {
3896 underTest = FALSE;
3897 if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
3898 {
3899 currParams.taskCompVal--;
3900 underTest = TRUE;
3901 }
3902 if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
3903 {
3904 currParams.dmaCompVal--;
3905 underTest = TRUE;
3906 }
3907 if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
3908 && !savedParams.fifoCompVal)
3909 {
3910 currParams.fifoCompVal -= BMI_FIFO_UNITS;
3911 underTest = TRUE;
3912 }
3913 if (!underTest)
3914 break;
3915
3916 ClearPerfCnts(p_FmPort);
3917 if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
3918 != E_OK)
3919 RETURN_ERROR(MAJOR, err, NO_MSG);
3920 FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
3921 XX_UDelay(1000000);
3922 FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
3923
3924 if (!savedParams.taskCompVal
3925 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
3926 savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
3927 if (!savedParams.dmaCompVal
3928 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
3929 savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
3930 if (!savedParams.fifoCompVal
3931 && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
3932 savedParams.fifoCompVal = currParams.fifoCompVal
3933 + (2 * BMI_FIFO_UNITS);
3934 }
3935
3936 XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
3937 savedParams.taskCompVal, savedParams.dmaCompVal,
3938 savedParams.fifoCompVal);
3939 return E_OK;
3940}
3941
3942t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
3943{
3944 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3945 int err;
3946
3947 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
3948 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
3949
3950 err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
3951 if (err != 0)
3952 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
3953 return E_OK;
3954}
3955
3956t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
3957{
3958 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
3959 volatile uint32_t *p_ErrDiscard = NULL;
3960 int err;
3961
3962 UNUSED(p_ErrDiscard);
3963 err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
3964 if (err != 0)
3965 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
3966
3967#ifdef FM_ERROR_VSP_NO_MATCH_SW006
3968 if (p_FmPort->fmRevInfo.majorRev >= 6)
3969 {
3970 t_FmPcdCtrlParamsPage *p_ParamsPage;
3971
3972 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
3973 (void**)&p_ParamsPage);
3974 ASSERT_COND(p_ParamsPage);
3975 switch (p_FmPort->portType)
3976 {
3977 case (e_FM_PORT_TYPE_RX_10G):
3978 case (e_FM_PORT_TYPE_RX):
3979 p_ErrDiscard =
3980 &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
3981 break;
3982 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
3983 p_ErrDiscard =
3984 &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
3985 break;
3986 default:
3987 RETURN_ERROR(
3988 MAJOR, E_INVALID_OPERATION,
3989 ("available for Rx and offline parsing ports only"));
3990 }
3991 WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
3992 GET_UINT32(*p_ErrDiscard) | errs);
3993 }
3994#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
3995
3996 return E_OK;
3997}
3998
3999t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
4000 bool enable)
4001{
4002 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4003 int err;
4004
4005 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4006 SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
4007 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4008
4009 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4010 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
4011 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4012 ("available for Rx ports only"));
4013
4014 err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
4015 if (err != 0)
4016 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
4017 return E_OK;
4018}
4019
4020t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
4021{
4022 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4023
4024 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4025 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
4026 p_BmiStats->cntCycle =
4027 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4028 /* fmbm_rccn */
4029 p_BmiStats->cntTaskUtil =
4030 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4031 /* fmbm_rtuc */
4032 p_BmiStats->cntQueueUtil =
4033 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
4034 /* fmbm_rrquc */
4035 p_BmiStats->cntDmaUtil =
4036 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4037 /* fmbm_rduc */
4038 p_BmiStats->cntFifoUtil =
4039 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4040 /* fmbm_rfuc */
4041 p_BmiStats->cntRxPauseActivation =
4042 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
4043 /* fmbm_rpac */
4044 p_BmiStats->cntFrame =
4045 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4046 /* fmbm_rfrc */
4047 p_BmiStats->cntDiscardFrame =
4048 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4049 /* fmbm_rfdc */
4050 p_BmiStats->cntDeallocBuf =
4051 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4052 /* fmbm_rbdc */
4053 p_BmiStats->cntRxBadFrame =
4054 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
4055 /* fmbm_rfbc */
4056 p_BmiStats->cntRxLargeFrame =
4057 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
4058 /* fmbm_rlfc */
4059 p_BmiStats->cntRxFilterFrame =
4060 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
4061 /* fmbm_rffc */
4062 p_BmiStats->cntRxListDmaErr =
4063 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
4064 /* fmbm_rfldec */
4065 p_BmiStats->cntRxOutOfBuffersDiscard =
4066 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
4067 /* fmbm_rodc */
4068 p_BmiStats->cntWredDiscard = 0;
4069 p_BmiStats->cntLengthErr = 0;
4070 p_BmiStats->cntUnsupportedFormat = 0;
4071 }
4072 else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
4073 || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
4074 p_BmiStats->cntCycle =
4075 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4076 /* fmbm_tccn */
4077 p_BmiStats->cntTaskUtil =
4078 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4079 /* fmbm_ttuc */
4080 p_BmiStats->cntQueueUtil =
4081 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
4082 /* fmbm_ttcquc */
4083 p_BmiStats->cntDmaUtil =
4084 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4085 /* fmbm_tduc */
4086 p_BmiStats->cntFifoUtil =
4087 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4088 /* fmbm_tfuc */
4089 p_BmiStats->cntRxPauseActivation = 0;
4090 p_BmiStats->cntFrame =
4091 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4092 /* fmbm_tfrc */
4093 p_BmiStats->cntDiscardFrame =
4094 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4095 /* fmbm_tfdc */
4096 p_BmiStats->cntDeallocBuf =
4097 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4098 /* fmbm_tbdc */
4099 p_BmiStats->cntRxBadFrame = 0;
4100 p_BmiStats->cntRxLargeFrame = 0;
4101 p_BmiStats->cntRxFilterFrame = 0;
4102 p_BmiStats->cntRxListDmaErr = 0;
4103 p_BmiStats->cntRxOutOfBuffersDiscard = 0;
4104 p_BmiStats->cntWredDiscard = 0;
4105 p_BmiStats->cntLengthErr =
4106 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
4107 /* fmbm_tfledc */
4108 p_BmiStats->cntUnsupportedFormat =
4109 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
4110 /* fmbm_tfufdc */
4111 }
4112 else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
4113 p_BmiStats->cntCycle =
4114 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
4115 /* fmbm_occn */
4116 p_BmiStats->cntTaskUtil =
4117 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
4118 /* fmbm_otuc */
4119 p_BmiStats->cntQueueUtil = 0;
4120 p_BmiStats->cntDmaUtil =
4121 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
4122 /* fmbm_oduc */
4123 p_BmiStats->cntFifoUtil =
4124 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
4125 /* fmbm_ofuc*/
4126 p_BmiStats->cntRxPauseActivation = 0;
4127 p_BmiStats->cntFrame =
4128 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
4129 /* fmbm_ofrc */
4130 p_BmiStats->cntDiscardFrame =
4131 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
4132 /* fmbm_ofdc */
4133 p_BmiStats->cntDeallocBuf =
4134 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
4135 /* fmbm_obdc*/
4136 p_BmiStats->cntRxBadFrame = 0;
4137 p_BmiStats->cntRxLargeFrame = 0;
4138 p_BmiStats->cntRxFilterFrame =
4139 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
4140 /* fmbm_offc */
4141 p_BmiStats->cntRxListDmaErr =
4142 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
4143 /* fmbm_ofldec */
4144 p_BmiStats->cntRxOutOfBuffersDiscard =
4145 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
4146 /* fmbm_rodc */
4147 p_BmiStats->cntWredDiscard =
4148 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
4149 /* fmbm_ofwdc */
4150 p_BmiStats->cntLengthErr =
4151 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
4152 /* fmbm_ofledc */
4153 p_BmiStats->cntUnsupportedFormat =
4154 FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
4155 /* fmbm_ofufdc */
4156 }
4157 return E_OK;
4158}
4159
4160uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
4161{
4162 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4163 bool bmiCounter = FALSE;
4164 enum fman_port_stats_counters statsType;
4165 enum fman_port_perf_counters perfType;
4166 enum fman_port_qmi_counters queueType;
4167 bool isStats;
4168 t_Error errCode;
4169
4170 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
4171 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4172
4173 switch (counter)
4174 {
4175 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4176 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4177 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4178 /* check that counter is available for the port type */
4179 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4180 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4181 {
4182 REPORT_ERROR(MINOR, E_INVALID_STATE,
4183 ("Requested counter is not available for Rx ports"));
4184 return 0;
4185 }
4186 bmiCounter = FALSE;
4187 break;
4188 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4189 bmiCounter = FALSE;
4190 break;
4191 default: /* BMI counters (or error - will be checked in BMI routine )*/
4192 bmiCounter = TRUE;
4193 break;
4194 }
4195
4196 if (bmiCounter)
4197 {
4198 errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
4199 &perfType, &isStats);
4200 if (errCode != E_OK)
4201 {
4202 REPORT_ERROR(MINOR, errCode, NO_MSG);
4203 return 0;
4204 }
4205 if (isStats)
4206 return fman_port_get_stats_counter(&p_FmPort->port, statsType);
4207 else
4208 return fman_port_get_perf_counter(&p_FmPort->port, perfType);
4209 }
4210 else /* QMI counter */
4211 {
4212 /* check that counters are enabled */
4213 if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
4214 & QMI_PORT_CFG_EN_COUNTERS))
4215
4216 {
4217 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
4218 return 0;
4219 }
4220
4221 /* Set counter */
4222 switch (counter)
4223 {
4224 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4225 queueType = E_FMAN_PORT_ENQ_TOTAL;
4226 break;
4227 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4228 queueType = E_FMAN_PORT_DEQ_TOTAL;
4229 break;
4230 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4231 queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
4232 break;
4233 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4234 queueType = E_FMAN_PORT_DEQ_CONFIRM;
4235 break;
4236 default:
4237 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
4238 return 0;
4239 }
4240
4241 return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
4242 }
4243
4244 return 0;
4245}
4246
4247t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
4248 uint32_t value)
4249{
4250 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4251 bool bmiCounter = FALSE;
4252 enum fman_port_stats_counters statsType;
4253 enum fman_port_perf_counters perfType;
4254 enum fman_port_qmi_counters queueType;
4255 bool isStats;
4256 t_Error errCode;
4257
4258 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4259 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4260
4261 switch (counter)
4262 {
4263 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4264 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4265 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4266 /* check that counter is available for the port type */
4267 if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
4268 || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4269 RETURN_ERROR(
4270 MINOR, E_INVALID_STATE,
4271 ("Requested counter is not available for Rx ports"));
4272 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4273 bmiCounter = FALSE;
4274 break;
4275 default: /* BMI counters (or error - will be checked in BMI routine )*/
4276 bmiCounter = TRUE;
4277 break;
4278 }
4279
4280 if (bmiCounter)
4281 {
4282 errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
4283 &perfType, &isStats);
4284 if (errCode != E_OK)
4285 {
4286 RETURN_ERROR(MINOR, errCode, NO_MSG);
4287 }
4288 if (isStats)
4289 fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
4290 else
4291 fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
4292 }
4293 else /* QMI counter */
4294 {
4295 /* check that counters are enabled */
4296 if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
4297 & QMI_PORT_CFG_EN_COUNTERS))
4298 {
4299 RETURN_ERROR(MINOR, E_INVALID_STATE,
4300 ("Requested counter was not enabled"));
4301 }
4302
4303 /* Set counter */
4304 switch (counter)
4305 {
4306 case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
4307 queueType = E_FMAN_PORT_ENQ_TOTAL;
4308 break;
4309 case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
4310 queueType = E_FMAN_PORT_DEQ_TOTAL;
4311 break;
4312 case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
4313 queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
4314 break;
4315 case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
4316 queueType = E_FMAN_PORT_DEQ_CONFIRM;
4317 break;
4318 default:
4319 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4320 ("Requested counter is not available"));
4321 }
4322
4323 fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
4324 }
4325
4326 return E_OK;
4327}
4328
4329uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
4330{
4331 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4332
4333 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
4334 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4335
4336 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
4337 && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4338 {
4339 REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
4340 return 0;
4341 }
4342 return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
4343}
4344
4345t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
4346 uint32_t value)
4347{
4348 t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
4349
4350 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4351 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4352
4353 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
4354 && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
4355 RETURN_ERROR( MINOR, E_INVALID_STATE,
4356 ("Requested counter is not available for non-Rx ports"));
4357
4358 fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
4359 return E_OK;
4360}
4361bool FM_PORT_IsStalled(t_Handle h_FmPort)
4362{
4363 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4364 t_Error err;
4365 bool isStalled;
4366
4367 SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
4368 SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
4369 FALSE);
4370
4371 err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
4372 if (err != E_OK)
4373 {
4374 REPORT_ERROR(MAJOR, err, NO_MSG);
4375 return TRUE;
4376 }
4377 return isStalled;
4378}
4379
4380t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
4381{
4382 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4383
4384 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4385 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4386
4387 return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
4388}
4389
4390t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
4391{
4392 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4393 int err;
4394
4395 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4396 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4397
4398 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4399 && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
4400 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4401 ("available for Rx ports only"));
4402
4403 if (l4Checksum)
4404 err = fman_port_modify_rx_fd_bits(
4405 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
4406 TRUE);
4407 else
4408 err = fman_port_modify_rx_fd_bits(
4409 &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
4410 FALSE);
4411 if (err != 0)
4412 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
4413
4414 return E_OK;
4415}
4416
4417/*****************************************************************************/
4418/* API Run-time PCD Control unit functions */
4419/*****************************************************************************/
4420
4421#if (DPAA_VERSION >= 11)
4422t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
4423{
4424 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4425 t_Error err = E_OK;
4426 volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
4427 uint32_t tmpReg = 0, tmp = 0;
4428 uint16_t hwStoragePrflId;
4429
4430 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4431 SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
4432 /*for numOfProfiles = 0 don't call this function*/
4433 SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
4434 /*dfltRelativeId should be in the range of numOfProfiles*/
4435 SANITY_CHECK_RETURN_ERROR(
4436 p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
4437 E_INVALID_VALUE);
4438 /*p_FmPort should be from Rx type or OP*/
4439 SANITY_CHECK_RETURN_ERROR(
4440 ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
4441 E_INVALID_VALUE);
4442 /*port should be disabled*/
4443 SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
4444 /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
4445 SANITY_CHECK_RETURN_ERROR(
4446 ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
4447 E_INVALID_VALUE);
4448 /*should be called before SetPCD - this port should be without PCD*/
4449 SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
4450
4451 /*alloc window of VSPs for this port*/
4452 err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
4453 p_FmPort->portId, p_VSPParams->numOfProfiles);
4454 if (err != E_OK)
4455 RETURN_ERROR(MAJOR, err, NO_MSG);
4456
4457 /*get absolute VSP ID for dfltRelative*/
4458 err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
4459 p_FmPort->portId,
4460 p_VSPParams->dfltRelativeId,
4461 &hwStoragePrflId);
4462 if (err != E_OK)
4463 RETURN_ERROR(MAJOR, err, NO_MSG);
4464
4465 /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
4466 switch (p_FmPort->portType)
4467 {
4468 case (e_FM_PORT_TYPE_RX_10G):
4469 case (e_FM_PORT_TYPE_RX):
4470 p_BmiStorageProfileId =
4471 &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
4472 p_BmiVspe =
4473 &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
4474
4475 tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
4476 tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
4477 WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
4478
4479 tmpReg = GET_UINT32(*p_BmiVspe);
4480 WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
4481
4482 p_BmiStorageProfileId =
4483 &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
4484 p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
4485 hwStoragePrflId = p_VSPParams->dfltRelativeId;
4486 break;
4487
4488 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4489 tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
4490 WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
4491 tmpReg);
4492
4493 p_BmiStorageProfileId =
4494 &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
4495 p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
4496 tmp |= BMI_EBD_EN;
4497 break;
4498
4499 default:
4500 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4501 ("available for Rx and offline parsing ports only"));
4502 }
4503
4504 p_FmPort->vspe = TRUE;
4505 p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
4506
4507 tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
4508 tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
4509 WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
4510
4511 tmpReg = GET_UINT32(*p_BmiVspe);
4512 WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
4513 return E_OK;
4514}
4515#endif /* (DPAA_VERSION >= 11) */
4516
4517t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
4518{
4519 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4520 t_Error err = E_OK;
4521
4522 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
4523 ASSERT_COND(p_FmPort->h_FmPcd);
4524
4525 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4526 {
4527 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4528 return ERROR_CODE(E_BUSY);
4529 }
4530
4531 if (numOfProfiles)
4532 {
4533 err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
4534 p_FmPort->hardwarePortId, numOfProfiles);
4535 if (err)
4536 RETURN_ERROR(MAJOR, err, NO_MSG);
4537 }
4538 /* set the port handle within the PCD policer, even if no profiles defined */
4539 FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
4540
4541 RELEASE_LOCK(p_FmPort->lock);
4542
4543 return E_OK;
4544}
4545
4546t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
4547{
4548 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4549 t_Error err = E_OK;
4550
4551 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4552 {
4553 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4554 return ERROR_CODE(E_BUSY);
4555 }
4556
4557 err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
4558
4559 RELEASE_LOCK(p_FmPort->lock);
4560
4561 if (err)
4562 RETURN_ERROR(MAJOR, err, NO_MSG);
4563
4564 return E_OK;
4565}
4566
4567t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
4568 t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
4569{
4570 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4571 volatile uint32_t *p_BmiHpnia = NULL;
4572 uint32_t tmpReg;
4573 uint8_t relativeSchemeId;
4574 uint8_t physicalSchemeId;
4575
4576 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4577 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4578 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
4579 E_INVALID_STATE);
4580
4581 tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
4582 switch (p_FmPort->portType)
4583 {
4584 case (e_FM_PORT_TYPE_RX_10G):
4585 case (e_FM_PORT_TYPE_RX):
4586 p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
4587 break;
4588 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4589 p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
4590 break;
4591 default:
4592 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4593 ("available for Rx and offline parsing ports only"));
4594 }
4595
4596 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4597 {
4598 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4599 return ERROR_CODE(E_BUSY);
4600 }
4601
4602 /* if we want to change to direct scheme, we need to check that this scheme is valid */
4603 if (p_FmPcdKgScheme->direct)
4604 {
4605 physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
4606 /* check that this scheme is bound to this port */
4607 if (!(p_FmPort->schemesPerPortVector
4608 & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
4609 {
4610 RELEASE_LOCK(p_FmPort->lock);
4611 RETURN_ERROR(
4612 MAJOR, E_INVALID_STATE,
4613 ("called with a scheme that is not bound to this port"));
4614 }
4615
4616 relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
4617 physicalSchemeId);
4618 if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
4619 {
4620 RELEASE_LOCK(p_FmPort->lock);
4621 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
4622 ("called with invalid Scheme "));
4623 }
4624
4625 if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
4626 {
4627 RELEASE_LOCK(p_FmPort->lock);
4628 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4629 ("called with uninitialized Scheme "));
4630 }
4631
4632 WRITE_UINT32(
4633 *p_BmiHpnia,
4634 NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
4635 }
4636 else
4637 /* change to indirect scheme */
4638 WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
4639 RELEASE_LOCK(p_FmPort->lock);
4640
4641 return E_OK;
4642}
4643
4644t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
4645 t_Handle h_Profile)
4646{
4647 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4648 volatile uint32_t *p_BmiNia;
4649 volatile uint32_t *p_BmiHpnia;
4650 uint32_t tmpReg;
4651 uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
4652
4653 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
4654 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4655 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
4656 E_INVALID_STATE);
4657
4658 /* check relevance of this routine - only when policer is used
4659 directly after BMI or Parser */
4660 if ((p_FmPort->pcdEngines & FM_PCD_KG)
4661 || (p_FmPort->pcdEngines & FM_PCD_CC))
4662 RETURN_ERROR(
4663 MAJOR,
4664 E_INVALID_STATE,
4665 ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
4666
4667 switch (p_FmPort->portType)
4668 {
4669 case (e_FM_PORT_TYPE_RX_10G):
4670 case (e_FM_PORT_TYPE_RX):
4671 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
4672 p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
4673 tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
4674 break;
4675 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4676 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
4677 p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
4678 tmpReg = 0;
4679 break;
4680 default:
4681 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4682 ("available for Rx and offline parsing ports only"));
4683 }
4684
4685 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4686 {
4687 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4688 return ERROR_CODE(E_BUSY);
4689 }
4690
4691 if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
4692 {
4693 RELEASE_LOCK(p_FmPort->lock);
4694 RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
4695 }
4696
4697 tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
4698
4699 if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
4700 {
4701 /* update BMI HPNIA */
4702 WRITE_UINT32(*p_BmiHpnia, tmpReg);
4703 }
4704 else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
4705 {
4706 /* rfne may contain FDCS bits, so first we read them. */
4707 tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
4708 /* update BMI NIA */
4709 WRITE_UINT32(*p_BmiNia, tmpReg);
4710 }RELEASE_LOCK(p_FmPort->lock);
4711
4712 return E_OK;
4713}
4714
4715t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
4716{
4717 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4718 t_Error err = E_OK;
4719 volatile uint32_t *p_BmiCcBase = NULL;
4720 volatile uint32_t *p_BmiNia = NULL;
4721 uint32_t ccTreePhysOffset;
4722
4723 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4724 SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
4725
4726 if (p_FmPort->imEn)
4727 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4728 ("available for non-independent mode ports only"));
4729
4730 /* get PCD registers pointers */
4731 switch (p_FmPort->portType)
4732 {
4733 case (e_FM_PORT_TYPE_RX_10G):
4734 case (e_FM_PORT_TYPE_RX):
4735 p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
4736 break;
4737 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4738 p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
4739 break;
4740 default:
4741 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4742 ("available for Rx and offline parsing ports only"));
4743 }
4744
4745 /* check that current NIA is BMI to BMI */
4746 if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
4747 != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
4748 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4749 ("may be called only for ports in BMI-to-BMI state."));
4750
4751 if (p_FmPort->pcdEngines & FM_PCD_CC)
4752 {
4753 if (p_FmPort->h_IpReassemblyManip)
4754 {
4755 err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
4756 p_FmPort->h_IpReassemblyManip, FALSE);
4757 if (err != E_OK)
4758 {
4759 RETURN_ERROR(MAJOR, err, NO_MSG);
4760 }
4761 }
4762 else
4763 if (p_FmPort->h_CapwapReassemblyManip)
4764 {
4765 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
4766 p_FmPort->h_CapwapReassemblyManip,
4767 FALSE);
4768 if (err != E_OK)
4769 {
4770 RETURN_ERROR(MAJOR, err, NO_MSG);
4771 }
4772 }
4773 switch (p_FmPort->portType)
4774 {
4775 case (e_FM_PORT_TYPE_RX_10G):
4776 case (e_FM_PORT_TYPE_RX):
4777 p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
4778 break;
4779 case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
4780 p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
4781 break;
4782 default:
4783 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
4784 }
4785
4786 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4787 {
4788 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4789 return ERROR_CODE(E_BUSY);
4790 }
4791 err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
4792 &ccTreePhysOffset, h_FmPort);
4793 if (err)
4794 {
4795 RELEASE_LOCK(p_FmPort->lock);
4796 RETURN_ERROR(MAJOR, err, NO_MSG);
4797 }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
4798
4799 p_FmPort->ccTreeId = h_CcTree;
4800 RELEASE_LOCK(p_FmPort->lock);
4801 }
4802 else
4803 RETURN_ERROR( MAJOR, E_INVALID_STATE,
4804 ("Coarse Classification not defined for this port."));
4805
4806 return E_OK;
4807}
4808
4809t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
4810{
4811 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4812 t_Error err = E_OK;
4813
4814 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4815 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4816
4817 if (p_FmPort->imEn)
4818 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4819 ("available for non-independent mode ports only"));
4820
4821 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4822 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4823 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4824 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4825 ("available for Rx and offline parsing ports only"));
4826
4827 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4828 {
4829 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4830 return ERROR_CODE(E_BUSY);
4831 }
4832
4833 if (p_FmPort->h_ReassemblyTree)
4834 p_FmPort->pcdEngines |= FM_PCD_CC;
4835
4836 err = AttachPCD(h_FmPort);
4837 RELEASE_LOCK(p_FmPort->lock);
4838
4839 return err;
4840}
4841
4842t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
4843{
4844 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4845 t_Error err = E_OK;
4846
4847 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4848 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4849
4850 if (p_FmPort->imEn)
4851 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4852 ("available for non-independent mode ports only"));
4853
4854 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4855 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4856 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4857 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4858 ("available for Rx and offline parsing ports only"));
4859
4860 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4861 {
4862 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4863 return ERROR_CODE(E_BUSY);
4864 }
4865
4866 err = DetachPCD(h_FmPort);
4867 if (err != E_OK)
4868 {
4869 RELEASE_LOCK(p_FmPort->lock);
4870 RETURN_ERROR(MAJOR, err, NO_MSG);
4871 }
4872
4873 if (p_FmPort->h_ReassemblyTree)
4874 p_FmPort->pcdEngines &= ~FM_PCD_CC;
4875 RELEASE_LOCK(p_FmPort->lock);
4876
4877 return E_OK;
4878}
4879
4880t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
4881{
4882 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
4883 t_Error err = E_OK;
4884 t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
4885 t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
4886 t_FmPortPcdCcParams fmPortPcdCcParams;
4887 t_FmPortGetSetCcParams fmPortGetSetCcParams;
4888
4889 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
4890 SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
4891 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
4892
4893 if (p_FmPort->imEn)
4894 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
4895 ("available for non-independent mode ports only"));
4896
4897 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
4898 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
4899 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4900 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
4901 ("available for Rx and offline parsing ports only"));
4902
4903 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
4904 {
4905 DBG(TRACE, ("FM Port Try Lock - BUSY"));
4906 return ERROR_CODE(E_BUSY);
4907 }
4908
4909 p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
4910 ASSERT_COND(p_FmPort->h_FmPcd);
4911
4912 if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
4913 RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
4914 ("Tree handle must be given if CC is required"));
4915
4916 memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
4917 p_PcdParams = &modifiedPcdParams;
4918 if ((p_PcdParams->h_IpReassemblyManip)
4919#if (DPAA_VERSION >= 11)
4920 || (p_PcdParams->h_CapwapReassemblyManip)
4921#endif /* (DPAA_VERSION >= 11) */
4922 )
4923 {
4924 if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4925 && (p_PcdParams->pcdSupport
4926 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
4927 && (p_PcdParams->pcdSupport
4928 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
4929 && (p_PcdParams->pcdSupport
4930 != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
4931 {
4932 RELEASE_LOCK(p_FmPort->lock);
4933 RETURN_ERROR( MAJOR, E_INVALID_STATE,
4934 ("pcdSupport must have KG for supporting Reassembly"));
4935 }
4936 p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
4937#if (DPAA_VERSION >= 11)
4938 if ((p_PcdParams->h_IpReassemblyManip)
4939 && (p_PcdParams->h_CapwapReassemblyManip))
4940 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4941 ("Either IP-R or CAPWAP-R is allowed"));
4942 if ((p_PcdParams->h_CapwapReassemblyManip)
4943 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
4944 RETURN_ERROR(MAJOR, E_INVALID_STATE,
4945 ("CAPWAP-R is allowed only on offline-port"));
4946 if (p_PcdParams->h_CapwapReassemblyManip)
4947 p_FmPort->h_CapwapReassemblyManip =
4948 p_PcdParams->h_CapwapReassemblyManip;
4949#endif /* (DPAA_VERSION >= 11) */
4950
4951 if (!p_PcdParams->p_CcParams)
4952 {
4953 if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4954 || (p_PcdParams->pcdSupport
4955 == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
4956 {
4957 RELEASE_LOCK(p_FmPort->lock);
4958 RETURN_ERROR(
4959 MAJOR,
4960 E_INVALID_STATE,
4961 ("PCD initialization structure is not consistent with pcdSupport"));
4962 }
4963
4964 /* No user-tree, need to build internal tree */
4965 p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
4966 sizeof(t_FmPcdCcTreeParams));
4967 if (!p_FmPcdCcTreeParams)
4968 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
4969 memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
4970 p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
4971 p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
4972 p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
4973
4974 if (!p_FmPort->h_ReassemblyTree)
4975 {
4976 RELEASE_LOCK(p_FmPort->lock);
4977 XX_Free(p_FmPcdCcTreeParams);
4978 RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
4979 ("FM_PCD_CcBuildTree for Reassembly failed"));
4980 }
4981 if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
4982 p_PcdParams->pcdSupport =
4983 e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
4984 else
4985 p_PcdParams->pcdSupport =
4986 e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
4987
4988 memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
4989 fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
4990 p_PcdParams->p_CcParams = &fmPortPcdCcParams;
4991 XX_Free(p_FmPcdCcTreeParams);
4992 }
4993
4994 if (p_FmPort->h_IpReassemblyManip)
4995 err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
4996 p_PcdParams->p_CcParams->h_CcTree,
4997 p_PcdParams->h_NetEnv,
4998 p_FmPort->h_IpReassemblyManip, TRUE);
4999#if (DPAA_VERSION >= 11)
5000 else
5001 if (p_FmPort->h_CapwapReassemblyManip)
5002 err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
5003 p_PcdParams->p_CcParams->h_CcTree,
5004 p_PcdParams->h_NetEnv,
5005 p_FmPort->h_CapwapReassemblyManip,
5006 TRUE);
5007#endif /* (DPAA_VERSION >= 11) */
5008
5009 if (err != E_OK)
5010 {
5011 if (p_FmPort->h_ReassemblyTree)
5012 {
5013 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5014 p_FmPort->h_ReassemblyTree = NULL;
5015 }RELEASE_LOCK(p_FmPort->lock);
5016 RETURN_ERROR(MAJOR, err, NO_MSG);
5017 }
5018 }
5019
5020 if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
5021 {
5022 if (p_FmPort->h_ReassemblyTree)
5023 {
5024 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5025 p_FmPort->h_ReassemblyTree = NULL;
5026 }RELEASE_LOCK(p_FmPort->lock);
5027 DBG(TRACE, ("Try LockAll - BUSY"));
5028 return ERROR_CODE(E_BUSY);
5029 }
5030
5031 err = SetPcd(h_FmPort, p_PcdParams);
5032 if (err)
5033 {
5034 if (p_FmPort->h_ReassemblyTree)
5035 {
5036 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5037 p_FmPort->h_ReassemblyTree = NULL;
5038 }
5039 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5040 RELEASE_LOCK(p_FmPort->lock);
5041 RETURN_ERROR(MAJOR, err, NO_MSG);
5042 }
5043
5044 if ((p_FmPort->pcdEngines & FM_PCD_PRS)
5045 && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
5046 {
5047 err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
5048 p_FmPort->hardwarePortId, TRUE);
5049 if (err)
5050 {
5051 DeletePcd(p_FmPort);
5052 if (p_FmPort->h_ReassemblyTree)
5053 {
5054 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5055 p_FmPort->h_ReassemblyTree = NULL;
5056 }
5057 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5058 RELEASE_LOCK(p_FmPort->lock);
5059 RETURN_ERROR(MAJOR, err, NO_MSG);
5060 }
5061 p_FmPort->includeInPrsStatistics = TRUE;
5062 }
5063
5064 FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
5065
5066 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5067 {
5068 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
5069
5070 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
5071 {
5072#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
5073 if ((p_FmPort->fmRevInfo.majorRev < 6) &&
5074 (p_FmPort->pcdEngines & FM_PCD_KG))
5075 {
5076 int i;
5077 for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
5078 /* The following function must be locked */
5079 FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
5080 p_PcdParams->p_KgParams->h_Schemes[i],
5081 UPDATE_KG_NIA_CC_WA,
5082 0);
5083 }
5084#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
5085
5086#if (DPAA_VERSION >= 11)
5087 {
5088 t_FmPcdCtrlParamsPage *p_ParamsPage;
5089
5090 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
5091 (void**)&p_ParamsPage);
5092 ASSERT_COND(p_ParamsPage);
5093 WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
5094 p_FmPort->savedBmiNia);
5095 }
5096#endif /* (DPAA_VERSION >= 11) */
5097
5098 /* Set post-bmi-fetch nia */
5099 p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
5100 p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
5101 | NIA_ENG_FM_CTL);
5102
5103 /* Set pre-bmi-fetch nia */
5104 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
5105#if (DPAA_VERSION >= 11)
5106 fmPortGetSetCcParams.setCcParams.nia =
5107 (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
5108#else
5109 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
5110#endif /* (DPAA_VERSION >= 11) */
5111 if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
5112 != E_OK)
5113 {
5114 DeletePcd(p_FmPort);
5115 if (p_FmPort->h_ReassemblyTree)
5116 {
5117 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5118 p_FmPort->h_ReassemblyTree = NULL;
5119 }
5120 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5121 RELEASE_LOCK(p_FmPort->lock);
5122 RETURN_ERROR(MAJOR, err, NO_MSG);
5123 }
5124 }
5125
5126 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5127
5128 /* Set pop-to-next-step nia */
5129#if (DPAA_VERSION == 10)
5130 if (p_FmPort->fmRevInfo.majorRev < 6)
5131 {
5132 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
5133 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
5134 }
5135 else
5136 {
5137#endif /* (DPAA_VERSION == 10) */
5138 fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
5139#if (DPAA_VERSION == 10)
5140 }
5141#endif /* (DPAA_VERSION == 10) */
5142 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5143 != E_OK)
5144 {
5145 DeletePcd(p_FmPort);
5146 if (p_FmPort->h_ReassemblyTree)
5147 {
5148 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5149 p_FmPort->h_ReassemblyTree = NULL;
5150 }RELEASE_LOCK(p_FmPort->lock);
5151 RETURN_ERROR(MAJOR, err, NO_MSG);
5152 }
5153
5154 /* Set post-bmi-prepare-to-enq nia */
5155 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
5156 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
5157 | NIA_ENG_FM_CTL);
5158 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5159 != E_OK)
5160 {
5161 DeletePcd(p_FmPort);
5162 if (p_FmPort->h_ReassemblyTree)
5163 {
5164 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5165 p_FmPort->h_ReassemblyTree = NULL;
5166 }RELEASE_LOCK(p_FmPort->lock);
5167 RETURN_ERROR(MAJOR, err, NO_MSG);
5168 }
5169
5170 if ((p_FmPort->h_IpReassemblyManip)
5171 || (p_FmPort->h_CapwapReassemblyManip))
5172 {
5173#if (DPAA_VERSION == 10)
5174 if (p_FmPort->fmRevInfo.majorRev < 6)
5175 {
5176 /* Overwrite post-bmi-prepare-to-enq nia */
5177 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
5178 fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
5179 fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
5180 }
5181 else
5182 {
5183#endif /* (DPAA_VERSION == 10) */
5184 /* Set the ORR bit (for order-restoration) */
5185 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
5186 fmPortGetSetCcParams.setCcParams.nia =
5187 fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
5188#if (DPAA_VERSION == 10)
5189 }
5190#endif /* (DPAA_VERSION == 10) */
5191 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5192 != E_OK)
5193 {
5194 DeletePcd(p_FmPort);
5195 if (p_FmPort->h_ReassemblyTree)
5196 {
5197 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5198 p_FmPort->h_ReassemblyTree = NULL;
5199 }RELEASE_LOCK(p_FmPort->lock);
5200 RETURN_ERROR(MAJOR, err, NO_MSG);
5201 }
5202 }
5203 }
5204 else
5205 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5206
5207#if (DPAA_VERSION >= 11)
5208 {
5209 t_FmPcdCtrlParamsPage *p_ParamsPage;
5210
5211 memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
5212
5213 fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
5214 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5215 fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
5216 | NIA_ENG_FM_CTL;
5217 else
5218 fmPortGetSetCcParams.setCcParams.nia =
5219 NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
5220 if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
5221 != E_OK)
5222 {
5223 DeletePcd(p_FmPort);
5224 if (p_FmPort->h_ReassemblyTree)
5225 {
5226 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5227 p_FmPort->h_ReassemblyTree = NULL;
5228 }RELEASE_LOCK(p_FmPort->lock);
5229 RETURN_ERROR(MAJOR, err, NO_MSG);
5230 }
5231
5232 FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
5233 (void**)&p_ParamsPage);
5234 ASSERT_COND(p_ParamsPage);
5235
5236 if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
5237 WRITE_UINT32(
5238 p_ParamsPage->misc,
5239 GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
5240
5241 if ((p_FmPort->h_IpReassemblyManip)
5242 || (p_FmPort->h_CapwapReassemblyManip))
5243 {
5244 if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
5245 WRITE_UINT32(
5246 p_ParamsPage->discardMask,
5247 GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
5248 else
5249 WRITE_UINT32(
5250 p_ParamsPage->discardMask,
5251 GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
5252 }
5253#ifdef FM_ERROR_VSP_NO_MATCH_SW006
5254 if (p_FmPort->vspe)
5255 WRITE_UINT32(
5256 p_ParamsPage->misc,
5257 GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
5258#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
5259 }
5260#endif /* (DPAA_VERSION >= 11) */
5261
5262 err = AttachPCD(h_FmPort);
5263 if (err)
5264 {
5265 DeletePcd(p_FmPort);
5266 if (p_FmPort->h_ReassemblyTree)
5267 {
5268 FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5269 p_FmPort->h_ReassemblyTree = NULL;
5270 }RELEASE_LOCK(p_FmPort->lock);
5271 RETURN_ERROR(MAJOR, err, NO_MSG);
5272 }
5273
5274 RELEASE_LOCK(p_FmPort->lock);
5275
5276 return err;
5277}
5278
5279t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
5280{
5281 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5282 t_Error err = E_OK;
5283
5284 SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
5285 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5286
5287 if (p_FmPort->imEn)
5288 RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
5289 ("available for non-independant mode ports only"));
5290
5291 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5292 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5293 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5294 RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
5295 ("available for Rx and offline parsing ports only"));
5296
5297 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5298 {
5299 DBG(TRACE, ("FM Port Try Lock - BUSY"));
5300 return ERROR_CODE(E_BUSY);
5301 }
5302
5303 err = DetachPCD(h_FmPort);
5304 if (err)
5305 {
5306 RELEASE_LOCK(p_FmPort->lock);
5307 RETURN_ERROR(MAJOR, err, NO_MSG);
5308 }
5309
5310 FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
5311
5312 /* we do it anyway, instead of checking if included */
5313 if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
5314 {
5315 FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
5316 p_FmPort->hardwarePortId, FALSE);
5317 p_FmPort->includeInPrsStatistics = FALSE;
5318 }
5319
5320 if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
5321 {
5322 RELEASE_LOCK(p_FmPort->lock);
5323 DBG(TRACE, ("Try LockAll - BUSY"));
5324 return ERROR_CODE(E_BUSY);
5325 }
5326
5327 err = DeletePcd(h_FmPort);
5328 FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
5329 if (err)
5330 {
5331 RELEASE_LOCK(p_FmPort->lock);
5332 RETURN_ERROR(MAJOR, err, NO_MSG);
5333 }
5334
5335 if (p_FmPort->h_ReassemblyTree)
5336 {
5337 err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
5338 if (err)
5339 {
5340 RELEASE_LOCK(p_FmPort->lock);
5341 RETURN_ERROR(MAJOR, err, NO_MSG);
5342 }
5343 p_FmPort->h_ReassemblyTree = NULL;
5344 }RELEASE_LOCK(p_FmPort->lock);
5345
5346 return err;
5347}
5348
5349t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
5350 t_FmPcdPortSchemesParams *p_PortScheme)
5351{
5352 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5353 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
5354 t_Error err = E_OK;
5355 uint32_t tmpScmVec = 0;
5356 int i;
5357
5358 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5359 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5360 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
5361 E_INVALID_STATE);
5362
5363 schemeBind.netEnvId = p_FmPort->netEnvId;
5364 schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
5365 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
5366 schemeBind.useClsPlan = p_FmPort->useClsPlan;
5367 for (i = 0; i < schemeBind.numOfSchemes; i++)
5368 {
5369 schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
5370 p_PortScheme->h_Schemes[i]);
5371 /* build vector */
5372 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
5373 }
5374
5375 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5376 {
5377 DBG(TRACE, ("FM Port Try Lock - BUSY"));
5378 return ERROR_CODE(E_BUSY);
5379 }
5380
5381 err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
5382 if (err == E_OK)
5383 p_FmPort->schemesPerPortVector |= tmpScmVec;
5384
5385#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
5386 if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
5387 (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
5388 (p_FmPort->fmRevInfo.majorRev < 6))
5389 {
5390 for (i=0; i<p_PortScheme->numOfSchemes; i++)
5391 FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
5392 }
5393#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
5394
5395 RELEASE_LOCK(p_FmPort->lock);
5396
5397 return err;
5398}
5399
5400t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
5401 t_FmPcdPortSchemesParams *p_PortScheme)
5402{
5403 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5404 t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
5405 t_Error err = E_OK;
5406 uint32_t tmpScmVec = 0;
5407 int i;
5408
5409 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5410 SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
5411 SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
5412 E_INVALID_STATE);
5413
5414 schemeBind.netEnvId = p_FmPort->netEnvId;
5415 schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
5416 schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
5417 for (i = 0; i < schemeBind.numOfSchemes; i++)
5418 {
5419 schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
5420 p_PortScheme->h_Schemes[i]);
5421 /* build vector */
5422 tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
5423 }
5424
5425 if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
5426 {
5427 DBG(TRACE, ("FM Port Try Lock - BUSY"));
5428 return ERROR_CODE(E_BUSY);
5429 }
5430
5431 err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
5432 if (err == E_OK)
5433 p_FmPort->schemesPerPortVector &= ~tmpScmVec;
5434 RELEASE_LOCK(p_FmPort->lock);
5435
5436 return err;
5437}
5438
5439t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
5440 t_FmPortCongestionGrps *p_CongestionGrps)
5441{
5442 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5443 uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
5444 uint8_t mod, index;
5445 uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
5446 int err;
5447#if (DPAA_VERSION >= 11)
5448 int j;
5449#endif /* (DPAA_VERSION >= 11) */
5450
5451 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5452
5453 /* un-necessary check of the indexes; probably will be needed in the future when there
5454 will be more CGs available ....
5455 for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5456 if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
5457 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
5458 */
5459
5460#ifdef FM_NO_OP_OBSERVED_CGS
5461 if ((p_FmPort->fmRevInfo.majorRev != 4) &&
5462 (p_FmPort->fmRevInfo.majorRev < 6))
5463 {
5464 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
5465 (p_FmPort->portType != e_FM_PORT_TYPE_RX))
5466 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
5467 }
5468 else
5469#endif /* FM_NO_OP_OBSERVED_CGS */
5470 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5471 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5472 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5473 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5474 ("Available for Rx & OP ports only"));
5475
5476 /* Prepare groups map array */
5477 memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
5478 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5479 {
5480 index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
5481 mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
5482 if (p_FmPort->fmRevInfo.majorRev != 4)
5483 grpsMap[7 - index] |= (uint32_t)(1 << mod);
5484 else
5485 grpsMap[0] |= (uint32_t)(1 << mod);
5486 }
5487
5488 memset(&priorityTmpArray, 0,
5489 FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
5490
5491 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5492 {
5493#if (DPAA_VERSION >= 11)
5494 for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
5495 if (p_CongestionGrps->pfcPrioritiesEn[i][j])
5496 priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
5497 (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
5498#endif /* (DPAA_VERSION >= 11) */
5499 }
5500
5501#if (DPAA_VERSION >= 11)
5502 for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
5503 {
5504 err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
5505 priorityTmpArray[i]);
5506 if (err)
5507 return err;
5508 }
5509#endif /* (DPAA_VERSION >= 11) */
5510
5511 err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
5512 if (err != 0)
5513 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
5514
5515 return E_OK;
5516}
5517
5518t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
5519 t_FmPortCongestionGrps *p_CongestionGrps)
5520{
5521 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5522 uint8_t mod, index;
5523 uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
5524 int err;
5525
5526 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5527
5528 {
5529#ifdef FM_NO_OP_OBSERVED_CGS
5530 t_FmRevisionInfo revInfo;
5531
5532 FM_GetRevision(p_FmPort->h_Fm, &revInfo);
5533 if (revInfo.majorRev != 4)
5534 {
5535 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
5536 (p_FmPort->portType != e_FM_PORT_TYPE_RX))
5537 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
5538 }
5539 else
5540#endif /* FM_NO_OP_OBSERVED_CGS */
5541 if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
5542 && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
5543 && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
5544 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
5545 ("Available for Rx & OP ports only"));
5546 }
5547
5548 /* Prepare groups map array */
5549 memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
5550 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5551 {
5552 index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
5553 mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
5554 if (p_FmPort->fmRevInfo.majorRev != 4)
5555 grpsMap[7 - index] |= (uint32_t)(1 << mod);
5556 else
5557 grpsMap[0] |= (uint32_t)(1 << mod);
5558 }
5559
5560#if (DPAA_VERSION >= 11)
5561 for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
5562 {
5563 t_Error err = FmSetCongestionGroupPFCpriority(
5564 p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
5565 0);
5566 if (err)
5567 return err;
5568 }
5569#endif /* (DPAA_VERSION >= 11) */
5570
5571 err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
5572 if (err != 0)
5573 RETURN_ERROR(MAJOR, E_INVALID_VALUE,
5574 ("fman_port_remove_congestion_grps"));
5575 return E_OK;
5576}
5577
5578#if (DPAA_VERSION >= 11)
5579t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
5580 uint32_t *p_Ipv4OptionsCount)
5581{
5582 t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
5583
5584 SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
5585 SANITY_CHECK_RETURN_ERROR(
5586 (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
5587 E_INVALID_VALUE);
5588 SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
5589 SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
5590
5591 *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
5592
5593 return E_OK;
5594}
5595#endif /* (DPAA_VERSION >= 11) */
5596
5597t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
5598 t_FmPortDsarTablesSizes *params)
5599{
5600 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5601 p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
5602 sizeof(struct t_FmPortDsarTablesSizes));
5603 memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
5604 sizeof(struct t_FmPortDsarTablesSizes));
5605 return E_OK;
5606}
5607
5608static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
5609{
5610 uint32_t *param_page;
5611 t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
5612 t_ArCommonDesc *ArCommonDescPtr;
5613 uint32_t size = sizeof(t_ArCommonDesc);
5614 // ARP
5615 // should put here if (params->max_num_of_arp_entries)?
5616 size = ROUND_UP(size,4);
5617 size += sizeof(t_DsarArpDescriptor);
5618 size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
5619 size += sizeof(t_DsarArpStatistics);
5620 //ICMPV4
5621 size = ROUND_UP(size,4);
5622 size += sizeof(t_DsarIcmpV4Descriptor);
5623 size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
5624 size += sizeof(t_DsarIcmpV4Statistics);
5625 //ICMPV6
5626 size = ROUND_UP(size,4);
5627 size += sizeof(t_DsarIcmpV6Descriptor);
5628 size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
5629 size += sizeof(t_DsarIcmpV6Statistics);
5630 //ND
5631 size = ROUND_UP(size,4);
5632 size += sizeof(t_DsarNdDescriptor);
5633 size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
5634 size += sizeof(t_DsarIcmpV6Statistics);
5635 //SNMP
5636 size = ROUND_UP(size,4);
5637 size += sizeof(t_DsarSnmpDescriptor);
5638 size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
5639 * params->maxNumOfSnmpIPV4Entries;
5640 size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
5641 * params->maxNumOfSnmpIPV6Entries;
5642 size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
5643 size += params->maxNumOfSnmpOidChar;
5644 size += sizeof(t_DsarIcmpV6Statistics);
5645 //filters
5646 size = ROUND_UP(size,4);
5647 size += params->maxNumOfIpProtFiltering;
5648 size = ROUND_UP(size,4);
5649 size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
5650 size = ROUND_UP(size,4);
5651 size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
5652
5653 // add here for more protocols
5654
5655 // statistics
5656 size = ROUND_UP(size,4);
5657 size += sizeof(t_ArStatistics);
5658
5659 ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
5660
5661 param_page =
5662 XX_PhysToVirt(
5663 p_FmPort->fmMuramPhysBaseAddr
5664 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
5665 WRITE_UINT32(
5666 *param_page,
5667 (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
5668 return E_OK;
5669}
5670
5671t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
5672{
5673 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5674 return p_FmPort->deepSleepVars.autoResMaxSizes;
5675}
5676
5677struct arOffsets
5678{
5679 uint32_t arp;
5680 uint32_t nd;
5681 uint32_t icmpv4;
5682 uint32_t icmpv6;
5683 uint32_t snmp;
5684 uint32_t stats;
5685 uint32_t filtIp;
5686 uint32_t filtUdp;
5687 uint32_t filtTcp;
5688};
5689
5690static uint32_t AR_ComputeOffsets(struct arOffsets* of,
5691 struct t_FmPortDsarParams *params,
5692 t_FmPort *p_FmPort)
5693{
5694 uint32_t size = sizeof(t_ArCommonDesc);
5695 // ARP
5696 if (params->p_AutoResArpInfo)
5697 {
5698 size = ROUND_UP(size,4);
5699 of->arp = size;
5700 size += sizeof(t_DsarArpDescriptor);
5701 size += sizeof(t_DsarArpBindingEntry)
5702 * params->p_AutoResArpInfo->tableSize;
5703 size += sizeof(t_DsarArpStatistics);
5704 }
5705 // ICMPV4
5706 if (params->p_AutoResEchoIpv4Info)
5707 {
5708 size = ROUND_UP(size,4);
5709 of->icmpv4 = size;
5710 size += sizeof(t_DsarIcmpV4Descriptor);
5711 size += sizeof(t_DsarIcmpV4BindingEntry)
5712 * params->p_AutoResEchoIpv4Info->tableSize;
5713 size += sizeof(t_DsarIcmpV4Statistics);
5714 }
5715 // ICMPV6
5716 if (params->p_AutoResEchoIpv6Info)
5717 {
5718 size = ROUND_UP(size,4);
5719 of->icmpv6 = size;
5720 size += sizeof(t_DsarIcmpV6Descriptor);
5721 size += sizeof(t_DsarIcmpV6BindingEntry)
5722 * params->p_AutoResEchoIpv6Info->tableSize;
5723 size += sizeof(t_DsarIcmpV6Statistics);
5724 }
5725 // ND
5726 if (params->p_AutoResNdpInfo)
5727 {
5728 size = ROUND_UP(size,4);
5729 of->nd = size;
5730 size += sizeof(t_DsarNdDescriptor);
5731 size += sizeof(t_DsarIcmpV6BindingEntry)
5732 * (params->p_AutoResNdpInfo->tableSizeAssigned
5733 + params->p_AutoResNdpInfo->tableSizeTmp);
5734 size += sizeof(t_DsarIcmpV6Statistics);
5735 }
5736 // SNMP
5737 if (params->p_AutoResSnmpInfo)
5738 {
5739 size = ROUND_UP(size,4);
5740 of->snmp = size;
5741 size += sizeof(t_DsarSnmpDescriptor);
5742 size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
5743 * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
5744 size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
5745 * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
5746 size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
5747 size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
5748 size += sizeof(t_DsarIcmpV6Statistics);
5749 }
5750 //filters
5751 size = ROUND_UP(size,4);
5752 if (params->p_AutoResFilteringInfo)
5753 {
5754 of->filtIp = size;
5755 size += params->p_AutoResFilteringInfo->ipProtTableSize;
5756 size = ROUND_UP(size,4);
5757 of->filtUdp = size;
5758 size += params->p_AutoResFilteringInfo->udpPortsTableSize
5759 * sizeof(t_PortTblEntry);
5760 size = ROUND_UP(size,4);
5761 of->filtTcp = size;
5762 size += params->p_AutoResFilteringInfo->tcpPortsTableSize
5763 * sizeof(t_PortTblEntry);
5764 }
5765 // add here for more protocols
5766 // statistics
5767 size = ROUND_UP(size,4);
5768 of->stats = size;
5769 size += sizeof(t_ArStatistics);
5770 return size;
5771}
5772
5773uint32_t* ARDesc;
5774void PrsEnable(t_Handle p_FmPcd);
5775void PrsDisable(t_Handle p_FmPcd);
5776int PrsIsEnabled(t_Handle p_FmPcd);
5777t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
5778
5779static t_Error DsarCheckParams(t_FmPortDsarParams *params,
5780 t_FmPortDsarTablesSizes *sizes)
5781{
5782 bool macInit = FALSE;
5783 uint8_t mac[6];
5784 int i = 0;
5785
5786 // check table sizes
5787 if (params->p_AutoResArpInfo
5788 && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
5789 RETURN_ERROR(
5790 MAJOR, E_INVALID_VALUE,
5791 ("DSAR: Arp table size exceeds the configured maximum size."));
5792 if (params->p_AutoResEchoIpv4Info
5793 && sizes->maxNumOfEchoIpv4Entries
5794 < params->p_AutoResEchoIpv4Info->tableSize)
5795 RETURN_ERROR(
5796 MAJOR,
5797 E_INVALID_VALUE,
5798 ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
5799 if (params->p_AutoResNdpInfo
5800 && sizes->maxNumOfNdpEntries
5801 < params->p_AutoResNdpInfo->tableSizeAssigned
5802 + params->p_AutoResNdpInfo->tableSizeTmp)
5803 RETURN_ERROR(
5804 MAJOR, E_INVALID_VALUE,
5805 ("DSAR: NDP table size exceeds the configured maximum size."));
5806 if (params->p_AutoResEchoIpv6Info
5807 && sizes->maxNumOfEchoIpv6Entries
5808 < params->p_AutoResEchoIpv6Info->tableSize)
5809 RETURN_ERROR(
5810 MAJOR,
5811 E_INVALID_VALUE,
5812 ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
5813 if (params->p_AutoResSnmpInfo
5814 && sizes->maxNumOfSnmpOidEntries
5815 < params->p_AutoResSnmpInfo->oidsTblSize)
5816 RETURN_ERROR(
5817 MAJOR,
5818 E_INVALID_VALUE,
5819 ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
5820 if (params->p_AutoResSnmpInfo
5821 && sizes->maxNumOfSnmpIPV4Entries
5822 < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
5823 RETURN_ERROR(
5824 MAJOR,
5825 E_INVALID_VALUE,
5826 ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
5827 if (params->p_AutoResSnmpInfo
5828 && sizes->maxNumOfSnmpIPV6Entries
5829 < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
5830 RETURN_ERROR(
5831 MAJOR,
5832 E_INVALID_VALUE,
5833 ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
5834 if (params->p_AutoResFilteringInfo)
5835 {
5836 if (sizes->maxNumOfIpProtFiltering
5837 < params->p_AutoResFilteringInfo->ipProtTableSize)
5838 RETURN_ERROR(
5839 MAJOR,
5840 E_INVALID_VALUE,
5841 ("DSAR: ip filter table size exceeds the configured maximum size."));
5842 if (sizes->maxNumOfTcpPortFiltering
5843 < params->p_AutoResFilteringInfo->udpPortsTableSize)
5844 RETURN_ERROR(
5845 MAJOR,
5846 E_INVALID_VALUE,
5847 ("DSAR: udp filter table size exceeds the configured maximum size."));
5848 if (sizes->maxNumOfUdpPortFiltering
5849 < params->p_AutoResFilteringInfo->tcpPortsTableSize)
5850 RETURN_ERROR(
5851 MAJOR,
5852 E_INVALID_VALUE,
5853 ("DSAR: tcp filter table size exceeds the configured maximum size."));
5854 }
5855 /* check only 1 MAC address is configured (this is what ucode currently supports) */
5856 if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
5857 {
5858 memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
5859 i = 1;
5860 macInit = TRUE;
5861
5862 for (; i < params->p_AutoResArpInfo->tableSize; i++)
5863 if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
5864 RETURN_ERROR(
5865 MAJOR, E_INVALID_VALUE,
5866 ("DSAR: Only 1 mac address is currently supported."));
5867 }
5868 if (params->p_AutoResEchoIpv4Info
5869 && params->p_AutoResEchoIpv4Info->tableSize)
5870 {
5871 i = 0;
5872 if (!macInit)
5873 {
5874 memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
5875 6);
5876 i = 1;
5877 macInit = TRUE;
5878 }
5879 for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
5880 if (memcmp(mac,
5881 params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
5882 RETURN_ERROR(
5883 MAJOR, E_INVALID_VALUE,
5884 ("DSAR: Only 1 mac address is currently supported."));
5885 }
5886 if (params->p_AutoResEchoIpv6Info
5887 && params->p_AutoResEchoIpv6Info->tableSize)
5888 {
5889 i = 0;
5890 if (!macInit)
5891 {
5892 memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
5893 6);
5894 i = 1;
5895 macInit = TRUE;
5896 }
5897 for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
5898 if (memcmp(mac,
5899 params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
5900 RETURN_ERROR(
5901 MAJOR, E_INVALID_VALUE,
5902 ("DSAR: Only 1 mac address is currently supported."));
5903 }
5904 if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
5905 {
5906 i = 0;
5907 if (!macInit)
5908 {
5909 memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
5910 6);
5911 i = 1;
5912 macInit = TRUE;
5913 }
5914 for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
5915 if (memcmp(mac,
5916 params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
5917 6))
5918 RETURN_ERROR(
5919 MAJOR, E_INVALID_VALUE,
5920 ("DSAR: Only 1 mac address is currently supported."));
5921 }
5922 if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
5923 {
5924 i = 0;
5925 if (!macInit)
5926 {
5927 memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
5928 i = 1;
5929 }
5930 for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
5931 if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
5932 6))
5933 RETURN_ERROR(
5934 MAJOR, E_INVALID_VALUE,
5935 ("DSAR: Only 1 mac address is currently supported."));
5936 }
5937 return E_OK;
5938}
5939
5940static int GetBERLen(uint8_t* buf)
5941{
5942 if (*buf & 0x80)
5943 {
5944 if ((*buf & 0x7F) == 1)
5945 return buf[1];
5946 else
5947 return *(uint16_t*)&buf[1]; // assuming max len is 2
5948 }
5949 else
5950 return buf[0];
5951}
5952#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
5953
5954#ifdef TODO_SOC_SUSPEND // XXX
5955#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
5956#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
5957#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
5958static int fm_soc_suspend(void)
5959{
5960 uint32_t *fmclk, tmp32;
5961 fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
5962 tmp32 = GET_UINT32(*fmclk);
5963 WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
5964 tmp32 = GET_UINT32(*fmclk);
5965 iounmap(fmclk);
5966 return 0;
5967}
5968
5969void fm_clk_down(void)
5970{
5971 uint32_t *fmclk, tmp32;
5972 fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
5973 tmp32 = GET_UINT32(*fmclk);
5974 WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
5975 tmp32 = GET_UINT32(*fmclk);
5976 iounmap(fmclk);
5977}
5978#endif
5979
5980#if 0
5981t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
5982{
5983 int i, j;
5984 t_Error err;
5985 uint32_t nia;
5986 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
5987 t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
5988 t_DsarArpDescriptor *ArpDescriptor;
5989 t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
5990 t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
5991 t_DsarNdDescriptor* NDDescriptor;
5992
5993 uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
5994 uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
5995 t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
5996 struct arOffsets* of;
5997 uint8_t tmp = 0;
5998 t_FmGetSetParams fmGetSetParams;
5999 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6000 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6001 fmGetSetParams.setParams.sleep = 1;
6002
6003 err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
6004 if (err != E_OK)
6005 return err;
6006
6007 p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
6008 of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
6009 IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
6010
6011 // common
6012 WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
6013 nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
6014 if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
6015 WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
6016 else
6017 WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
6018 WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
6019
6020 // ARP
6021 if (params->p_AutoResArpInfo)
6022 {
6023 t_DsarArpBindingEntry* arp_bindings;
6024 ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
6025 WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
6026 arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
6027 if (params->p_AutoResArpInfo->enableConflictDetection)
6028 WRITE_UINT16(ArpDescriptor->control, 1);
6029 else
6030 WRITE_UINT16(ArpDescriptor->control, 0);
6031 if (params->p_AutoResArpInfo->tableSize)
6032 {
6033 t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
6034 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
6035 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
6036 WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
6037
6038 for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
6039 {
6040 WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
6041 if (arp_entry[i].isVlan)
6042 WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
6043 }
6044 WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
6045 }
6046 WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
6047 sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
6048 }
6049
6050 // ICMPV4
6051 if (params->p_AutoResEchoIpv4Info)
6052 {
6053 t_DsarIcmpV4BindingEntry* icmpv4_bindings;
6054 ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
6055 WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
6056 icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
6057 WRITE_UINT16(ICMPV4Descriptor->control, 0);
6058 if (params->p_AutoResEchoIpv4Info->tableSize)
6059 {
6060 t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
6061 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
6062 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
6063 WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
6064
6065 for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
6066 {
6067 WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
6068 if (arp_entry[i].isVlan)
6069 WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
6070 }
6071 WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
6072 }
6073 WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
6074 sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
6075 }
6076
6077 // ICMPV6
6078 if (params->p_AutoResEchoIpv6Info)
6079 {
6080 t_DsarIcmpV6BindingEntry* icmpv6_bindings;
6081 ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
6082 WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
6083 icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
6084 WRITE_UINT16(ICMPV6Descriptor->control, 0);
6085 if (params->p_AutoResEchoIpv6Info->tableSize)
6086 {
6087 t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
6088 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
6089 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
6090 WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
6091
6092 for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
6093 {
6094 for (j = 0; j < 4; j++)
6095 WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6096 if (ndp_entry[i].isVlan)
6097 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6098 }
6099 WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
6100 }
6101 WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
6102 sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
6103 }
6104
6105 // ND
6106 if (params->p_AutoResNdpInfo)
6107 {
6108 t_DsarIcmpV6BindingEntry* icmpv6_bindings;
6109 NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
6110 WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
6111 icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
6112 if (params->p_AutoResNdpInfo->enableConflictDetection)
6113 WRITE_UINT16(NDDescriptor->control, 1);
6114 else
6115 WRITE_UINT16(NDDescriptor->control, 0);
6116 if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
6117 {
6118 t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
6119 WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
6120 WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
6121 WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
6122 + params->p_AutoResNdpInfo->tableSizeTmp);
6123
6124 for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
6125 {
6126 for (j = 0; j < 4; j++)
6127 WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6128 if (ndp_entry[i].isVlan)
6129 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6130 }
6131 ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
6132 for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
6133 {
6134 for (j = 0; j < 4; j++)
6135 WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
6136 if (ndp_entry[i].isVlan)
6137 WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
6138 }
6139 WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
6140 }
6141 WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
6142 * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
6143 - fmMuramVirtBaseAddr);
6144 WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
6145 }
6146
6147 // SNMP
6148 if (params->p_AutoResSnmpInfo)
6149 {
6150 t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
6151 t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
6152 t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
6153 t_OidsTblEntry* snmpOid;
6154 uint8_t *charPointer;
6155 int len;
6156 t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
6157 WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
6158 WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
6159 WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
6160 snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
6161 if (snmpSrc->numOfIpv4Addresses)
6162 {
6163 t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
6164 WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
6165 for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
6166 {
6167 WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
6168 if (snmpIpv4AddrSrc[i].isVlan)
6169 WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
6170 }
6171 WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
6172 }
6173 snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
6174 + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
6175 if (snmpSrc->numOfIpv6Addresses)
6176 {
6177 t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
6178 WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
6179 for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
6180 {
6181 for (j = 0; j < 4; j++)
6182 WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
6183 if (snmpIpv6AddrSrc[i].isVlan)
6184 WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
6185 }
6186 WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
6187 }
6188 snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
6189 + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
6190 charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
6191 + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
6192 len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
6193 Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
6194 WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6195 charPointer += len;
6196 len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
6197 Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
6198 WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6199 charPointer += len;
6200 WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
6201 WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
6202 for (i = 0; i < snmpSrc->oidsTblSize; i++)
6203 {
6204 WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
6205 WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
6206 Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
6207 WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6208 charPointer += snmpSrc->p_OidsTbl[i].oidSize;
6209 if (snmpSrc->p_OidsTbl[i].resSize <= 4)
6210 WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
6211 else
6212 {
6213 Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
6214 WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6215 charPointer += snmpSrc->p_OidsTbl[i].resSize;
6216 }
6217 snmpOid++;
6218 }
6219 charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
6220 WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
6221 }
6222
6223 // filtering
6224 if (params->p_AutoResFilteringInfo)
6225 {
6226 if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
6227 tmp |= IP_PROT_TBL_PASS_MASK;
6228 if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
6229 tmp |= UDP_PORT_TBL_PASS_MASK;
6230 if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
6231 tmp |= TCP_PORT_TBL_PASS_MASK;
6232 WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
6233 WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
6234
6235 // ip filtering
6236 if (params->p_AutoResFilteringInfo->ipProtTableSize)
6237 {
6238 uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
6239 WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
6240 for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
6241 WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
6242 WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
6243 }
6244
6245 // udp filtering
6246 if (params->p_AutoResFilteringInfo->udpPortsTableSize)
6247 {
6248 t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
6249 WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
6250 for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
6251 {
6252 WRITE_UINT32(udp_tbl[i].Ports,
6253 (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
6254 params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
6255 WRITE_UINT32(udp_tbl[i].PortsMask,
6256 (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
6257 params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
6258 }
6259 WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
6260 }
6261
6262 // tcp filtering
6263 if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
6264 {
6265 t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
6266 WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
6267 for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
6268 {
6269 WRITE_UINT32(tcp_tbl[i].Ports,
6270 (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
6271 params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
6272 WRITE_UINT32(tcp_tbl[i].PortsMask,
6273 (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
6274 params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
6275 }
6276 WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
6277 }
6278 }
6279 // common stats
6280 WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
6281
6282 // get into Deep Sleep sequence:
6283
6284 // Ensures that FMan do not enter the idle state. This is done by programing
6285 // FMDPSLPCR[FM_STOP] to one.
6286 fm_soc_suspend();
6287
6288 ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
6289 return E_OK;
6290
6291}
6292
6293void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
6294t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
6295{
6296 t_FmGetSetParams fmGetSetParams;
6297 t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
6298 t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
6299 t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
6300 t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
6301 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6302 fmGetSetParams.setParams.type = UPDATE_FM_CLD;
6303 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6304
6305 /* Issue graceful stop to HC port */
6306 FM_PORT_Disable(p_FmPortHc);
6307
6308 // config tx port
6309 p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
6310 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN);
6311 // ????
6312 p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
6313 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
6314 // Stage 7:echo
6315 p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
6316 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
6317 if (!PrsIsEnabled(h_FmPcd))
6318 {
6319 p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
6320 PrsEnable(h_FmPcd);
6321 }
6322 else
6323 p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
6324
6325 p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
6326 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
6327
6328 // save rcfg for restoring: accumulate mode is changed by ucode
6329 p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
6330 WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
6331 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6332 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6333 fmGetSetParams.setParams.sleep = 1;
6334 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6335
6336// ***** issue external request sync command
6337 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6338 fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
6339 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6340 // get
6341 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6342 fmGetSetParams.getParams.type = GET_FMFP_EXTC;
6343 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6344 if (fmGetSetParams.getParams.fmfp_extc != 0)
6345 {
6346 // clear
6347 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6348 fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
6349 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6350}
6351
6352 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6353 fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
6354 do
6355 {
6356 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6357 } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
6358 if (fmGetSetParams.getParams.fm_npi != 0)
6359 XX_Print("FM: Sync did not finish\n");
6360
6361 // check that all stoped
6362 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6363 fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
6364 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6365 while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
6366 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6367 if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
6368 XX_Print("FM: Sleeping\n");
6369// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
6370
6371 return E_OK;
6372}
6373
6374void FM_PORT_Dsar_DumpRegs()
6375{
6376 uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
6377 DUMP_MEMORY(hh, 0x220);
6378}
6379
6380void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
6381{
6382 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
6383 t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
6384 t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
6385 t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
6386 t_FmGetSetParams fmGetSetParams;
6387 memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
6388 fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
6389 fmGetSetParams.setParams.sleep = 0;
6390 if (p_FmPort->deepSleepVars.autoResOffsets)
6391 {
6392 XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
6393 p_FmPort->deepSleepVars.autoResOffsets = 0;
6394 }
6395
6396 if (p_FmPort->deepSleepVars.dsarEnabledParser)
6397 PrsDisable(FmGetPcd(p_FmPort->h_Fm));
6398 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
6399 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
6400 WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
6401 FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
6402 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
6403 WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
6404 FM_PORT_Enable(p_FmPortHc);
6405}
6406
6407bool FM_PORT_IsInDsar(t_Handle h_FmPort)
6408{
6409 t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
6410 return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
6411}
6412
6413t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
6414{
6415 t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
6416 struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
6417 uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
6418 uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
6419 t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
6420 t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
6421 t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6422 t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
6423 t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
6424 t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
6425 t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6426 t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
6427 t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
6428 t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
6429 t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
6430 stats->arpArCnt = arp_stats->arCnt;
6431 stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
6432 stats->ndpArCnt = nd_stats->arCnt;
6433 stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
6434 stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
6435 stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
6436 return E_OK;
6437}
6438#endif