summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2016-02-29 03:38:00 +0000
committerjhibbits <jhibbits@FreeBSD.org>2016-02-29 03:38:00 +0000
commit8bf1194fe59ab6a4905efd0ff00cd6b7462247e1 (patch)
tree5b00ae419405b400d27fe05a3ed4868b17bbcb84
parent52a73c87240c0127dc9cc5990eb4c701f34efdd2 (diff)
downloadFreeBSD-src-8bf1194fe59ab6a4905efd0ff00cd6b7462247e1.zip
FreeBSD-src-8bf1194fe59ab6a4905efd0ff00cd6b7462247e1.tar.gz
Add support for the Freescale dTSEC DPAA-based ethernet controller.
Freescale's QorIQ line includes a new ethernet controller, based on their Datapath Acceleration Architecture (DPAA). This uses a combination of a Frame manager, Buffer manager, and Queue manager to improve performance across all interfaces by being able to pass data directly between hardware acceleration interfaces. As part of this import, Freescale's Netcomm Software (ncsw) driver is imported. This was an attempt by Freescale to create an OS-agnostic sub-driver for managing the hardware, using shims to interface to the OS-specific APIs. This work was abandoned, and Freescale's primary work is in the Linux driver (dual BSD/GPL license). Hence, this was imported directly to sys/contrib, rather than going through the vendor area. Going forward, FreeBSD-specific changes may be made to the ncsw code, diverging from the upstream in potentially incompatible ways. An alternative could be to import the Linux driver itself, using the linuxKPI layer, as that would maintain parity with the vendor-maintained driver. However, the Linux driver has not been evaluated for reliability yet, and may have issues with the import, whereas the ncsw-based driver in this commit was completed by Semihalf 4 years ago, and is very stable. Other SoC modules based on DPAA, which could be added in the future: * Security and Encryption engine (SEC4.x, SEC5.x) * RAID engine Additional work to be done: * Implement polling mode * Test vlan support * Add support for the Pattern Matching Engine, which can do regular expression matching on packets. This driver has been tested on the P5020 QorIQ SoC. Others listed in the dtsec(4) manual page are expected to work as the same DPAA engine is included in all. Obtained from: Semihalf Relnotes: Yes Sponsored by: Alex Perez/Inertial Computing
-rw-r--r--share/man/man4/man4.powerpc/dtsec.4120
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/bm.c815
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/bm.h453
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/bm_ipc.h125
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/bm_pool.c593
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/bm_portal.c561
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/bman_low.c494
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/bman_private.h249
-rw-r--r--sys/contrib/ncsw/Peripherals/BM/fsl_bman.h347
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/HC/hc.c1584
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c1941
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h634
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c120
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h78
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c560
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h197
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c1268
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h482
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c121
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h81
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c3467
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h312
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c3189
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c2637
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h310
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c1693
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h715
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h326
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c1702
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c517
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c5060
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h894
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c789
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c891
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h217
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/fm.c4605
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/fm.h699
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/fm_guest.c35
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/fm_ipc.h449
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/fm_muram.c164
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h1173
-rw-r--r--sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h86
-rw-r--r--sys/contrib/ncsw/Peripherals/QM/fsl_qman.h1097
-rw-r--r--sys/contrib/ncsw/Peripherals/QM/qm.c1266
-rw-r--r--sys/contrib/ncsw/Peripherals/QM/qm.h651
-rw-r--r--sys/contrib/ncsw/Peripherals/QM/qm_ipc.h125
-rw-r--r--sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c2701
-rw-r--r--sys/contrib/ncsw/Peripherals/QM/qman_low.h1148
-rw-r--r--sys/contrib/ncsw/Peripherals/QM/qman_private.h285
-rw-r--r--sys/contrib/ncsw/build/dflags.h60
-rw-r--r--sys/contrib/ncsw/build/events_mapping.h47
-rw-r--r--sys/contrib/ncsw/etc/error.c118
-rw-r--r--sys/contrib/ncsw/etc/list.c70
-rw-r--r--sys/contrib/ncsw/etc/mem.h74
-rw-r--r--sys/contrib/ncsw/etc/memcpy.c665
-rw-r--r--sys/contrib/ncsw/etc/mm.c1109
-rw-r--r--sys/contrib/ncsw/etc/mm.h101
-rw-r--r--sys/contrib/ncsw/etc/ncsw_mem.c763
-rw-r--r--sys/contrib/ncsw/etc/sprint.c81
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/bm_ext.h688
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h363
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h206
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/fm_ext.h1347
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h713
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h158
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h2160
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h2196
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h592
-rw-r--r--sys/contrib/ncsw/inc/Peripherals/qm_ext.h1270
-rw-r--r--sys/contrib/ncsw/inc/core_ext.h81
-rw-r--r--sys/contrib/ncsw/inc/cores/e500v2_ext.h413
-rw-r--r--sys/contrib/ncsw/inc/cores/ppc_ext.h130
-rw-r--r--sys/contrib/ncsw/inc/ctype_ext.h93
-rw-r--r--sys/contrib/ncsw/inc/ddr_std_ext.h80
-rw-r--r--sys/contrib/ncsw/inc/debug_ext.h259
-rw-r--r--sys/contrib/ncsw/inc/endian_ext.h446
-rw-r--r--sys/contrib/ncsw/inc/enet_ext.h154
-rw-r--r--sys/contrib/ncsw/inc/error_ext.h553
-rw-r--r--sys/contrib/ncsw/inc/etc/list_ext.h357
-rw-r--r--sys/contrib/ncsw/inc/etc/mem_ext.h317
-rw-r--r--sys/contrib/ncsw/inc/etc/memcpy_ext.h173
-rw-r--r--sys/contrib/ncsw/inc/etc/mm_ext.h300
-rw-r--r--sys/contrib/ncsw/inc/etc/sprint_ext.h130
-rw-r--r--sys/contrib/ncsw/inc/integrations/P2041/dpaa_integration_ext.h349
-rw-r--r--sys/contrib/ncsw/inc/integrations/P2041/part_integration_ext.h758
-rw-r--r--sys/contrib/ncsw/inc/integrations/P3041/dpaa_integration_ext.h371
-rw-r--r--sys/contrib/ncsw/inc/integrations/P3041/part_integration_ext.h995
-rw-r--r--sys/contrib/ncsw/inc/integrations/P5020/dpaa_integration_ext.h374
-rw-r--r--sys/contrib/ncsw/inc/integrations/P5020/part_integration_ext.h1004
-rw-r--r--sys/contrib/ncsw/inc/integrations/part_ext.h84
-rw-r--r--sys/contrib/ncsw/inc/math_ext.h98
-rw-r--r--sys/contrib/ncsw/inc/ncsw_ext.h430
-rw-r--r--sys/contrib/ncsw/inc/net_ext.h388
-rw-r--r--sys/contrib/ncsw/inc/std_ext.h48
-rw-r--r--sys/contrib/ncsw/inc/stdarg_ext.h53
-rw-r--r--sys/contrib/ncsw/inc/stdlib_ext.h166
-rw-r--r--sys/contrib/ncsw/inc/string_ext.h61
-rw-r--r--sys/contrib/ncsw/inc/types_ext.h114
-rw-r--r--sys/contrib/ncsw/inc/types_freebsd.h104
-rw-r--r--sys/contrib/ncsw/inc/xx_ext.h938
-rw-r--r--sys/contrib/ncsw/integrations/P2041/module_strings.c62
-rw-r--r--sys/contrib/ncsw/integrations/P3041/fman_ctrl_code/p3041_r1.0.h1801
-rw-r--r--sys/contrib/ncsw/integrations/P3041/module_strings.c62
-rw-r--r--sys/contrib/ncsw/integrations/P5020/module_strings.c62
-rw-r--r--sys/contrib/ncsw/integrations/fman_ucode.h48
-rw-r--r--sys/contrib/ncsw/user/env/core.c40
-rw-r--r--sys/contrib/ncsw/user/env/stdlib.c35
-rw-r--r--sys/contrib/ncsw/user/env/xx.c949
-rw-r--r--sys/dev/dpaa/bman.c370
-rw-r--r--sys/dev/dpaa/bman.h204
-rw-r--r--sys/dev/dpaa/bman_fdt.c225
-rw-r--r--sys/dev/dpaa/bman_portals.c180
-rw-r--r--sys/dev/dpaa/dpaa.c184
-rw-r--r--sys/dev/dpaa/fman.c357
-rw-r--r--sys/dev/dpaa/fman.h67
-rw-r--r--sys/dev/dpaa/fman_fdt.c104
-rw-r--r--sys/dev/dpaa/if_dtsec.c879
-rw-r--r--sys/dev/dpaa/if_dtsec.h154
-rw-r--r--sys/dev/dpaa/if_dtsec_fdt.c215
-rw-r--r--sys/dev/dpaa/if_dtsec_im.c262
-rw-r--r--sys/dev/dpaa/if_dtsec_im.h41
-rw-r--r--sys/dev/dpaa/if_dtsec_rm.c654
-rw-r--r--sys/dev/dpaa/if_dtsec_rm.h53
-rw-r--r--sys/dev/dpaa/portals.h64
-rw-r--r--sys/dev/dpaa/portals_common.c166
-rw-r--r--sys/dev/dpaa/qman.c555
-rw-r--r--sys/dev/dpaa/qman.h246
-rw-r--r--sys/dev/dpaa/qman_fdt.c221
-rw-r--r--sys/dev/dpaa/qman_portals.c191
-rw-r--r--sys/powerpc/booke/pmap.c3
-rw-r--r--sys/powerpc/conf/dpaa/DPAA101
-rw-r--r--sys/powerpc/conf/dpaa/config.dpaa21
-rw-r--r--sys/powerpc/conf/dpaa/config.p204111
-rw-r--r--sys/powerpc/conf/dpaa/config.p304111
-rw-r--r--sys/powerpc/conf/dpaa/config.p502011
-rw-r--r--sys/powerpc/conf/dpaa/files.dpaa105
-rw-r--r--sys/powerpc/conf/dpaa/files.p20413
-rw-r--r--sys/powerpc/conf/dpaa/files.p30413
-rw-r--r--sys/powerpc/conf/dpaa/files.p50203
-rw-r--r--sys/powerpc/include/intr_machdep.h3
-rw-r--r--sys/powerpc/include/tlb.h5
-rw-r--r--sys/powerpc/powerpc/intr_machdep.c24
142 files changed, 79377 insertions, 6 deletions
diff --git a/share/man/man4/man4.powerpc/dtsec.4 b/share/man/man4/man4.powerpc/dtsec.4
new file mode 100644
index 0000000..a057cb2
--- /dev/null
+++ b/share/man/man4/man4.powerpc/dtsec.4
@@ -0,0 +1,120 @@
+.\"
+.\" Copyright (c) 2016 Justin Hibbits
+.\"
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 28, 2016
+.Dt DTSEC 4
+.Os
+.Sh NAME
+.Nm dtsec
+.Nd "Freescale Datapath Acceleration Architecture-based Three-Speed Ethernet Controller device driver"
+.Sh SYNOPSIS
+To compile this driver into the kernel, place the following lines in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "include ""dpaa/DPAA""
+.Cd "options QORIQ_DPAA"
+.Cd "device dpaa"
+.Cd "device dtsec"
+.Cd "device miibus"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the DPAA-based gigabit Ethernet controller
+integrated in some of the Freescale system-on-chip devices.
+.Pp
+The
+.Nm
+driver supports the following media types:
+.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
+.It autoselect
+Enable autoselection of the media type and options
+.It 10baseT/UTP
+Set 10Mbps operation
+.It 100baseTX
+Set 100Mbps operation
+.It 1000baseT
+Set 1000baseT operation
+.El
+.Pp
+The
+.Nm
+driver supports the following media options:
+.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
+.It full-duplex
+Set full duplex operation
+.El
+.Pp
+The
+.Nm
+driver supports two operating modes:
+.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
+.It Regular
+Normal mode, utilizing the full datapath acceleration, Buffer Manager, and Queue
+Manager.
+.It Independent
+Runs disconnected from the Buffer Manager and Queue Manager.
+.El
+.Sh HARDWARE
+Gigabit Ethernet controllers built into the following Freescale
+system-on-chip devices are known to work with the
+.Nm
+driver:
+.Pp
+.Bl -bullet -compact
+.It
+P2041, P3041
+.It
+P5010, P5020
+.El
+.Sh SEE ALSO
+.Xr altq 4 ,
+.Xr arp 4 ,
+.Xr miibus 4 ,
+.Xr netintro 4 ,
+.Xr ng_ether 4 ,
+.Xr ifconfig 8
+.Sh BUGS
+The
+.Nm
+driver assumes that there is only one Frame Manager, and that dtsec0 controls
+the MDIO interface. Though this is the case for the supported devices, other
+SoCs with the DPAA controller may not work correctly. Particularly, the P5040
+and P4080 SoCs have two frame managers, which breaks this assumption.
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Fx 11.0 .
+.Sh AUTHORS
+.An -nosplit
+The base version of
+.Nm
+device driver was written by
+.An Semihalf .
+This manual page was written by
+.An Justin Hibbits .
diff --git a/sys/contrib/ncsw/Peripherals/BM/bm.c b/sys/contrib/ncsw/Peripherals/BM/bm.c
new file mode 100644
index 0000000..2b31620
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/bm.c
@@ -0,0 +1,815 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+
+ **************************************************************************/
+/******************************************************************************
+ @File bm.c
+
+ @Description BM
+*//***************************************************************************/
+#include "error_ext.h"
+#include "std_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "debug_ext.h"
+#include "mm_ext.h"
+
+#include "bm.h"
+
+
+t_Error BM_ConfigException(t_Handle h_Bm, e_BmExceptions exception, bool enable);
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+
+static volatile bool blockingFlag = FALSE;
+static void BmIpcMsgCompletionCB(t_Handle h_Module,
+ uint8_t *p_Msg,
+ uint8_t *p_Reply,
+ uint32_t replyLength,
+ t_Error status)
+{
+ SANITY_CHECK_RETURN(h_Module, E_INVALID_HANDLE);
+
+#ifdef DISABLE_SANITY_CHECKS
+ UNUSED(h_Module);
+#endif /* DISABLE_SANITY_CHECKS */
+ UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
+
+ blockingFlag = FALSE;
+}
+
+static t_Error BmHandleIpcMsgCB(t_Handle h_Bm,
+ uint8_t *p_Msg,
+ uint32_t msgLength,
+ uint8_t *p_Reply,
+ uint32_t *p_ReplyLength)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+ t_BmIpcMsg *p_IpcMsg = (t_BmIpcMsg*)p_Msg;
+ t_BmIpcReply *p_IpcReply = (t_BmIpcReply *)p_Reply;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
+
+#ifdef DISABLE_SANITY_CHECKS
+ UNUSED(msgLength);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ ASSERT_COND(p_IpcMsg);
+
+ memset(p_IpcReply, 0, (sizeof(uint8_t) * BM_IPC_MAX_REPLY_SIZE));
+ *p_ReplyLength = 0;
+
+ switch(p_IpcMsg->msgId)
+ {
+ case (BM_MASTER_IS_ALIVE):
+ *(uint8_t*)p_IpcReply->replyBody = 1;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ case (BM_SET_POOL_THRESH):
+ {
+ t_Error err;
+ t_BmIpcPoolThreshParams ipcPoolThresh;
+
+ memcpy((uint8_t*)&ipcPoolThresh, p_IpcMsg->msgBody, sizeof(t_BmIpcPoolThreshParams));
+ if ((err = BmSetPoolThresholds(p_Bm,
+ ipcPoolThresh.bpid,
+ ipcPoolThresh.thresholds)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (BM_UNSET_POOL_THRESH):
+ {
+ t_Error err;
+ t_BmIpcPoolThreshParams ipcPoolThresh;
+
+ memcpy((uint8_t*)&ipcPoolThresh, p_IpcMsg->msgBody, sizeof(t_BmIpcPoolThreshParams));
+ if ((err = BmUnSetPoolThresholds(p_Bm,
+ ipcPoolThresh.bpid)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (BM_GET_COUNTER):
+ {
+ t_BmIpcGetCounter ipcCounter;
+ uint32_t count;
+
+ memcpy((uint8_t*)&ipcCounter, p_IpcMsg->msgBody, sizeof(t_BmIpcGetCounter));
+ count = BmGetCounter(p_Bm,
+ (e_BmInterModuleCounters)ipcCounter.enumId,
+ ipcCounter.bpid);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&count, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (BM_GET_REVISION):
+ {
+ t_BmRevisionInfo revInfo;
+ t_BmIpcRevisionInfo ipcRevInfo;
+
+ p_IpcReply->error = (uint32_t)BmGetRevision(h_Bm, &revInfo);
+ ipcRevInfo.majorRev = revInfo.majorRev;
+ ipcRevInfo.minorRev = revInfo.minorRev;
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_BmIpcRevisionInfo));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo);
+ break;
+ }
+ case (BM_FORCE_BPID):
+ {
+ t_BmIpcBpidParams ipcBpid;
+ uint32_t tmp;
+
+ memcpy((uint8_t*)&ipcBpid, p_IpcMsg->msgBody, sizeof(t_BmIpcBpidParams));
+ tmp = BmBpidGet(p_Bm, TRUE, ipcBpid.bpid);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (BM_PUT_BPID):
+ {
+ t_Error err;
+ t_BmIpcBpidParams ipcBpid;
+
+ memcpy((uint8_t*)&ipcBpid, p_IpcMsg->msgBody, sizeof(t_BmIpcBpidParams));
+ if ((err = BmBpidPut(p_Bm, ipcBpid.bpid)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ default:
+ *p_ReplyLength = 0;
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
+ }
+
+ return E_OK;
+}
+
+static t_Error CheckBmParameters(t_Bm *p_Bm)
+{
+ if ((p_Bm->p_BmDriverParams->partBpidBase + p_Bm->p_BmDriverParams->partNumOfPools) > BM_MAX_NUM_OF_POOLS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partBpidBase+partNumOfPools out of range!!!"));
+
+ if (p_Bm->guestId == NCSW_MASTER_ID)
+ {
+ if (!p_Bm->p_BmDriverParams->totalNumOfBuffers)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfBuffers must be larger than '0'!!!"));
+ if (p_Bm->p_BmDriverParams->totalNumOfBuffers > (128*MEGABYTE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfBuffers must be equal or smaller than 128M!!!"));
+ if(!p_Bm->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
+ }
+
+ return E_OK;
+}
+
+static __inline__ uint32_t GenerateThresh(uint32_t val, int roundup)
+{
+ uint32_t e = 0; /* co-efficient, exponent */
+ uint32_t oddbit = 0;
+ while(val > 0xff) {
+ oddbit = val & 1;
+ val >>= 1;
+ e++;
+ if(roundup && oddbit)
+ val++;
+ }
+ return (val | (e << 8));
+}
+
+static t_Error BmSetPool(t_Handle h_Bm,
+ uint8_t bpid,
+ uint32_t swdet,
+ uint32_t swdxt,
+ uint32_t hwdet,
+ uint32_t hwdxt)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE);
+
+ WRITE_UINT32(p_Bm->p_BmRegs->swdet[bpid], GenerateThresh(swdet, 0));
+ WRITE_UINT32(p_Bm->p_BmRegs->swdxt[bpid], GenerateThresh(swdxt, 1));
+ WRITE_UINT32(p_Bm->p_BmRegs->hwdet[bpid], GenerateThresh(hwdet, 0));
+ WRITE_UINT32(p_Bm->p_BmRegs->hwdxt[bpid], GenerateThresh(hwdxt, 1));
+
+ return E_OK;
+}
+
+/****************************************/
+/* Inter-Module functions */
+/****************************************/
+
+t_Error BmSetPoolThresholds(t_Handle h_Bm, uint8_t bpid, const uint32_t *thresholds)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE);
+
+ if (p_Bm->guestId == NCSW_MASTER_ID)
+ {
+ return BmSetPool(h_Bm,
+ bpid,
+ thresholds[0],
+ thresholds[1],
+ thresholds[2],
+ thresholds[3]);
+ }
+ else if (p_Bm->h_Session)
+ {
+ t_BmIpcMsg msg;
+ t_BmIpcPoolThreshParams ipcPoolThresh;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_BmIpcMsg));
+ ipcPoolThresh.bpid = bpid;
+ memcpy(ipcPoolThresh.thresholds, thresholds, sizeof(uintptr_t) * MAX_DEPLETION_THRESHOLDS);
+ msg.msgId = BM_SET_POOL_THRESH;
+ memcpy(msg.msgBody, &ipcPoolThresh, sizeof(t_BmIpcPoolThreshParams));
+ if ((errCode = XX_IpcSendMessage(p_Bm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_BmIpcPoolThreshParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ return E_OK;
+ }
+ else
+ RETURN_ERROR(WARNING, E_NOT_SUPPORTED, ("IPC"));
+}
+
+t_Error BmUnSetPoolThresholds(t_Handle h_Bm, uint8_t bpid)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE);
+
+ if (p_Bm->guestId == NCSW_MASTER_ID)
+ {
+ return BmSetPool(h_Bm,
+ bpid,
+ 0,
+ 0,
+ 0,
+ 0);
+ }
+ else if (p_Bm->h_Session)
+ {
+ t_BmIpcMsg msg;
+ t_BmIpcPoolThreshParams ipcPoolThresh;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_BmIpcMsg));
+ memset(&ipcPoolThresh, 0, sizeof(t_BmIpcPoolThreshParams));
+ ipcPoolThresh.bpid = bpid;
+ msg.msgId = BM_UNSET_POOL_THRESH;
+ memcpy(msg.msgBody, &ipcPoolThresh, sizeof(t_BmIpcPoolThreshParams));
+ if ((errCode = XX_IpcSendMessage(p_Bm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_BmIpcPoolThreshParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ return E_OK;
+ }
+ else
+ RETURN_ERROR(WARNING, E_NOT_SUPPORTED, ("IPC"));
+}
+
+uint32_t BmGetCounter(t_Handle h_Bm, e_BmInterModuleCounters counter, uint8_t bpid)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Bm, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE, 0);
+ SANITY_CHECK_RETURN_VALUE((((p_Bm->guestId == NCSW_MASTER_ID) && p_Bm->p_BmRegs) ||
+ (p_Bm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE, 0);
+
+ if ((p_Bm->guestId == NCSW_MASTER_ID) ||
+ (!p_Bm->h_Session && p_Bm->p_BmRegs))
+ {
+ switch(counter)
+ {
+ case(e_BM_IM_COUNTERS_POOL_CONTENT):
+ return GET_UINT32(p_Bm->p_BmRegs->content[bpid]);
+ case(e_BM_IM_COUNTERS_POOL_SW_DEPLETION):
+ return GET_UINT32(p_Bm->p_BmRegs->sdcnt[bpid]);
+ case(e_BM_IM_COUNTERS_POOL_HW_DEPLETION):
+ return GET_UINT32(p_Bm->p_BmRegs->hdcnt[bpid]);
+ case(e_BM_IM_COUNTERS_FBPR):
+ return GET_UINT32(p_Bm->p_BmRegs->fbpr_fpc);
+ default:
+ break;
+ }
+ /* should never get here */
+ ASSERT_COND(FALSE);
+ }
+ else if (p_Bm->h_Session)
+ {
+ t_BmIpcMsg msg;
+ t_BmIpcReply reply;
+ t_BmIpcGetCounter ipcCounter;
+ uint32_t replyLength;
+ uint32_t count;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_BmIpcMsg));
+ memset(&reply, 0, sizeof(t_BmIpcReply));
+ ipcCounter.bpid = bpid;
+ ipcCounter.enumId = (uint32_t)counter;
+ msg.msgId = BM_GET_COUNTER;
+ memcpy(msg.msgBody, &ipcCounter, sizeof(t_BmIpcGetCounter));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((errCode = XX_IpcSendMessage(p_Bm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_BmIpcGetCounter),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MAJOR, errCode, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ errCode = E_INVALID_VALUE;
+ }
+ if (errCode == E_OK)
+ {
+ memcpy((uint8_t*)&count, reply.replyBody, sizeof(uint32_t));
+ return count;
+ }
+ }
+ else
+ REPORT_ERROR(WARNING, E_NOT_SUPPORTED,
+ ("In 'guest', either IPC or 'baseAddress' is required!"));
+
+ return 0;
+}
+
+t_Error BmGetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmRevisionInfo, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR((((p_Bm->guestId == NCSW_MASTER_ID) && p_Bm->p_BmRegs) ||
+ (p_Bm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE);
+
+ if ((p_Bm->guestId == NCSW_MASTER_ID) ||
+ (!p_Bm->h_Session && p_Bm->p_BmRegs))
+ {
+ /* read revision register 1 */
+ tmpReg = GET_UINT32(p_Bm->p_BmRegs->ip_rev_1);
+ p_BmRevisionInfo->majorRev = (uint8_t)((tmpReg & REV1_MAJOR_MASK) >> REV1_MAJOR_SHIFT);
+ p_BmRevisionInfo->minorRev = (uint8_t)((tmpReg & REV1_MINOR_MASK) >> REV1_MINOR_SHIFT);
+ }
+ else if (p_Bm->h_Session)
+ {
+ t_BmIpcMsg msg;
+ t_BmIpcReply reply;
+ t_BmIpcRevisionInfo ipcRevInfo;
+ uint32_t replyLength;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_BmIpcMsg));
+ memset(&reply, 0, sizeof(t_BmIpcReply));
+ msg.msgId = BM_GET_REVISION;
+ replyLength = sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo);
+ if ((errCode = XX_IpcSendMessage(p_Bm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(t_BmIpcRevisionInfo)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_BmIpcRevisionInfo));
+ p_BmRevisionInfo->majorRev = ipcRevInfo.majorRev;
+ p_BmRevisionInfo->minorRev = ipcRevInfo.minorRev;
+ return (t_Error)(reply.error);
+ }
+ else
+ RETURN_ERROR(WARNING, E_NOT_SUPPORTED,
+ ("In 'guest', either IPC or 'baseAddress' is required!"));
+
+ return E_OK;
+}
+
+static void FreeInitResources(t_Bm *p_Bm)
+{
+ if (p_Bm->p_FbprBase)
+ XX_FreeSmart(p_Bm->p_FbprBase);
+ if (p_Bm->h_Session)
+ XX_IpcFreeSession(p_Bm->h_Session);
+ if (p_Bm->h_BpidMm)
+ MM_Free(p_Bm->h_BpidMm);
+}
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+
+t_Handle BM_Config(t_BmParam *p_BmParam)
+{
+ t_Bm *p_Bm;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmParam, E_INVALID_HANDLE, NULL);
+
+ p_Bm = (t_Bm *)XX_Malloc(sizeof(t_Bm));
+ if (!p_Bm)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("BM obj!!!"));
+ return NULL;
+ }
+ memset(p_Bm, 0, sizeof(t_Bm));
+
+ p_Bm->p_BmDriverParams = (t_BmDriverParams *)XX_Malloc(sizeof(t_BmDriverParams));
+ if (!p_Bm->p_BmDriverParams)
+ {
+ XX_Free(p_Bm);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm driver parameters"));
+ return NULL;
+ }
+ memset(p_Bm->p_BmDriverParams, 0, sizeof(t_BmDriverParams));
+
+ p_Bm->guestId = p_BmParam->guestId;
+ p_Bm->p_BmDriverParams->partNumOfPools = p_BmParam->partNumOfPools;
+ p_Bm->p_BmDriverParams->partBpidBase = p_BmParam->partBpidBase;
+ p_Bm->p_BmRegs = (t_BmRegs *)UINT_TO_PTR(p_BmParam->baseAddress);
+
+ if (p_Bm->guestId == NCSW_MASTER_ID)
+ {
+ p_Bm->exceptions = DEFAULT_exceptions;
+ p_Bm->f_Exception = p_BmParam->f_Exception;
+ p_Bm->h_App = p_BmParam->h_App;
+ p_Bm->errIrq = p_BmParam->errIrq;
+ p_Bm->p_BmDriverParams->totalNumOfBuffers = p_BmParam->totalNumOfBuffers;
+ p_Bm->p_BmDriverParams->fbprMemPartitionId = p_BmParam->fbprMemPartitionId;
+ p_Bm->p_BmDriverParams->fbprThreshold = DEFAULT_fbprThreshold;
+ p_Bm->p_BmDriverParams->liodn = p_BmParam->liodn;
+
+ }
+ /* build the BM partition IPC address */
+ memset(p_Bm->moduleName, 0, MODULE_NAME_SIZE);
+ if(Sprint (p_Bm->moduleName, "BM_0_%d",p_Bm->guestId) != (p_Bm->guestId<10 ? 6:7))
+ {
+ XX_Free(p_Bm->p_BmDriverParams);
+ XX_Free(p_Bm);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ return NULL;
+ }
+ return p_Bm;
+}
+
+t_Error BM_Init(t_Handle h_Bm)
+{
+ t_Bm *p_Bm = (t_Bm *)h_Bm;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE);
+
+ CHECK_INIT_PARAMETERS(p_Bm, CheckBmParameters);
+
+ if (p_Bm->p_BmDriverParams->partNumOfPools)
+ if (MM_Init(&p_Bm->h_BpidMm, p_Bm->p_BmDriverParams->partBpidBase, p_Bm->p_BmDriverParams->partNumOfPools) != E_OK)
+ {
+ FreeInitResources(p_Bm);
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("BM-BPIDS-MEM partition!!!"));
+ }
+
+ if (p_Bm->guestId == NCSW_MASTER_ID)
+ {
+ uint64_t phyAddr;
+ t_BmRevisionInfo revInfo;
+ uint32_t dsSize, exp;
+
+ BmGetRevision(p_Bm, &revInfo);
+ DBG(TRACE, ("Bman ver:%02x,%02x", revInfo.majorRev, revInfo.minorRev));
+
+ WRITE_UINT32(p_Bm->p_BmRegs->liodnr, (uint16_t)p_Bm->p_BmDriverParams->liodn);
+
+ /* FBPR memory */
+ dsSize = (uint32_t)(p_Bm->p_BmDriverParams->totalNumOfBuffers * (FBPR_ENTRY_SIZE / 8));
+ LOG2(dsSize, exp);
+ if (!POWER_OF_2(dsSize)) (exp++);
+ dsSize = (uint32_t)(1 << exp);
+ if (dsSize < (4*KILOBYTE))
+ {
+ dsSize = (4*KILOBYTE);
+ LOG2(dsSize, exp);
+ }
+ p_Bm->p_FbprBase = XX_MallocSmart(dsSize, (int)p_Bm->p_BmDriverParams->fbprMemPartitionId, dsSize);
+ if (!p_Bm->p_FbprBase)
+ {
+ FreeInitResources(p_Bm);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FBPR obj!!!"));
+ }
+ phyAddr = XX_VirtToPhys(p_Bm->p_FbprBase);
+ WRITE_UINT32(p_Bm->p_BmRegs->fbpr_bare, ((uint32_t)(phyAddr >> 32) & 0xffff));
+ WRITE_UINT32(p_Bm->p_BmRegs->fbpr_bar, (uint32_t)phyAddr);
+ WRITE_UINT32(p_Bm->p_BmRegs->fbpr_ar, (exp - 1));
+
+ WRITE_UINT32(p_Bm->p_BmRegs->fbpr_fp_lwit, p_Bm->p_BmDriverParams->fbprThreshold);
+ WRITE_UINT32(p_Bm->p_BmRegs->err_isr, p_Bm->exceptions);
+ WRITE_UINT32(p_Bm->p_BmRegs->err_ier, p_Bm->exceptions);
+ WRITE_UINT32(p_Bm->p_BmRegs->err_isdr, 0x0);
+ if (p_Bm->errIrq != NO_IRQ)
+ {
+ XX_SetIntr(p_Bm->errIrq, BM_ErrorIsr, p_Bm);
+ XX_EnableIntr(p_Bm->errIrq);
+ }
+
+ if ((err = XX_IpcRegisterMsgHandler(p_Bm->moduleName, BmHandleIpcMsgCB, p_Bm, BM_IPC_MAX_REPLY_SIZE)) != E_OK)
+ {
+ FreeInitResources(p_Bm);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+ else /* guest mode */
+ {
+ char masterModuleName[MODULE_NAME_SIZE];
+
+ memset(masterModuleName, 0, MODULE_NAME_SIZE);
+ if(Sprint (masterModuleName, "BM_0_%d", NCSW_MASTER_ID) != (NCSW_MASTER_ID<10 ? 6:7))
+ {
+ FreeInitResources(p_Bm);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ }
+
+ p_Bm->h_Session = XX_IpcInitSession(masterModuleName, p_Bm->moduleName);
+ if (p_Bm->h_Session)
+ {
+ t_BmIpcMsg msg;
+ uint8_t isMasterAlive = 0;
+ t_BmIpcReply reply;
+ uint32_t replyLength;
+
+ memset(&msg, 0, sizeof(t_BmIpcMsg));
+ memset(&reply, 0, sizeof(t_BmIpcReply));
+ msg.msgId = BM_MASTER_IS_ALIVE;
+ replyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ do
+ {
+ blockingFlag = TRUE;
+ if ((err = XX_IpcSendMessage(p_Bm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ BmIpcMsgCompletionCB,
+ p_Bm)) != E_OK)
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ while(blockingFlag) ;
+ if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ isMasterAlive = *(uint8_t*)(reply.replyBody);
+ } while (!isMasterAlive);
+ }
+ }
+
+ XX_Free(p_Bm->p_BmDriverParams);
+ p_Bm->p_BmDriverParams = NULL;
+
+ return E_OK;
+}
+
+t_Error BM_Free(t_Handle h_Bm)
+{
+ t_Bm *p_Bm = (t_Bm *)h_Bm;
+
+ if (!p_Bm)
+ return ERROR_CODE(E_INVALID_HANDLE);
+
+ if (p_Bm->guestId == NCSW_MASTER_ID)
+ {
+ XX_IpcUnregisterMsgHandler(p_Bm->moduleName);
+ if (p_Bm->errIrq != NO_IRQ)
+ {
+ XX_DisableIntr(p_Bm->errIrq);
+ XX_FreeIntr(p_Bm->errIrq);
+ }
+ }
+ FreeInitResources(p_Bm);
+
+ if(p_Bm->p_BmDriverParams)
+ XX_Free(p_Bm->p_BmDriverParams);
+
+ XX_Free(p_Bm);
+ return E_OK;
+}
+
+t_Error BM_ConfigException(t_Handle h_Bm, e_BmExceptions exception, bool enable)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+ uint32_t bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE);
+
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Bm->exceptions |= bitMask;
+ else
+ p_Bm->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+t_Error BM_ConfigFbprThreshold(t_Handle h_Bm, uint32_t threshold)
+{
+ t_Bm *p_Bm = (t_Bm *)h_Bm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Bm->p_BmDriverParams, E_INVALID_HANDLE);
+
+ p_Bm->p_BmDriverParams->fbprThreshold = threshold;
+
+ return E_OK;
+}
+
+void BM_ErrorIsr(t_Handle h_Bm)
+{
+ t_Bm *p_Bm = (t_Bm *)h_Bm;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN(p_Bm, E_INVALID_HANDLE);
+
+ if (p_Bm->guestId != NCSW_MASTER_ID)
+ {
+ REPORT_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only"));
+ return;
+ }
+
+ tmpReg = GET_UINT32(p_Bm->p_BmRegs->err_isr);
+ tmpReg &= GET_UINT32(p_Bm->p_BmRegs->err_ier);
+ WRITE_UINT32(p_Bm->p_BmRegs->err_isr, tmpReg);
+
+ if (tmpReg & BM_EX_INVALID_COMMAND)
+ p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_INVALID_COMMAND);
+ if (tmpReg & BM_EX_FBPR_THRESHOLD)
+ p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_FBPR_THRESHOLD);
+ if (tmpReg & BM_EX_MULTI_ECC)
+ p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_MULTI_ECC);
+ if (tmpReg & BM_EX_SINGLE_ECC)
+ p_Bm->f_Exception(p_Bm->h_App, e_BM_EX_SINGLE_ECC);
+}
+
+uint32_t BM_GetCounter(t_Handle h_Bm, e_BmCounters counter)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Bm, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_Bm->p_BmDriverParams, E_INVALID_STATE, 0);
+
+ switch(counter)
+ {
+ case(e_BM_COUNTERS_FBPR):
+ return BmGetCounter(p_Bm, e_BM_IM_COUNTERS_FBPR, 0);
+ default:
+ break;
+ }
+ /* should never get here */
+ ASSERT_COND(FALSE);
+
+ return 0;
+}
+
+t_Error BM_SetException(t_Handle h_Bm, e_BmExceptions exception, bool enable)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+ uint32_t tmpReg, bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+
+ if (p_Bm->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only"));
+
+ BM_ConfigException(p_Bm, exception, enable);
+
+ tmpReg = GET_UINT32(p_Bm->p_BmRegs->err_ier);
+
+ if(enable)
+ tmpReg |= bitMask;
+ else
+ tmpReg &= ~bitMask;
+ WRITE_UINT32(p_Bm->p_BmRegs->err_ier, tmpReg);
+
+ return E_OK;
+}
+
+t_Error BM_GetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmRevisionInfo, E_NULL_POINTER);
+
+ return BmGetRevision(p_Bm, p_BmRevisionInfo);
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error BM_DumpRegs(t_Handle h_Bm)
+{
+ t_Bm *p_Bm = (t_Bm *)h_Bm;
+
+ DECLARE_DUMP;
+
+ if (p_Bm->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only"));
+
+ SANITY_CHECK_RETURN_ERROR(p_Bm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Bm->p_BmDriverParams, E_INVALID_STATE);
+
+ DUMP_SUBTITLE(("\n"));
+
+ DUMP_TITLE(p_Bm->p_BmRegs, ("BmRegs Regs"));
+
+ DUMP_ARR(p_Bm->p_BmRegs, swdet);
+ DUMP_ARR(p_Bm->p_BmRegs, hwdet);
+ DUMP_ARR(p_Bm->p_BmRegs, swdxt);
+ DUMP_ARR(p_Bm->p_BmRegs, hwdxt);
+ DUMP_ARR(p_Bm->p_BmRegs, sdcnt);
+ DUMP_ARR(p_Bm->p_BmRegs, hdcnt);
+ DUMP_ARR(p_Bm->p_BmRegs, content);
+ DUMP_ARR(p_Bm->p_BmRegs, hdptr);
+
+ DUMP_VAR(p_Bm->p_BmRegs,fbpr_fpc);
+ DUMP_VAR(p_Bm->p_BmRegs,fbpr_fp_lwit);
+
+ DUMP_ARR(p_Bm->p_BmRegs, cmd_pm_cfg);
+ DUMP_ARR(p_Bm->p_BmRegs, fl_pm_cfg);
+ DUMP_VAR(p_Bm->p_BmRegs, ecsr);
+ DUMP_VAR(p_Bm->p_BmRegs, ecir);
+ DUMP_VAR(p_Bm->p_BmRegs, eadr);
+ DUMP_ARR(p_Bm->p_BmRegs, edata);
+ DUMP_VAR(p_Bm->p_BmRegs,sbet);
+ DUMP_VAR(p_Bm->p_BmRegs,efcr);
+ DUMP_VAR(p_Bm->p_BmRegs,efar);
+ DUMP_VAR(p_Bm->p_BmRegs,sbec0);
+ DUMP_VAR(p_Bm->p_BmRegs,sbec1);
+ DUMP_VAR(p_Bm->p_BmRegs,ip_rev_1);
+ DUMP_VAR(p_Bm->p_BmRegs,ip_rev_2);
+ DUMP_VAR(p_Bm->p_BmRegs,fbpr_bare);
+ DUMP_VAR(p_Bm->p_BmRegs,fbpr_bar);
+ DUMP_VAR(p_Bm->p_BmRegs,fbpr_ar);
+ DUMP_VAR(p_Bm->p_BmRegs,srcidr);
+ DUMP_VAR(p_Bm->p_BmRegs,liodnr);
+ DUMP_VAR(p_Bm->p_BmRegs,err_isr);
+ DUMP_VAR(p_Bm->p_BmRegs,err_ier);
+ DUMP_VAR(p_Bm->p_BmRegs,err_isdr);
+ DUMP_VAR(p_Bm->p_BmRegs,err_iir);
+ DUMP_VAR(p_Bm->p_BmRegs,err_ifr);
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
diff --git a/sys/contrib/ncsw/Peripherals/BM/bm.h b/sys/contrib/ncsw/Peripherals/BM/bm.h
new file mode 100644
index 0000000..1573156
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/bm.h
@@ -0,0 +1,453 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File bm.h
+
+ @Description BM header
+*//***************************************************************************/
+#ifndef __BM_H
+#define __BM_H
+
+#include "bm_ext.h"
+#include "mm_ext.h"
+
+#include "bman_private.h"
+#include "bm_ipc.h"
+
+
+#define __ERR_MODULE__ MODULE_BM
+
+#define BM_NUM_OF_POOLS 64
+#define BM_NUM_OF_PM 8
+
+/**************************************************************************//**
+ @Description Exceptions
+*//***************************************************************************/
+#define BM_EX_INVALID_COMMAND 0x00000010
+#define BM_EX_FBPR_THRESHOLD 0x00000008
+#define BM_EX_MULTI_ECC 0x00000004
+#define BM_EX_SINGLE_ECC 0x00000002
+#define BM_EX_POOLS_AVAIL_STATE 0x00000001
+
+#define GET_EXCEPTION_FLAG(bitMask, exception) \
+switch(exception){ \
+ case e_BM_EX_INVALID_COMMAND: \
+ bitMask = BM_EX_INVALID_COMMAND; break; \
+ case e_BM_EX_FBPR_THRESHOLD: \
+ bitMask = BM_EX_FBPR_THRESHOLD; break; \
+ case e_BM_EX_SINGLE_ECC: \
+ bitMask = BM_EX_SINGLE_ECC; break; \
+ case e_BM_EX_MULTI_ECC: \
+ bitMask = BM_EX_MULTI_ECC; break; \
+ default: bitMask = 0;break; \
+}
+
+/**************************************************************************//**
+ @Description defaults
+*//***************************************************************************/
+/* BM defaults */
+#define DEFAULT_exceptions (BM_EX_INVALID_COMMAND |\
+ BM_EX_FBPR_THRESHOLD |\
+ BM_EX_MULTI_ECC |\
+ BM_EX_SINGLE_ECC )
+
+#define DEFAULT_fbprThreshold 0
+/* BM-Portal defaults */
+#define DEFAULT_memAttr MEMORY_ATTR_CACHEABLE
+
+/* BM-Pool defaults */
+#define DEFAULT_dynamicBpid TRUE
+#define DEFAULT_useDepletion FALSE
+#define DEFAULT_useStockpile FALSE
+#define DEFAULT_numOfBufsPerCmd 8
+
+/**************************************************************************//**
+ @Description Memory Mapped Registers
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct
+{
+ /* BMan Buffer Pool Configuration & Status Registers */
+ volatile uint32_t swdet[BM_NUM_OF_POOLS]; /**< S/W Portal depletion entry threshold */
+ volatile uint32_t hwdet[BM_NUM_OF_POOLS]; /**< H/W Portal depletion entry threshold */
+ volatile uint32_t swdxt[BM_NUM_OF_POOLS]; /**< S/W Portal depletion exit threshold */
+ volatile uint32_t hwdxt[BM_NUM_OF_POOLS]; /**< H/W Portal depletion exit threshold */
+ volatile uint32_t sdcnt[BM_NUM_OF_POOLS]; /**< S/W Portal depletion count */
+ volatile uint32_t hdcnt[BM_NUM_OF_POOLS]; /**< H/W Portal depletion count */
+ volatile uint32_t content[BM_NUM_OF_POOLS]; /**< Snapshot of buffer count in Pool */
+ volatile uint32_t hdptr[BM_NUM_OF_POOLS]; /**< Head Pointer for Pool's FBPR list. */
+
+ /* Free Buffer Proxy Record (FBPR) Manager Query Registers */
+ volatile uint32_t fbpr_fpc; /**< FBPR Free Pool Count */
+ volatile uint32_t fbpr_fp_lwit; /**< FBPR Free Pool Low Watermark Interrupt Threshold */
+ volatile uint8_t res1[248]; /**< reserved */
+
+ /* Performance Monitor (PM) Configuration Register */
+ volatile uint32_t cmd_pm_cfg[BM_NUM_OF_PM]; /**< BMan Command Performance Monitor configuration registers. */
+ volatile uint32_t fl_pm_cfg[BM_NUM_OF_PM]; /**< BMan Free List Performance Monitor configuration registers */
+ volatile uint8_t res2[192]; /**< reserved */
+
+ /* BMan Error Capture Registers */
+ volatile uint32_t ecsr; /**< BMan Error Capture Status Register */
+ volatile uint32_t ecir; /**< BMan Error Capture Information Register */
+ volatile uint32_t eadr; /**< BMan Error Capture Address Register */
+ volatile uint8_t res3[4]; /**< reserved */
+ volatile uint32_t edata[8]; /**< BMan ECC Error Data Register */
+ volatile uint32_t sbet; /**< BMan Single Bit ECC Error Threshold Register */
+ volatile uint32_t efcr; /**< BMan Error Fetch Capture Register */
+ volatile uint32_t efar; /**< BMan Error Fetch Address Register */
+ volatile uint8_t res4[68]; /**< reserved */
+ volatile uint32_t sbec0; /**< BMan Single Bit ECC Error Count 0 Register */
+ volatile uint32_t sbec1; /**< BMan Single Bit ECC Error Count 1 Register */
+ volatile uint8_t res5[368]; /**< reserved */
+
+ /* BMan ID/Revision Registers */
+ volatile uint32_t ip_rev_1; /**< BMan IP Block Revision 1 register */
+ volatile uint32_t ip_rev_2; /**< BMan IP Block Revision 2 register */
+
+ /* CoreNet Initiator Interface Memory Window Configuration Registers */
+ volatile uint32_t fbpr_bare; /**< Data Structure Extended Base Address Register */
+ volatile uint32_t fbpr_bar; /**< Data Structure Base Address Register */
+ volatile uint8_t res6[8]; /**< reserved */
+ volatile uint32_t fbpr_ar; /**< Data Structure Attributes Register */
+ volatile uint8_t res7[240]; /**< reserved */
+ volatile uint32_t srcidr; /**< BMan Source ID Register */
+ volatile uint32_t liodnr; /**< BMan Logical I/O Device Number Register */
+ volatile uint8_t res8[244]; /**< reserved */
+
+ /* BMan Interrupt and Error Registers */
+ volatile uint32_t err_isr; /**< BMan Error Interrupt Status Register */
+ volatile uint32_t err_ier; /**< BMan Error Interrupt Enable Register */
+ volatile uint32_t err_isdr; /**< BMan Error Interrupt Status Disable Register */
+ volatile uint32_t err_iir; /**< BMan Error Interrupt Inhibit Register */
+ volatile uint32_t err_ifr; /**< BMan Error Interrupt Force Register */
+} _PackedType t_BmRegs;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+/**************************************************************************//**
+ @Description General defines
+*//***************************************************************************/
+#define MODULE_NAME_SIZE 30
+
+#define FBPR_ENTRY_SIZE 64 /* 64 bytes */
+
+/* Compilation constants */
+#define RCR_THRESH 2 /* reread h/w CI when running out of space */
+#define RCR_ITHRESH 4 /* if RCR congests, interrupt threshold */
+
+/* Lock/unlock portals, subject to "UNLOCKED" flag */
+#define NCSW_PLOCK(p) ((t_BmPortal*)(p))->irq_flags = XX_DisableAllIntr()
+#define PUNLOCK(p) XX_RestoreAllIntr(((t_BmPortal*)(p))->irq_flags)
+
+#define BM_RCR_RING 0
+#define BM_NUM_OF_RINGS 1
+
+/**************************************************************************//**
+ @Description Register defines
+*//***************************************************************************/
+
+/* masks */
+#define REV1_MAJOR_MASK 0x0000FF00
+#define REV1_MINOR_MASK 0x000000FF
+
+#define REV2_INTEG_MASK 0x00FF0000
+#define REV2_ERR_MASK 0x0000FF00
+#define REV2_CFG_MASK 0x000000FF
+
+#define AR_PRIORITY 0x40000000
+#define AR_SIZE_MASK 0x0000003f
+
+/* shifts */
+#define REV1_MAJOR_SHIFT 8
+#define REV1_MINOR_SHIFT 0
+
+#define REV2_INTEG_SHIFT 16
+#define REV2_ERR_SHIFT 8
+#define REV2_CFG_SHIFT 0
+
+#define AR_SIZE_SHIFT 0
+
+typedef uint8_t bmRingType_t;
+typedef uint8_t (t_BmUpdateCb)(struct bm_portal *p_BmPortalLow);
+typedef void (t_BmPrefetchCb)(struct bm_portal *p_BmPortalLow);
+typedef void (t_BmCommitCb)(struct bm_portal *p_BmPortalLow, uint8_t myverb);
+
+typedef struct {
+ bool useStockpile; /**< */
+ bool dynamicBpid; /**< boolean indicates use of dynamic Bpid */
+ bool useDepletion; /**< boolean indicates use of depletion */
+ uint32_t depletionThresholds[MAX_DEPLETION_THRESHOLDS]; /**< depletion-entry/exit thresholds, if useThresholds is set. NB:
+ this is only allowed if useThresholds is used and
+ when run in the control plane (which controls Bman CCSR) */
+} t_BmPoolDriverParams;
+
+typedef struct BmPool {
+ uint8_t bpid; /**< index of the buffer pool to encapsulate (0-63) */
+ t_Handle h_Bm;
+ t_Handle h_BmPortal;
+ bool shadowMode;
+ uint32_t numOfBuffers; /**< Number of buffers use by this pool */
+ t_BufferPoolInfo bufferPoolInfo; /**< Data buffers pool information */
+ uint32_t flags; /**< bit-mask of BMAN_POOL_FLAG_*** options */
+ t_Handle h_App; /**< opaque user value passed as a parameter to 'cb' */
+ t_BmDepletionCallback *f_Depletion; /**< depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
+ uint32_t swDepletionCount;
+ uint32_t hwDepletionCount;
+ /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
+ struct bm_buffer *sp;
+ uint16_t spFill;
+ uint8_t spBufsCmd;
+ uint16_t spMaxBufs;
+ uint16_t spMinBufs;
+ bool noBuffCtxt;
+
+ t_BmPoolDriverParams *p_BmPoolDriverParams;
+} t_BmPool;
+
+typedef struct {
+ t_BmUpdateCb *f_BmUpdateCb;
+ t_BmPrefetchCb *f_BmPrefetchCb;
+ t_BmCommitCb *f_BmCommitCb;
+} t_BmPortalCallbacks;
+
+typedef struct {
+ uint32_t hwExtStructsMemAttr;
+ struct bman_depletion mask;
+} t_BmPortalDriverParams;
+
+typedef struct {
+ t_Handle h_Bm;
+ struct bm_portal *p_BmPortalLow;
+ t_BmPortalCallbacks cbs[BM_NUM_OF_RINGS];
+ int irq;
+ int cpu; /* This is used for any "core-affine" portals, ie. default portals
+ * associated to the corresponding cpu. -1 implies that there is no core
+ * affinity configured. */
+ struct bman_depletion pools[2]; /**< 2-element array. pools[0] is mask, pools[1] is snapshot. */
+ uint32_t flags; /**< BMAN_PORTAL_FLAG_*** - static, caller-provided */
+ uint32_t irq_flags;
+ int thresh_set;
+ uint32_t slowpoll;
+ uint32_t rcrProd; /**< The wrap-around rcr_[prod|cons] counters are used to support BMAN_RELEASE_FLAG_WAIT_SYNC. */
+ uint32_t rcrCons;
+ /**< 64-entry hash-table of pool objects that are tracking depletion
+ * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
+ * we're not fussy about cache-misses and so forth - whereas the above
+ * members should all fit in one cacheline.
+ * BTW, with BM_MAX_NUM_OF_POOLS entries in the hash table and BM_MAX_NUM_OF_POOLS buffer pools to track,
+ * you'll never guess the hash-function ... */
+ t_BmPool *depletionPoolsTable[BM_MAX_NUM_OF_POOLS];
+ t_BmPortalDriverParams *p_BmPortalDriverParams;
+} t_BmPortal;
+
+typedef struct {
+ uint8_t partBpidBase;
+ uint8_t partNumOfPools;
+ uint32_t totalNumOfBuffers; /**< total number of buffers */
+ uint32_t fbprMemPartitionId;
+ uint32_t fbprThreshold;
+ uint16_t liodn;
+} t_BmDriverParams;
+
+typedef struct {
+ uint8_t guestId;
+ t_Handle h_BpidMm;
+ t_Handle h_SpinLock;
+ t_Handle h_Portals[DPAA_MAX_NUM_OF_SW_PORTALS];
+ t_Handle h_Session;
+ char moduleName[MODULE_NAME_SIZE];
+ t_BmRegs *p_BmRegs;
+ void *p_FbprBase;
+ uint32_t exceptions;
+ t_BmExceptionsCallback *f_Exception;
+ t_Handle h_App;
+ int errIrq; /**< error interrupt line; NO_IRQ if interrupts not used */
+ t_BmDriverParams *p_BmDriverParams;
+} t_Bm;
+
+static __inline__ void BmSetPortalHandle(t_Handle h_Bm, t_Handle h_Portal, e_DpaaSwPortal portalId)
+{
+ ASSERT_COND(!((t_Bm*)h_Bm)->h_Portals[portalId] || !h_Portal);
+ ((t_Bm*)h_Bm)->h_Portals[portalId] = h_Portal;
+}
+
+static __inline__ t_Handle BmGetPortalHandle(t_Handle h_Bm)
+{
+ t_Bm *p_Bm = (t_Bm*)h_Bm;
+ ASSERT_COND(p_Bm);
+ return p_Bm->h_Portals[CORE_GetId()];
+}
+
+static __inline__ uint8_t BmUpdate(t_BmPortal *p_BmPortal, bmRingType_t type)
+{
+ return p_BmPortal->cbs[type].f_BmUpdateCb(p_BmPortal->p_BmPortalLow);
+}
+
+static __inline__ void BmPrefetch(t_BmPortal *p_BmPortal, bmRingType_t type)
+{
+ if (p_BmPortal->cbs[type].f_BmPrefetchCb)
+ p_BmPortal->cbs[type].f_BmPrefetchCb(p_BmPortal->p_BmPortalLow);
+}
+
+static __inline__ void BmCommit(t_BmPortal *p_BmPortal, bmRingType_t type, uint8_t myverb)
+{
+ p_BmPortal->cbs[type].f_BmCommitCb(p_BmPortal->p_BmPortalLow, myverb);
+}
+
+static __inline__ uint32_t BmBpidGet(t_Bm *p_Bm, bool force, uint32_t base)
+{
+ uint64_t ans, size = 1;
+ uint32_t alignment = 1;
+
+ if (force)
+ {
+ if (MM_InRange(p_Bm->h_BpidMm, (uint64_t)base))
+ {
+ ans = MM_GetForce(p_Bm->h_BpidMm,
+ base,
+ (int)size,
+ "BM BPID MEM");
+ ans = base;
+ }
+ else if (p_Bm->h_Session)
+ {
+ t_BmIpcMsg msg;
+ t_BmIpcReply reply;
+ uint32_t replyLength;
+ t_BmIpcBpidParams ipcBpid;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_BmIpcMsg));
+ memset(&reply, 0, sizeof(t_BmIpcReply));
+ ipcBpid.bpid = (uint8_t)base;
+ msg.msgId = BM_FORCE_BPID;
+ memcpy(msg.msgBody, &ipcBpid, sizeof(t_BmIpcBpidParams));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((errCode = XX_IpcSendMessage(p_Bm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_BmIpcBpidParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ {
+ REPORT_ERROR(MAJOR, errCode, NO_MSG);
+ return (uint32_t)ILLEGAL_BASE;
+ }
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return (uint32_t)ILLEGAL_BASE;
+ }
+ memcpy((uint8_t*)&ans, reply.replyBody, sizeof(uint32_t));
+ }
+ else
+ {
+ DBG(WARNING, ("No Ipc - can't validate bpid."));
+ ans = base;
+ }
+ }
+ else
+ ans = MM_Get(p_Bm->h_BpidMm,
+ size,
+ alignment,
+ "BM BPID MEM");
+ return (uint32_t)ans;
+}
+
+static __inline__ t_Error BmBpidPut(t_Bm *p_Bm, uint32_t base)
+{
+ if (MM_InRange(p_Bm->h_BpidMm, (uint64_t)base))
+ {
+ if (MM_Put(p_Bm->h_BpidMm, (uint64_t)base) != base)
+ return E_OK;
+ else
+ return ERROR_CODE(E_NOT_FOUND);
+ }
+ else if (p_Bm->h_Session)
+ {
+ t_BmIpcMsg msg;
+ t_BmIpcBpidParams ipcBpid;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_BmIpcMsg));
+ ipcBpid.bpid = (uint8_t)base;
+ msg.msgId = BM_PUT_BPID;
+ memcpy(msg.msgBody, &ipcBpid, sizeof(t_BmIpcBpidParams));
+ if ((errCode = XX_IpcSendMessage(p_Bm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_BmIpcBpidParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ }
+ else
+ DBG(WARNING, ("No Ipc - can't validate bpid."));
+ return E_OK;
+}
+
+/****************************************/
+/* Inter-Module functions */
+/****************************************/
+typedef enum e_BmInterModuleCounters {
+ e_BM_IM_COUNTERS_FBPR = 0,
+ e_BM_IM_COUNTERS_POOL_CONTENT,
+ e_BM_IM_COUNTERS_POOL_SW_DEPLETION,
+ e_BM_IM_COUNTERS_POOL_HW_DEPLETION
+} e_BmInterModuleCounters;
+
+
+t_Error BmSetPoolThresholds(t_Handle h_Bm, uint8_t bpid, const uint32_t *thresholds);
+t_Error BmUnSetPoolThresholds(t_Handle h_Bm, uint8_t bpid);
+uint8_t BmPortalAcquire(t_Handle h_BmPortal, uint8_t bpid, struct bm_buffer *bufs, uint8_t num);
+t_Error BmPortalRelease(t_Handle h_BmPortal, uint8_t bpid, struct bm_buffer *bufs, uint8_t num, uint32_t flags);
+t_Error BmPortalQuery(t_Handle h_BmPortal, struct bman_depletion *p_Pools, bool depletion);
+uint32_t BmGetCounter(t_Handle h_Bm, e_BmInterModuleCounters counter, uint8_t bpid);
+t_Error BmGetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo);
+
+
+#endif /* __BM_H */
diff --git a/sys/contrib/ncsw/Peripherals/BM/bm_ipc.h b/sys/contrib/ncsw/Peripherals/BM/bm_ipc.h
new file mode 100644
index 0000000..3adfb04
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/bm_ipc.h
@@ -0,0 +1,125 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/**************************************************************************//**
+ @File bm_ipc.h
+
+ @Description BM Inter-Partition prototypes, structures and definitions.
+*//***************************************************************************/
+#ifndef __BM_IPC_H
+#define __BM_IPC_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group BM_grp Frame Manager API
+
+ @Description BM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group BM_IPC_grp BM Inter-Partition messaging Unit
+
+ @Description BM Inter-Partition messaging unit API definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+#define BM_SET_POOL_THRESH 1
+#define BM_UNSET_POOL_THRESH 2
+#define BM_GET_COUNTER 3
+#define BM_GET_REVISION 4
+#define BM_FORCE_BPID 5
+#define BM_PUT_BPID 6
+#define BM_MASTER_IS_ALIVE 7
+
+#define BM_IPC_MAX_REPLY_BODY_SIZE 16
+#define BM_IPC_MAX_REPLY_SIZE (BM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
+#define BM_IPC_MAX_MSG_SIZE 30
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct t_BmIpcMsg
+{
+ uint32_t msgId;
+ uint8_t msgBody[BM_IPC_MAX_MSG_SIZE];
+} _PackedType t_BmIpcMsg;
+
+typedef _Packed struct t_BmIpcReply
+{
+ uint32_t error;
+ uint8_t replyBody[BM_IPC_MAX_REPLY_BODY_SIZE];
+} _PackedType t_BmIpcReply;
+
+typedef _Packed struct t_BmIpcPoolThreshParams
+{
+ uint8_t bpid; /**< IN */
+ uint32_t thresholds[MAX_DEPLETION_THRESHOLDS]; /**< IN */
+} _PackedType t_BmIpcPoolThreshParams;
+
+typedef _Packed struct t_BmIpcGetCounter
+{
+ uint8_t bpid; /**< IN */
+ uint32_t enumId; /**< IN */
+} _PackedType t_BmIpcGetCounter;
+
+typedef _Packed struct t_BmIpcBpidParams
+{
+ uint8_t bpid; /**< IN */
+} _PackedType t_BmIpcBpidParams;
+
+typedef _Packed struct t_BmIpcRevisionInfo {
+ uint8_t majorRev; /**< Major revision */
+ uint8_t minorRev; /**< Minor revision */
+} _PackedType t_BmIpcRevisionInfo;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+/** @} */ /* end of BM_IPC_grp group */
+/** @} */ /* end of BM_grp group */
+
+
+#endif /* __BM_IPC_H */
diff --git a/sys/contrib/ncsw/Peripherals/BM/bm_pool.c b/sys/contrib/ncsw/Peripherals/BM/bm_pool.c
new file mode 100644
index 0000000..d7a38c2
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/bm_pool.c
@@ -0,0 +1,593 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File bm.c
+
+ @Description BM
+*//***************************************************************************/
+#include "error_ext.h"
+#include "std_ext.h"
+#include "string_ext.h"
+#include "mem_ext.h"
+#include "core_ext.h"
+
+#include "bm.h"
+
+
+#define __ERR_MODULE__ MODULE_BM
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+
+/* (De)Registration of depletion notification callbacks */
+static void depletion_link(t_BmPool *p_BmPool)
+{
+ t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
+
+ NCSW_PLOCK(p_Portal);
+ p_Portal->depletionPoolsTable[p_BmPool->bpid] = p_BmPool;
+ bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 1);
+ PUNLOCK(p_Portal);
+}
+
+static void depletion_unlink(t_BmPool *p_BmPool)
+{
+ t_BmPortal *p_Portal = (t_BmPortal *)p_BmPool->h_BmPortal;
+
+ NCSW_PLOCK(p_Portal);
+ p_Portal->depletionPoolsTable[p_BmPool->bpid] = NULL;
+ bm_isr_bscn_mask(p_Portal->p_BmPortalLow, (uint8_t)p_BmPool->bpid, 0);
+ PUNLOCK(p_Portal);
+}
+
+static t_Error BmPoolRelease(t_BmPool *p_BmPool,
+ t_Handle h_BmPortal,
+ struct bm_buffer *bufs,
+ uint8_t num,
+ uint32_t flags)
+{
+ ASSERT_COND(num && (num <= 8));
+ if (p_BmPool->flags & BMAN_POOL_FLAG_NO_RELEASE)
+ return ERROR_CODE(E_INVALID_VALUE);
+
+ /* Without stockpile, this API is a pass-through to the h/w operation */
+ if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
+ return BmPortalRelease(h_BmPortal, p_BmPool->bpid, bufs, num, flags);
+
+ /* This needs some explanation. Adding the given buffers may take the
+ * stockpile over the threshold, but in fact the stockpile may already
+ * *be* over the threshold if a previous release-to-hw attempt had
+ * failed. So we have 3 cases to cover;
+ * 1. we add to the stockpile and don't hit the threshold,
+ * 2. we add to the stockpile, hit the threshold and release-to-hw,
+ * 3. we have to release-to-hw before adding to the stockpile
+ * (not enough room in the stockpile for case 2).
+ * Our constraints on thresholds guarantee that in case 3, there must be
+ * at least 8 bufs already in the stockpile, so all release-to-hw ops
+ * are for 8 bufs. Despite all this, the API must indicate whether the
+ * given buffers were taken off the caller's hands, irrespective of
+ * whether a release-to-hw was attempted. */
+ while (num)
+ {
+ /* Add buffers to stockpile if they fit */
+ if ((p_BmPool->spFill + num) <= p_BmPool->spMaxBufs)
+ {
+ memcpy(PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
+ bufs,
+ sizeof(struct bm_buffer) * num);
+ p_BmPool->spFill += num;
+ num = 0; /* --> will return success no matter what */
+ }
+ else
+ /* Do hw op if hitting the high-water threshold */
+ {
+ t_Error ret = BmPortalRelease(h_BmPortal,
+ p_BmPool->bpid,
+ (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - p_BmPool->spBufsCmd)),
+ p_BmPool->spBufsCmd,
+ flags);
+ if (ret)
+ return (num ? ret : E_OK);
+ p_BmPool->spFill -= p_BmPool->spBufsCmd;
+ }
+ }
+
+ return E_OK;
+}
+
+static int BmPoolAcquire(t_BmPool *p_BmPool,t_Handle h_BmPortal,
+ struct bm_buffer *bufs, uint8_t num, uint32_t flags)
+{
+ ASSERT_COND(IN_RANGE(1, num, 8));
+ if (p_BmPool->flags & BMAN_POOL_FLAG_ONLY_RELEASE)
+ return 0;
+
+ /* Without stockpile, this API is a pass-through to the h/w operation */
+ if (!(p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE))
+ return BmPortalAcquire(h_BmPortal, p_BmPool->bpid, bufs, num);
+ /* Only need a h/w op if we'll hit the low-water thresh */
+ if (!(flags & BMAN_ACQUIRE_FLAG_STOCKPILE) &&
+ ((p_BmPool->spFill - num) < p_BmPool->spMinBufs))
+ {
+ p_BmPool->spFill += BmPortalAcquire(h_BmPortal,
+ p_BmPool->bpid,
+ (struct bm_buffer *)PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill)),
+ p_BmPool->spBufsCmd);
+ }
+ else if (p_BmPool->spFill < num)
+ return 0;
+ if (!p_BmPool->spFill)
+ return 0;
+ memcpy(bufs,
+ PTR_MOVE(p_BmPool->sp, sizeof(struct bm_buffer) * (p_BmPool->spFill - num)),
+ sizeof(struct bm_buffer) * num);
+ p_BmPool->spFill -= num;
+ return num;
+}
+
+static t_Error BmPoolFree(t_BmPool *p_BmPool, bool discardBuffers)
+{
+ t_Handle h_BufContext;
+ void *p_Data;
+
+ ASSERT_COND(p_BmPool);
+
+ if (!p_BmPool->shadowMode)
+ {
+ if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
+ {
+ depletion_unlink(p_BmPool);
+ BmUnSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid);
+ }
+ while (TRUE)
+ {
+ p_Data = BM_POOL_GetBuf(p_BmPool, p_BmPool->h_BmPortal);
+ if (!p_Data)
+ break;
+ h_BufContext = BM_POOL_GetBufferContext(p_BmPool, p_Data);
+ if (!discardBuffers)
+ p_BmPool->bufferPoolInfo.f_PutBuf(p_BmPool->bufferPoolInfo.h_BufferPool, p_Data, h_BufContext);
+ }
+ BmBpidPut(p_BmPool->h_Bm, p_BmPool->bpid);
+ }
+
+ if (p_BmPool->sp)
+ XX_Free(p_BmPool->sp);
+
+ XX_Free(p_BmPool);
+
+ return E_OK;
+}
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+
+t_Handle BM_POOL_Config(t_BmPoolParam *p_BmPoolParam)
+{
+ t_BmPool *p_BmPool;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPoolParam, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_BmPoolParam->h_Bm, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE((p_BmPoolParam->shadowMode ||
+ (p_BmPoolParam->bufferPoolInfo.h_BufferPool &&
+ p_BmPoolParam->bufferPoolInfo.f_GetBuf &&
+ p_BmPoolParam->bufferPoolInfo.f_PutBuf &&
+ p_BmPoolParam->bufferPoolInfo.bufferSize)), E_INVALID_STATE, NULL);
+
+ p_BmPool = (t_BmPool*)XX_Malloc(sizeof(t_BmPool));
+ if (!p_BmPool)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("BM Pool obj!!!"));
+ return NULL;
+ }
+ memset(p_BmPool, 0, sizeof(t_BmPool));
+
+ p_BmPool->p_BmPoolDriverParams = (t_BmPoolDriverParams *)XX_Malloc(sizeof(t_BmPoolDriverParams));
+ if (!p_BmPool->p_BmPoolDriverParams)
+ {
+ XX_Free(p_BmPool);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool driver parameters"));
+ return NULL;
+ }
+ memset(p_BmPool->p_BmPoolDriverParams, 0, sizeof(t_BmPoolDriverParams));
+
+ p_BmPool->h_Bm = p_BmPoolParam->h_Bm;
+ p_BmPool->h_BmPortal = p_BmPoolParam->h_BmPortal;
+ p_BmPool->h_App = p_BmPoolParam->h_App;
+ p_BmPool->numOfBuffers = p_BmPoolParam->numOfBuffers;
+ p_BmPool->shadowMode = p_BmPoolParam->shadowMode;
+
+ if (!p_BmPool->h_BmPortal)
+ {
+ p_BmPool->h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
+ SANITY_CHECK_RETURN_VALUE(p_BmPool->h_BmPortal, E_INVALID_HANDLE, NULL);
+ }
+
+ memcpy(&p_BmPool->bufferPoolInfo, &p_BmPoolParam->bufferPoolInfo, sizeof(t_BufferPoolInfo));
+ if (!p_BmPool->bufferPoolInfo.f_PhysToVirt)
+ p_BmPool->bufferPoolInfo.f_PhysToVirt = XX_PhysToVirt;
+ if (!p_BmPool->bufferPoolInfo.f_VirtToPhys)
+ p_BmPool->bufferPoolInfo.f_VirtToPhys = XX_VirtToPhys;
+
+ p_BmPool->p_BmPoolDriverParams->dynamicBpid = DEFAULT_dynamicBpid;
+ p_BmPool->p_BmPoolDriverParams->useDepletion = DEFAULT_useDepletion;
+ p_BmPool->p_BmPoolDriverParams->useStockpile = DEFAULT_useStockpile;
+
+ if (p_BmPool->shadowMode)
+ {
+ p_BmPool->numOfBuffers = 0;
+ BM_POOL_ConfigBpid(p_BmPool, p_BmPoolParam->bpid);
+ }
+
+ return p_BmPool;
+}
+
+t_Error BM_POOL_Init(t_Handle h_BmPool)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
+
+ p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->dynamicBpid)?BMAN_POOL_FLAG_DYNAMIC_BPID:0;
+ p_BmPool->flags |= (p_BmPool->p_BmPoolDriverParams->useStockpile)?BMAN_POOL_FLAG_STOCKPILE:0;
+ p_BmPool->flags |= ((!p_BmPool->shadowMode) &&
+ (p_BmPool->p_BmPoolDriverParams->useDepletion))?BMAN_POOL_FLAG_DEPLETION:0;
+
+ if (p_BmPool->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
+ {
+ if((p_BmPool->bpid = (uint8_t)BmBpidGet(p_BmPool->h_Bm, FALSE, (uint32_t)0)) == (uint8_t)ILLEGAL_BASE)
+ {
+ BM_POOL_Free(p_BmPool);
+ RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't allocate new dynamic pool id"));
+ }
+ }
+ else
+ {
+ if (BmBpidGet(p_BmPool->h_Bm, TRUE, (uint32_t)p_BmPool->bpid) == (uint32_t)ILLEGAL_BASE)
+ {
+ BM_POOL_Free(p_BmPool);
+ RETURN_ERROR(CRITICAL, E_INVALID_STATE, ("can't force pool id %d", p_BmPool->bpid));
+ }
+ }
+ if (p_BmPool->flags & BMAN_POOL_FLAG_DEPLETION)
+ {
+ if(BmSetPoolThresholds(p_BmPool->h_Bm, p_BmPool->bpid, p_BmPool->p_BmPoolDriverParams->depletionThresholds))
+ {
+ BM_POOL_Free(p_BmPool);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can't set thresh for pool bpid %d",p_BmPool->bpid));
+ }
+
+ depletion_link(p_BmPool);
+ }
+
+ if (p_BmPool->flags & BMAN_POOL_FLAG_STOCKPILE)
+ {
+ p_BmPool->sp = (struct bm_buffer *)XX_Malloc(sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
+ if (!p_BmPool->sp)
+ {
+ BM_POOL_Free(p_BmPool);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Bm Pool Stockpile"));
+ }
+ memset(p_BmPool->sp, 0, sizeof(struct bm_buffer) * p_BmPool->spMaxBufs);
+ }
+
+ XX_Free(p_BmPool->p_BmPoolDriverParams);
+ p_BmPool->p_BmPoolDriverParams = NULL;
+
+ /*******************/
+ /* Create buffers */
+ /*******************/
+ if ((err = BM_POOL_FillBufs (p_BmPool, p_BmPool->h_BmPortal, p_BmPool->numOfBuffers)) != E_OK)
+ {
+ BM_POOL_Free(p_BmPool);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+t_Error BM_POOL_Free(t_Handle h_BmPool)
+{
+ SANITY_CHECK_RETURN_ERROR(h_BmPool, E_INVALID_HANDLE);
+
+ return BmPoolFree(h_BmPool, FALSE);
+}
+
+t_Error BM_POOL_ConfigBpid(t_Handle h_BmPool, uint8_t bpid)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(bpid < BM_MAX_NUM_OF_POOLS, E_INVALID_VALUE);
+
+ p_BmPool->p_BmPoolDriverParams->dynamicBpid = FALSE;
+ p_BmPool->bpid = bpid;
+
+ return E_OK;
+}
+
+
+t_Error BM_POOL_ConfigDepletion(t_Handle h_BmPool, t_BmDepletionCallback *f_Depletion, uint32_t *p_Thresholds)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(f_Depletion, E_INVALID_HANDLE);
+
+ p_BmPool->p_BmPoolDriverParams->useDepletion = TRUE;
+ p_BmPool->f_Depletion = f_Depletion;
+ memcpy(&p_BmPool->p_BmPoolDriverParams->depletionThresholds,
+ p_Thresholds,
+ sizeof(p_BmPool->p_BmPoolDriverParams->depletionThresholds));
+
+ return E_OK;
+}
+
+t_Error BM_POOL_ConfigStockpile(t_Handle h_BmPool, uint16_t maxBuffers, uint16_t minBuffers)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(maxBuffers, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(maxBuffers >= minBuffers, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR((p_BmPool->shadowMode ||
+ ((maxBuffers * 2) <= p_BmPool->numOfBuffers)),
+ E_INVALID_STATE);
+
+ p_BmPool->p_BmPoolDriverParams->useStockpile = TRUE;
+ p_BmPool->spMaxBufs = maxBuffers;
+ p_BmPool->spMinBufs = minBuffers;
+ p_BmPool->spBufsCmd = DEFAULT_numOfBufsPerCmd;
+
+ SANITY_CHECK_RETURN_ERROR((p_BmPool->spMaxBufs >=
+ (p_BmPool->spMinBufs + p_BmPool->spBufsCmd)),
+ E_INVALID_STATE);
+
+ return E_OK;
+}
+
+t_Error BM_POOL_ConfigBuffContextMode(t_Handle h_BmPool, bool en)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE);
+
+ p_BmPool->noBuffCtxt = !en;
+
+ return E_OK;
+}
+
+void * BM_POOL_GetBuf(t_Handle h_BmPool, t_Handle h_BmPortal)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+ struct bm_buffer bufs[1];
+ uint8_t retBufsNum;
+ uint64_t physAddr;
+ uint32_t flags = 0;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_BmPool->bufferPoolInfo.f_PhysToVirt, E_INVALID_STATE, NULL);
+
+ if (!h_BmPortal)
+ {
+ if (p_BmPool->h_BmPortal)
+ h_BmPortal = p_BmPool->h_BmPortal;
+ else
+ {
+ SANITY_CHECK_RETURN_VALUE(p_BmPool->h_Bm, E_INVALID_HANDLE, NULL);
+ h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
+ SANITY_CHECK_RETURN_VALUE(h_BmPortal, E_INVALID_HANDLE, NULL);
+ }
+ }
+
+ retBufsNum = (uint8_t)BmPoolAcquire(p_BmPool, h_BmPortal, bufs, 1, flags);
+ if (!retBufsNum)
+ {
+ REPORT_ERROR(TRACE, E_NOT_AVAILABLE, ("buffer"));
+ return NULL;
+ }
+ physAddr = (uint64_t)bufs[0].lo;
+ physAddr |= (uint64_t)(((uint64_t)bufs[0].hi << 32) & 0x000000ff00000000LL);
+ DBG(TRACE,("Get Buffer : poolId %d, address 0x%016llx",
+ p_BmPool->bpid,
+ p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr)));
+
+ return p_BmPool->bufferPoolInfo.f_PhysToVirt((physAddress_t)physAddr);
+}
+
+t_Error BM_POOL_PutBuf(t_Handle h_BmPool, t_Handle h_BmPortal, void *p_Buff)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+ uint64_t physAddress;
+ struct bm_buffer bufs[1];
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_Buff, E_NULL_POINTER);
+
+ physAddress = (uint64_t)(XX_VirtToPhys(p_Buff));
+
+ bufs[0].bpid = p_BmPool->bpid;
+ bufs[0].hi = (uint8_t)((physAddress & 0x000000ff00000000LL) >> 32);
+ bufs[0].lo = (uint32_t)(physAddress & 0xffffffff);
+
+ DBG(TRACE,("Put Buffer : poolId %d, address 0x%016llx, phys 0x%016llx",
+ p_BmPool->bpid, (uint64_t)PTR_TO_UINT(p_Buff), physAddress));
+
+ if (!h_BmPortal)
+ {
+ if (p_BmPool->h_BmPortal)
+ h_BmPortal = p_BmPool->h_BmPortal;
+ else
+ {
+ SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
+ h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
+ SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
+ }
+ }
+
+ return BmPoolRelease(p_BmPool, h_BmPortal, bufs, 1, BMAN_RELEASE_FLAG_WAIT);
+}
+
+t_Error BM_POOL_FillBufs(t_Handle h_BmPool, t_Handle h_BmPortal, uint32_t numBufs)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPool, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_BmPool->p_BmPoolDriverParams, E_INVALID_STATE);
+
+ if (!h_BmPortal)
+ {
+ if (p_BmPool->h_BmPortal)
+ h_BmPortal = p_BmPool->h_BmPortal;
+ else
+ {
+ SANITY_CHECK_RETURN_ERROR(p_BmPool->h_Bm, E_INVALID_HANDLE);
+ h_BmPortal = BmGetPortalHandle(p_BmPool->h_Bm);
+ SANITY_CHECK_RETURN_ERROR(h_BmPortal, E_INVALID_HANDLE);
+ }
+ }
+
+ while (numBufs--)
+ {
+ uint8_t *p_Data;
+ t_Error res;
+ t_Handle h_BufContext;
+
+ p_Data = p_BmPool->bufferPoolInfo.f_GetBuf(p_BmPool->bufferPoolInfo.h_BufferPool, &h_BufContext);
+ if(!p_Data)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("run-out of buffers for bpid %d",p_BmPool->bpid));
+
+ if (!p_BmPool->noBuffCtxt)
+ *(t_Handle *)(p_Data - sizeof(t_Handle)) = h_BufContext;
+
+ if ((res = BM_POOL_PutBuf(p_BmPool, h_BmPortal, p_Data)) != E_OK)
+ RETURN_ERROR(CRITICAL, res, ("Seeding reserved buffer pool failed"));
+ }
+
+ return E_OK;
+}
+
+uint8_t BM_POOL_GetId(t_Handle h_BmPool)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
+
+ return p_BmPool->bpid;
+}
+
+uint16_t BM_POOL_GetBufferSize(t_Handle h_BmPool)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
+
+ return p_BmPool->bufferPoolInfo.bufferSize;
+}
+
+t_Handle BM_POOL_GetBufferContext(t_Handle h_BmPool, void *p_Buff)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_Buff, E_NULL_POINTER, NULL);
+
+ if (p_BmPool->noBuffCtxt)
+ return NULL;
+
+ return *(t_Handle *)PTR_MOVE(p_Buff, -(sizeof(t_Handle)));
+}
+
+void * BM_POOL_PhysToVirt(t_Handle h_BmPool, physAddress_t addr)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, NULL);
+
+ return p_BmPool->bufferPoolInfo.f_PhysToVirt(addr);
+}
+
+physAddress_t BM_POOL_VirtToPhys(t_Handle h_BmPool, void *p_Buff)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, (physAddress_t)0);
+ SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, (physAddress_t)0);
+
+ return p_BmPool->bufferPoolInfo.f_VirtToPhys(p_Buff);
+}
+
+uint32_t BM_POOL_GetCounter(t_Handle h_BmPool, e_BmPoolCounters counter)
+{
+ t_BmPool *p_BmPool = (t_BmPool *)h_BmPool;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPool, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_BmPool->p_BmPoolDriverParams, E_INVALID_HANDLE, 0);
+
+ switch(counter)
+ {
+ case(e_BM_POOL_COUNTERS_CONTENT):
+ return BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_CONTENT, p_BmPool->bpid);
+ case(e_BM_POOL_COUNTERS_SW_DEPLETION):
+ return (p_BmPool->swDepletionCount +=
+ BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_SW_DEPLETION, p_BmPool->bpid));
+ case(e_BM_POOL_COUNTERS_HW_DEPLETION):
+ return (p_BmPool->hwDepletionCount +=
+ BmGetCounter(p_BmPool->h_Bm, e_BM_IM_COUNTERS_POOL_HW_DEPLETION, p_BmPool->bpid));
+ default:
+ break;
+ }
+
+ /* should never get here */
+ ASSERT_COND(FALSE);
+
+ return 0;
+}
diff --git a/sys/contrib/ncsw/Peripherals/BM/bm_portal.c b/sys/contrib/ncsw/Peripherals/BM/bm_portal.c
new file mode 100644
index 0000000..34b48e3
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/bm_portal.c
@@ -0,0 +1,561 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File bm.c
+
+ @Description BM
+*//***************************************************************************/
+#include "error_ext.h"
+#include "std_ext.h"
+#include "string_ext.h"
+#include "mem_ext.h"
+#include "core_ext.h"
+
+#include "bm.h"
+
+
+#define __ERR_MODULE__ MODULE_BM
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+
+static uint32_t __poll_portal_slow(t_BmPortal *p);
+static void __poll_portal_fast(t_BmPortal *p);
+
+/* Portal interrupt handler */
+static void portal_isr(void *ptr)
+{
+ t_BmPortal *portal = ptr;
+ /* Only do fast-path handling if it's required */
+ if (portal->flags & BMAN_PORTAL_FLAG_IRQ_FAST)
+ __poll_portal_fast(portal);
+ __poll_portal_slow(portal);
+
+}
+
+/**
+ * bman_create_portal - Manage a Bman s/w portal
+ * @portal: the s/w corenet portal to use
+ * @flags: bit-mask of BMAN_PORTAL_FLAG_*** options
+ * @pools: bit-array of buffer pools available to this portal
+ * @portal_ctx: opaque user-supplied data to be associated with the portal
+ *
+ * Creates a managed portal object. @irq is only used if @flags specifies
+ * BMAN_PORTAL_FLAG_IRQ. @pools is copied, so the caller can do as they please
+ * with it after the function returns. It will only be possible to configure
+ * buffer pool objects as "suppliers" if they are specified in @pools, and the
+ * driver will only track depletion state changes to the same subset of buffer
+ * pools. If @pools is NULL, buffer pool depletion state will not be tracked.
+ * If the BMAN_PORTAL_FLAG_RECOVER flag is specified, then the function will
+ * attempt to expire any existing RCR entries, otherwise the function will fail
+ * if RCR is non-empty. If the BMAN_PORTAL_FLAG_WAIT flag is set, the function
+ * is allowed to block waiting for expiration of RCR. BMAN_PORTAL_FLAG_WAIT_INT
+ * makes any blocking interruptible.
+ */
+
+static t_Error bman_create_portal(t_BmPortal *p_BmPortal,
+ uint32_t flags,
+ const struct bman_depletion *pools)
+{
+ int ret = 0;
+ uint8_t bpid = 0;
+ e_BmPortalRcrConsumeMode rcr_cmode;
+ e_BmPortalProduceMode pmode;
+
+ pmode = e_BmPortalPVB;
+ rcr_cmode = (flags & BMAN_PORTAL_FLAG_CACHE) ? e_BmPortalRcrCCE : e_BmPortalRcrCCI;
+
+ switch (pmode)
+ {
+ case e_BmPortalPCI:
+ p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pci_commit;
+ break;
+ case e_BmPortalPCE:
+ p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pce_commit;
+ break;
+ case e_BmPortalPVB:
+ p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pvb_commit;
+ break;
+ }
+ switch (rcr_cmode)
+ {
+ case e_BmPortalRcrCCI:
+ p_BmPortal->cbs[BM_RCR_RING].f_BmUpdateCb = bm_rcr_cci_update;
+ p_BmPortal->cbs[BM_RCR_RING].f_BmPrefetchCb = NULL;
+ break;
+ case e_BmPortalRcrCCE:
+ p_BmPortal->cbs[BM_RCR_RING].f_BmUpdateCb = bm_rcr_cce_update;
+ p_BmPortal->cbs[BM_RCR_RING].f_BmPrefetchCb = bm_rcr_cce_prefetch;
+ break;
+ }
+
+ if (bm_rcr_init(p_BmPortal->p_BmPortalLow, pmode, rcr_cmode)) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("RCR initialization failed"));
+ goto fail_rcr;
+ }
+ if (bm_mc_init(p_BmPortal->p_BmPortalLow)) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MC initialization failed"));
+ goto fail_mc;
+ }
+ p_BmPortal->pools[0] = *pools;
+ bman_depletion_init(&p_BmPortal->pools[1]);
+ while (bpid < BM_MAX_NUM_OF_POOLS) {
+ /* Default to all BPIDs disabled, we enable as required
+ * at run-time. */
+ bm_isr_bscn_mask(p_BmPortal->p_BmPortalLow, bpid, 0);
+ bpid++;
+ }
+ p_BmPortal->flags = flags;
+ p_BmPortal->slowpoll = 0;
+ p_BmPortal->rcrProd = p_BmPortal->rcrCons = 0;
+ memset(&p_BmPortal->depletionPoolsTable, 0, sizeof(p_BmPortal->depletionPoolsTable));
+ /* Write-to-clear any stale interrupt status bits */
+ bm_isr_disable_write(p_BmPortal->p_BmPortalLow, 0xffffffff);
+ bm_isr_status_clear(p_BmPortal->p_BmPortalLow, 0xffffffff);
+ bm_isr_enable_write(p_BmPortal->p_BmPortalLow, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
+ if (flags & BMAN_PORTAL_FLAG_IRQ)
+ {
+ XX_SetIntr(p_BmPortal->irq, portal_isr, p_BmPortal);
+ XX_EnableIntr(p_BmPortal->irq);
+ /* Enable the bits that make sense */
+ bm_isr_uninhibit(p_BmPortal->p_BmPortalLow);
+ } else
+ /* without IRQ, we can't block */
+ flags &= ~BMAN_PORTAL_FLAG_WAIT;
+ /* Need RCR to be empty before continuing */
+ bm_isr_disable_write(p_BmPortal->p_BmPortalLow, (uint32_t)~BM_PIRQ_RCRI);
+ if (!(flags & BMAN_PORTAL_FLAG_RECOVER) ||
+ !(flags & BMAN_PORTAL_FLAG_WAIT))
+ ret = bm_rcr_get_fill(p_BmPortal->p_BmPortalLow);
+ if (ret) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("RCR unclean, need recovery"));
+ goto fail_rcr_empty;
+ }
+ bm_isr_disable_write(p_BmPortal->p_BmPortalLow, 0);
+ return E_OK;
+fail_rcr_empty:
+ bm_mc_finish(p_BmPortal->p_BmPortalLow);
+fail_mc:
+ bm_rcr_finish(p_BmPortal->p_BmPortalLow);
+fail_rcr:
+ XX_Free(p_BmPortal);
+ return ERROR_CODE(E_INVALID_STATE);
+}
+
+static void bman_destroy_portal(t_BmPortal* p_BmPortal)
+{
+ BmUpdate(p_BmPortal, BM_RCR_RING);
+ if (p_BmPortal->flags & BMAN_PORTAL_FLAG_IRQ)
+ {
+ XX_DisableIntr(p_BmPortal->irq);
+ XX_FreeIntr(p_BmPortal->irq);
+ }
+ bm_mc_finish(p_BmPortal->p_BmPortalLow);
+ bm_rcr_finish(p_BmPortal->p_BmPortalLow);
+ XX_Free(p_BmPortal->p_BmPortalLow);
+}
+
+/* When release logic waits on available RCR space, we need a global waitqueue
+ * in the case of "affine" use (as the waits wake on different cpus which means
+ * different portals - so we can't wait on any per-portal waitqueue). */
+
+static uint32_t __poll_portal_slow(t_BmPortal* p_BmPortal)
+{
+ struct bman_depletion tmp;
+ t_BmPool *p_BmPool;
+ uint32_t ret,is = bm_isr_status_read(p_BmPortal->p_BmPortalLow);
+ ret = is;
+
+ /* There is a gotcha to be aware of. If we do the query before clearing
+ * the status register, we may miss state changes that occur between the
+ * two. If we write to clear the status register before the query, the
+ * cache-enabled query command may overtake the status register write
+ * unless we use a heavyweight sync (which we don't want). Instead, we
+ * write-to-clear the status register then *read it back* before doing
+ * the query, hence the odd while loop with the 'is' accumulation. */
+ if (is & BM_PIRQ_BSCN) {
+ uint32_t i, j;
+ uint32_t __is;
+ bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_BSCN);
+ while ((__is = bm_isr_status_read(p_BmPortal->p_BmPortalLow)) & BM_PIRQ_BSCN) {
+ is |= __is;
+ bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_BSCN);
+ }
+ is &= ~BM_PIRQ_BSCN;
+ BmPortalQuery(p_BmPortal, &tmp, TRUE);
+ for (i = 0; i < 2; i++) {
+ uint32_t idx = i * 32;
+ /* tmp is a mask of currently-depleted pools.
+ * pools[0] is mask of those we care about.
+ * pools[1] is our previous view (we only want to
+ * be told about changes). */
+ tmp.__state[i] &= p_BmPortal->pools[0].__state[i];
+ if (tmp.__state[i] == p_BmPortal->pools[1].__state[i])
+ /* fast-path, nothing to see, move along */
+ continue;
+ for (j = 0; j <= 31; j++, idx++) {
+ int b4 = bman_depletion_get(&p_BmPortal->pools[1], (uint8_t)idx);
+ int af = bman_depletion_get(&tmp, (uint8_t)idx);
+ if (b4 == af)
+ continue;
+ p_BmPool = p_BmPortal->depletionPoolsTable[idx];
+ ASSERT_COND(p_BmPool->f_Depletion);
+ p_BmPool->f_Depletion(p_BmPool->h_App, (bool)af);
+ }
+ }
+ p_BmPortal->pools[1] = tmp;
+ }
+
+ if (is & BM_PIRQ_RCRI) {
+ NCSW_PLOCK(p_BmPortal);
+ p_BmPortal->rcrCons += BmUpdate(p_BmPortal, BM_RCR_RING);
+ bm_rcr_set_ithresh(p_BmPortal->p_BmPortalLow, 0);
+ PUNLOCK(p_BmPortal);
+ bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_RCRI);
+ is &= ~BM_PIRQ_RCRI;
+ }
+
+ /* There should be no status register bits left undefined */
+ ASSERT_COND(!is);
+ return ret;
+}
+
+static void __poll_portal_fast(t_BmPortal* p_BmPortal)
+{
+ UNUSED(p_BmPortal);
+ /* nothing yet, this is where we'll put optimised RCR consumption
+ * tracking */
+}
+
+
+static __inline__ void rel_set_thresh(t_BmPortal *p_BmPortal, int check)
+{
+ if (!check || !bm_rcr_get_ithresh(p_BmPortal->p_BmPortalLow))
+ bm_rcr_set_ithresh(p_BmPortal->p_BmPortalLow, RCR_ITHRESH);
+}
+
+/* Used as a wait_event() expression. If it returns non-NULL, any lock will
+ * remain held. */
+static struct bm_rcr_entry *try_rel_start(t_BmPortal *p_BmPortal)
+{
+ struct bm_rcr_entry *r;
+
+ NCSW_PLOCK(p_BmPortal);
+ if (bm_rcr_get_avail((p_BmPortal)->p_BmPortalLow) < RCR_THRESH)
+ BmUpdate(p_BmPortal, BM_RCR_RING);
+ r = bm_rcr_start((p_BmPortal)->p_BmPortalLow);
+ if (!r) {
+ rel_set_thresh(p_BmPortal, 1);
+ PUNLOCK(p_BmPortal);
+ }
+ return r;
+}
+
+static __inline__ t_Error wait_rel_start(t_BmPortal *p_BmPortal,
+ struct bm_rcr_entry **rel,
+ uint32_t flags)
+{
+ int tries = 100;
+
+ UNUSED(flags);
+ do {
+ *rel = try_rel_start(p_BmPortal);
+ XX_Sleep(1);
+ } while (!*rel && --tries);
+
+ if (!(*rel))
+ return ERROR_CODE(E_BUSY);
+
+ return E_OK;
+}
+
+/* This copies Qman's eqcr_completed() routine, see that for details */
+static int rel_completed(t_BmPortal *p_BmPortal, uint32_t rcr_poll)
+{
+ uint32_t tr_cons = p_BmPortal->rcrCons;
+ if (rcr_poll & 0xc0000000) {
+ rcr_poll &= 0x7fffffff;
+ tr_cons ^= 0x80000000;
+ }
+ if (tr_cons >= rcr_poll)
+ return 1;
+ if ((rcr_poll - tr_cons) > BM_RCR_SIZE)
+ return 1;
+ if (!bm_rcr_get_fill(p_BmPortal->p_BmPortalLow))
+ /* If RCR is empty, we must have completed */
+ return 1;
+ rel_set_thresh(p_BmPortal, 0);
+ return 0;
+}
+
+static __inline__ void rel_commit(t_BmPortal *p_BmPortal, uint32_t flags,uint8_t num)
+{
+ uint32_t rcr_poll;
+
+ BmCommit(p_BmPortal, BM_RCR_RING, (uint8_t)(BM_RCR_VERB_CMD_BPID_SINGLE | (num & BM_RCR_VERB_BUFCOUNT_MASK)));
+ /* increment the producer count and capture it for SYNC */
+ rcr_poll = ++p_BmPortal->rcrProd;
+ if ((flags & BMAN_RELEASE_FLAG_WAIT_SYNC) ==
+ BMAN_RELEASE_FLAG_WAIT_SYNC)
+ rel_set_thresh(p_BmPortal, 1);
+ PUNLOCK(p_BmPortal);
+ if ((flags & BMAN_RELEASE_FLAG_WAIT_SYNC) !=
+ BMAN_RELEASE_FLAG_WAIT_SYNC)
+ return;
+ rel_completed(p_BmPortal, rcr_poll);
+}
+
+
+/****************************************/
+/* Inter-Module functions */
+/****************************************/
+
+/**
+ * bman_release - Release buffer(s) to the buffer pool
+ * @p_BmPool: the buffer pool object to release to
+ * @bufs: an array of buffers to release
+ * @num: the number of buffers in @bufs (1-8)
+ * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
+ *
+ * Adds the given buffers to RCR entries. If the portal @p_BmPortal was created with the
+ * "COMPACT" flag, then it will be using a compaction algorithm to improve
+ * utilization of RCR. As such, these buffers may join an existing ring entry
+ * and/or it may not be issued right away so as to allow future releases to join
+ * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
+ * behavior by committing the RCR entry (or entries) right away. If the RCR
+ * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
+ * is selected, in which case it will sleep waiting for space to become
+ * available in RCR. If the function receives a signal before such time (and
+ * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
+ * it returns zero.
+ */
+
+t_Error BmPortalRelease(t_Handle h_BmPortal,
+ uint8_t bpid,
+ struct bm_buffer *bufs,
+ uint8_t num,
+ uint32_t flags)
+{
+ t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
+ struct bm_rcr_entry *r;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
+ /* TODO: I'm ignoring BMAN_PORTAL_FLAG_COMPACT for now. */
+ r = try_rel_start(p_BmPortal);
+ if (!r) {
+ if (flags & BMAN_RELEASE_FLAG_WAIT) {
+ t_Error ret = wait_rel_start(p_BmPortal, &r, flags);
+ if (ret)
+ return ret;
+ } else
+ return ERROR_CODE(E_BUSY);
+ ASSERT_COND(r != NULL);
+ }
+ r->bpid = bpid;
+ for (i = 0; i < num; i++) {
+ r->bufs[i].hi = bufs[i].hi;
+ r->bufs[i].lo = bufs[i].lo;
+ }
+ /* Issue the release command and wait for sync if requested. NB: the
+ * commit can't fail, only waiting can. Don't propagate any failure if a
+ * signal arrives, otherwise the caller can't distinguish whether the
+ * release was issued or not. Code for user-space can check
+ * signal_pending() after we return. */
+ rel_commit(p_BmPortal, flags, num);
+ return E_OK;
+}
+
+uint8_t BmPortalAcquire(t_Handle h_BmPortal,
+ uint8_t bpid,
+ struct bm_buffer *bufs,
+ uint8_t num)
+{
+ t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
+ struct bm_mc_command *mcc;
+ struct bm_mc_result *mcr;
+ uint8_t ret = 0;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPortal, E_INVALID_HANDLE, 0);
+ NCSW_PLOCK(p_BmPortal);
+ mcc = bm_mc_start(p_BmPortal->p_BmPortalLow);
+ mcc->acquire.bpid = bpid;
+ bm_mc_commit(p_BmPortal->p_BmPortalLow,
+ (uint8_t)(BM_MCC_VERB_CMD_ACQUIRE |
+ (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT)));
+ while (!(mcr = bm_mc_result(p_BmPortal->p_BmPortalLow))) ;
+ ret = num = (uint8_t)(mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT);
+ ASSERT_COND(num <= 8);
+ while (num--) {
+ bufs[num].bpid = bpid;
+ bufs[num].hi = mcr->acquire.bufs[num].hi;
+ bufs[num].lo = mcr->acquire.bufs[num].lo;
+ }
+ PUNLOCK(p_BmPortal);
+ return ret;
+}
+
+t_Error BmPortalQuery(t_Handle h_BmPortal, struct bman_depletion *p_Pools, bool depletion)
+{
+ t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
+ struct bm_mc_result *mcr;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
+
+ NCSW_PLOCK(p_BmPortal);
+ bm_mc_start(p_BmPortal->p_BmPortalLow);
+ bm_mc_commit(p_BmPortal->p_BmPortalLow, BM_MCC_VERB_CMD_QUERY);
+ while (!(mcr = bm_mc_result(p_BmPortal->p_BmPortalLow))) ;
+ if (depletion)
+ *p_Pools = mcr->query.ds.state;
+ else
+ *p_Pools = mcr->query.as.state;
+ PUNLOCK(p_BmPortal);
+ return E_OK;
+}
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+
+t_Handle BM_PORTAL_Config(t_BmPortalParam *p_BmPortalParam)
+{
+ t_BmPortal *p_BmPortal;
+
+ SANITY_CHECK_RETURN_VALUE(p_BmPortalParam, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_BmPortalParam->h_Bm, E_INVALID_HANDLE, NULL);
+
+ p_BmPortal = (t_BmPortal *)XX_Malloc(sizeof(t_BmPortal));
+ if (!p_BmPortal)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Portal obj!!!"));
+ return NULL;
+ }
+ memset(p_BmPortal, 0, sizeof(t_BmPortal));
+
+ p_BmPortal->p_BmPortalLow = (struct bm_portal *)XX_Malloc(sizeof(struct bm_portal));
+ if (!p_BmPortal->p_BmPortalLow)
+ {
+ XX_Free(p_BmPortal);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Low bm portal obj!!!"));
+ return NULL;
+ }
+ memset(p_BmPortal->p_BmPortalLow, 0, sizeof(struct bm_portal));
+
+ p_BmPortal->p_BmPortalDriverParams = (t_BmPortalDriverParams *)XX_Malloc(sizeof(t_BmPortalDriverParams));
+ if (!p_BmPortal->p_BmPortalDriverParams)
+ {
+ XX_Free(p_BmPortal);
+ XX_Free(p_BmPortal->p_BmPortalLow);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Portal driver parameters"));
+ return NULL;
+ }
+ memset(p_BmPortal->p_BmPortalDriverParams, 0, sizeof(t_BmPortalDriverParams));
+
+ p_BmPortal->p_BmPortalLow->addr.addr_ce = UINT_TO_PTR(p_BmPortalParam->ceBaseAddress);
+ p_BmPortal->p_BmPortalLow->addr.addr_ci = UINT_TO_PTR(p_BmPortalParam->ciBaseAddress);
+ p_BmPortal->cpu = (int)p_BmPortalParam->swPortalId;
+ p_BmPortal->irq = p_BmPortalParam->irq;
+
+ p_BmPortal->h_Bm = p_BmPortalParam->h_Bm;
+
+ p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr = DEFAULT_memAttr;
+ bman_depletion_fill(&p_BmPortal->p_BmPortalDriverParams->mask);
+
+ return p_BmPortal;
+}
+
+t_Error BM_PORTAL_Init(t_Handle h_BmPortal)
+{
+ t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
+ uint32_t flags;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
+
+ flags = (uint32_t)((p_BmPortal->irq != NO_IRQ) ? BMAN_PORTAL_FLAG_IRQ : 0);
+ flags |= ((p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE) ?
+ BMAN_PORTAL_FLAG_CACHE : 0);
+
+ if (bman_create_portal(p_BmPortal,flags,&p_BmPortal->p_BmPortalDriverParams->mask)!=E_OK)
+ {
+ BM_PORTAL_Free(p_BmPortal);
+ RETURN_ERROR(MAJOR, E_NULL_POINTER, ("create portal failed"));
+ }
+ BmSetPortalHandle(p_BmPortal->h_Bm, (t_Handle)p_BmPortal, (e_DpaaSwPortal)p_BmPortal->cpu);
+
+ XX_Free(p_BmPortal->p_BmPortalDriverParams);
+ p_BmPortal->p_BmPortalDriverParams = NULL;
+
+ DBG(TRACE,("Bman-Portal (%d) @ %p:%p\n",
+ p_BmPortal->cpu,
+ p_BmPortal->p_BmPortalLow->addr.addr_ce,
+ p_BmPortal->p_BmPortalLow->addr.addr_ci
+ ));
+
+ DBG(TRACE,("Bman-Portal (%d) @ 0x%016llx:0x%016llx",
+ p_BmPortal->cpu,
+ (uint64_t)XX_VirtToPhys(p_BmPortal->p_BmPortalLow->addr.addr_ce),
+ (uint64_t)XX_VirtToPhys(p_BmPortal->p_BmPortalLow->addr.addr_ci)
+ ));
+
+ return E_OK;
+}
+
+t_Error BM_PORTAL_Free(t_Handle h_BmPortal)
+{
+ t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
+
+ if (!p_BmPortal)
+ return ERROR_CODE(E_INVALID_HANDLE);
+ BmSetPortalHandle(p_BmPortal->h_Bm, NULL, (e_DpaaSwPortal)p_BmPortal->cpu);
+ bman_destroy_portal(p_BmPortal);
+ XX_Free(p_BmPortal);
+ return E_OK;
+}
+
+t_Error BM_PORTAL_ConfigMemAttr(t_Handle h_BmPortal, uint32_t hwExtStructsMemAttr)
+{
+ t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_BmPortal->p_BmPortalDriverParams, E_INVALID_HANDLE);
+
+ p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr = hwExtStructsMemAttr;
+
+ return E_OK;
+}
diff --git a/sys/contrib/ncsw/Peripherals/BM/bman_low.c b/sys/contrib/ncsw/Peripherals/BM/bman_low.c
new file mode 100644
index 0000000..740277f
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/bman_low.c
@@ -0,0 +1,494 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File bman_low.c
+
+ @Description BM low-level implementation
+*//***************************************************************************/
+#include "std_ext.h"
+#include "core_ext.h"
+#include "xx_ext.h"
+#include "error_ext.h"
+
+#include "bman_private.h"
+
+
+/***************************/
+/* Portal register assists */
+/***************************/
+
+/* Cache-inhibited register offsets */
+#define REG_RCR_PI_CINH (void *)0x0000
+#define REG_RCR_CI_CINH (void *)0x0004
+#define REG_RCR_ITR (void *)0x0008
+#define REG_CFG (void *)0x0100
+#define REG_SCN(n) ((void *)(0x0200 + ((n) << 2)))
+#define REG_ISR (void *)0x0e00
+#define REG_IER (void *)0x0e04
+#define REG_ISDR (void *)0x0e08
+#define REG_IIR (void *)0x0e0c
+
+/* Cache-enabled register offsets */
+#define CL_CR (void *)0x0000
+#define CL_RR0 (void *)0x0100
+#define CL_RR1 (void *)0x0140
+#define CL_RCR (void *)0x1000
+#define CL_RCR_PI_CENA (void *)0x3000
+#define CL_RCR_CI_CENA (void *)0x3100
+
+/* The h/w design requires mappings to be size-aligned so that "add"s can be
+ * reduced to "or"s. The primitives below do the same for s/w. */
+
+static __inline__ void *ptr_ADD(void *a, void *b)
+{
+ return (void *)((uintptr_t)a + (uintptr_t)b);
+}
+
+/* Bitwise-OR two pointers */
+static __inline__ void *ptr_OR(void *a, void *b)
+{
+ return (void *)((uintptr_t)a | (uintptr_t)b);
+}
+
+/* Cache-inhibited register access */
+static __inline__ uint32_t __bm_in(struct bm_addr *bm, void *offset)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(bm->addr_ci, offset);
+ return GET_UINT32(*tmp);
+}
+static __inline__ void __bm_out(struct bm_addr *bm, void *offset, uint32_t val)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(bm->addr_ci, offset);
+ WRITE_UINT32(*tmp, val);
+}
+#define bm_in(reg) __bm_in(&portal->addr, REG_##reg)
+#define bm_out(reg, val) __bm_out(&portal->addr, REG_##reg, val)
+
+/* Convert 'n' cachelines to a pointer value for bitwise OR */
+#define bm_cl(n) (void *)((n) << 6)
+
+/* Cache-enabled (index) register access */
+static __inline__ void __bm_cl_touch_ro(struct bm_addr *bm, void *offset)
+{
+ dcbt_ro(ptr_ADD(bm->addr_ce, offset));
+}
+static __inline__ void __bm_cl_touch_rw(struct bm_addr *bm, void *offset)
+{
+ dcbt_rw(ptr_ADD(bm->addr_ce, offset));
+}
+static __inline__ uint32_t __bm_cl_in(struct bm_addr *bm, void *offset)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(bm->addr_ce, offset);
+ return GET_UINT32(*tmp);
+}
+static __inline__ void __bm_cl_out(struct bm_addr *bm, void *offset, uint32_t val)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(bm->addr_ce, offset);
+ WRITE_UINT32(*tmp, val);
+ dcbf(tmp);
+}
+static __inline__ void __bm_cl_invalidate(struct bm_addr *bm, void *offset)
+{
+ dcbi(ptr_ADD(bm->addr_ce, offset));
+}
+#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, CL_##reg##_CENA)
+#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, CL_##reg##_CENA)
+#define bm_cl_in(reg) __bm_cl_in(&portal->addr, CL_##reg##_CENA)
+#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, CL_##reg##_CENA, val)
+#define bm_cl_invalidate(reg) __bm_cl_invalidate(&portal->addr, CL_##reg##_CENA)
+
+/* Cyclic helper for rings. TODO: once we are able to do fine-grain perf
+ * analysis, look at using the "extra" bit in the ring index registers to avoid
+ * cyclic issues. */
+static __inline__ uint8_t cyc_diff(uint8_t ringsize, uint8_t first, uint8_t last)
+{
+ /* 'first' is included, 'last' is excluded */
+ if (first <= last)
+ return (uint8_t)(last - first);
+ return (uint8_t)(ringsize + last - first);
+}
+
+/* --------------- */
+/* --- RCR API --- */
+
+/* It's safer to code in terms of the 'rcr' object than the 'portal' object,
+ * because the latter runs the risk of copy-n-paste errors from other code where
+ * we could manipulate some other structure within 'portal'. */
+/* #define RCR_API_START() register struct bm_rcr *rcr = &portal->rcr */
+
+/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
+#define RCR_CARRYCLEAR(p) \
+ (void *)((uintptr_t)(p) & (~(uintptr_t)(BM_RCR_SIZE << 6)))
+
+/* Bit-wise logic to convert a ring pointer to a ring index */
+static __inline__ uint8_t RCR_PTR2IDX(struct bm_rcr_entry *e)
+{
+ return (uint8_t)(((uint32_t)e >> 6) & (BM_RCR_SIZE - 1));
+}
+
+/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
+static __inline__ void RCR_INC(struct bm_rcr *rcr)
+{
+ /* NB: this is odd-looking, but experiments show that it generates
+ * fast code with essentially no branching overheads. We increment to
+ * the next RCR pointer and handle overflow and 'vbit'. */
+ struct bm_rcr_entry *partial = rcr->cursor + 1;
+ rcr->cursor = RCR_CARRYCLEAR(partial);
+ if (partial != rcr->cursor)
+ rcr->vbit ^= BM_RCR_VERB_VBIT;
+}
+
+t_Error bm_rcr_init(struct bm_portal *portal,
+ e_BmPortalProduceMode pmode,
+ e_BmPortalRcrConsumeMode cmode)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ uint32_t cfg;
+ uint8_t pi;
+
+ rcr->ring = ptr_ADD(portal->addr.addr_ce, CL_RCR);
+ rcr->ci = (uint8_t)(bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1));
+ pi = (uint8_t)(bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1));
+ rcr->cursor = rcr->ring + pi;
+ rcr->vbit = (uint8_t)((bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0);
+ rcr->available = (uint8_t)(BM_RCR_SIZE - 1 - cyc_diff(BM_RCR_SIZE, rcr->ci, pi));
+ rcr->ithresh = (uint8_t)bm_in(RCR_ITR);
+#ifdef BM_CHECKING
+ rcr->busy = 0;
+ rcr->pmode = pmode;
+ rcr->cmode = cmode;
+#else
+ UNUSED(cmode);
+#endif /* BM_CHECKING */
+ cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
+ bm_out(CFG, cfg);
+ return 0;
+}
+
+void bm_rcr_finish(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ uint8_t pi = (uint8_t)(bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1));
+ uint8_t ci = (uint8_t)(bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1));
+ ASSERT_COND(!rcr->busy);
+ if (pi != RCR_PTR2IDX(rcr->cursor))
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("losing uncommitted RCR entries"));
+ if (ci != rcr->ci)
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("missing existing RCR completions"));
+ if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("RCR destroyed unquiesced"));
+}
+
+struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ ASSERT_COND(!rcr->busy);
+ if (!rcr->available)
+ return NULL;
+#ifdef BM_CHECKING
+ rcr->busy = 1;
+#endif /* BM_CHECKING */
+ dcbz_64(rcr->cursor);
+ return rcr->cursor;
+}
+
+void bm_rcr_abort(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ ASSERT_COND(rcr->busy);
+#ifdef BM_CHECKING
+ rcr->busy = 0;
+#else
+ UNUSED(rcr);
+#endif /* BM_CHECKING */
+}
+
+struct bm_rcr_entry *bm_rcr_pend_and_next(struct bm_portal *portal, uint8_t myverb)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ ASSERT_COND(rcr->busy);
+ ASSERT_COND(rcr->pmode != e_BmPortalPVB);
+ if (rcr->available == 1)
+ return NULL;
+ rcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit);
+ dcbf_64(rcr->cursor);
+ RCR_INC(rcr);
+ rcr->available--;
+ dcbz_64(rcr->cursor);
+ return rcr->cursor;
+}
+
+void bm_rcr_pci_commit(struct bm_portal *portal, uint8_t myverb)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ ASSERT_COND(rcr->busy);
+ ASSERT_COND(rcr->pmode == e_BmPortalPCI);
+ rcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit);
+ RCR_INC(rcr);
+ rcr->available--;
+ hwsync();
+ bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
+#ifdef BM_CHECKING
+ rcr->busy = 0;
+#endif /* BM_CHECKING */
+}
+
+void bm_rcr_pce_prefetch(struct bm_portal *portal)
+{
+ ASSERT_COND(((struct bm_rcr *)&portal->rcr)->pmode == e_BmPortalPCE);
+ bm_cl_invalidate(RCR_PI);
+ bm_cl_touch_rw(RCR_PI);
+}
+
+void bm_rcr_pce_commit(struct bm_portal *portal, uint8_t myverb)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ ASSERT_COND(rcr->busy);
+ ASSERT_COND(rcr->pmode == e_BmPortalPCE);
+ rcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit);
+ RCR_INC(rcr);
+ rcr->available--;
+ lwsync();
+ bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
+#ifdef BM_CHECKING
+ rcr->busy = 0;
+#endif /* BM_CHECKING */
+}
+
+void bm_rcr_pvb_commit(struct bm_portal *portal, uint8_t myverb)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ struct bm_rcr_entry *rcursor;
+ ASSERT_COND(rcr->busy);
+ ASSERT_COND(rcr->pmode == e_BmPortalPVB);
+ lwsync();
+ rcursor = rcr->cursor;
+ rcursor->__dont_write_directly__verb = (uint8_t)(myverb | rcr->vbit);
+ dcbf_64(rcursor);
+ RCR_INC(rcr);
+ rcr->available--;
+#ifdef BM_CHECKING
+ rcr->busy = 0;
+#endif /* BM_CHECKING */
+}
+
+
+uint8_t bm_rcr_cci_update(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ uint8_t diff, old_ci = rcr->ci;
+ ASSERT_COND(rcr->cmode == e_BmPortalRcrCCI);
+ rcr->ci = (uint8_t)(bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1));
+ diff = cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
+ rcr->available += diff;
+ return diff;
+}
+
+
+void bm_rcr_cce_prefetch(struct bm_portal *portal)
+{
+ ASSERT_COND(((struct bm_rcr *)&portal->rcr)->cmode == e_BmPortalRcrCCE);
+ bm_cl_touch_ro(RCR_CI);
+}
+
+
+uint8_t bm_rcr_cce_update(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ uint8_t diff, old_ci = rcr->ci;
+ ASSERT_COND(rcr->cmode == e_BmPortalRcrCCE);
+ rcr->ci = (uint8_t)(bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1));
+ bm_cl_invalidate(RCR_CI);
+ diff = cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
+ rcr->available += diff;
+ return diff;
+}
+
+
+uint8_t bm_rcr_get_ithresh(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ return rcr->ithresh;
+}
+
+
+void bm_rcr_set_ithresh(struct bm_portal *portal, uint8_t ithresh)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ rcr->ithresh = ithresh;
+ bm_out(RCR_ITR, ithresh);
+}
+
+
+uint8_t bm_rcr_get_avail(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ return rcr->available;
+}
+
+
+uint8_t bm_rcr_get_fill(struct bm_portal *portal)
+{
+ register struct bm_rcr *rcr = &portal->rcr;
+ return (uint8_t)(BM_RCR_SIZE - 1 - rcr->available);
+}
+
+
+/* ------------------------------ */
+/* --- Management command API --- */
+
+/* It's safer to code in terms of the 'mc' object than the 'portal' object,
+ * because the latter runs the risk of copy-n-paste errors from other code where
+ * we could manipulate some other structure within 'portal'. */
+/* #define MC_API_START() register struct bm_mc *mc = &portal->mc */
+
+
+t_Error bm_mc_init(struct bm_portal *portal)
+{
+ register struct bm_mc *mc = &portal->mc;
+ mc->cr = ptr_ADD(portal->addr.addr_ce, CL_CR);
+ mc->rr = ptr_ADD(portal->addr.addr_ce, CL_RR0);
+ mc->rridx = (uint8_t)((mc->cr->__dont_write_directly__verb & BM_MCC_VERB_VBIT) ?
+ 0 : 1);
+ mc->vbit = (uint8_t)(mc->rridx ? BM_MCC_VERB_VBIT : 0);
+#ifdef BM_CHECKING
+ mc->state = mc_idle;
+#endif /* BM_CHECKING */
+ return 0;
+}
+
+
+void bm_mc_finish(struct bm_portal *portal)
+{
+ register struct bm_mc *mc = &portal->mc;
+ ASSERT_COND(mc->state == mc_idle);
+#ifdef BM_CHECKING
+ if (mc->state != mc_idle)
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("Losing incomplete MC command"));
+#else
+ UNUSED(mc);
+#endif /* BM_CHECKING */
+}
+
+
+struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
+{
+ register struct bm_mc *mc = &portal->mc;
+ ASSERT_COND(mc->state == mc_idle);
+#ifdef BM_CHECKING
+ mc->state = mc_user;
+#endif /* BM_CHECKING */
+ dcbz_64(mc->cr);
+ return mc->cr;
+}
+
+
+void bm_mc_abort(struct bm_portal *portal)
+{
+ register struct bm_mc *mc = &portal->mc;
+ ASSERT_COND(mc->state == mc_user);
+#ifdef BM_CHECKING
+ mc->state = mc_idle;
+#else
+ UNUSED(mc);
+#endif /* BM_CHECKING */
+}
+
+
+void bm_mc_commit(struct bm_portal *portal, uint8_t myverb)
+{
+ register struct bm_mc *mc = &portal->mc;
+ ASSERT_COND(mc->state == mc_user);
+ lwsync();
+ mc->cr->__dont_write_directly__verb = (uint8_t)(myverb | mc->vbit);
+ dcbf_64(mc->cr);
+ dcbit_ro(mc->rr + mc->rridx);
+#ifdef BM_CHECKING
+ mc->state = mc_hw;
+#endif /* BM_CHECKING */
+}
+
+
+struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
+{
+ register struct bm_mc *mc = &portal->mc;
+ struct bm_mc_result *rr = mc->rr + mc->rridx;
+ ASSERT_COND(mc->state == mc_hw);
+ /* The inactive response register's verb byte always returns zero until
+ * its command is submitted and completed. This includes the valid-bit,
+ * in case you were wondering... */
+ if (!rr->verb) {
+ dcbit_ro(rr);
+ return NULL;
+ }
+ mc->rridx ^= 1;
+ mc->vbit ^= BM_MCC_VERB_VBIT;
+#ifdef BM_CHECKING
+ mc->state = mc_idle;
+#endif /* BM_CHECKING */
+ return rr;
+}
+
+/* ------------------------------------- */
+/* --- Portal interrupt register API --- */
+
+#define SCN_REG(bpid) REG_SCN((bpid) / 32)
+#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
+void bm_isr_bscn_mask(struct bm_portal *portal, uint8_t bpid, int enable)
+{
+ uint32_t val;
+ ASSERT_COND(bpid < BM_MAX_NUM_OF_POOLS);
+ /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
+ val = __bm_in(&portal->addr, SCN_REG(bpid));
+ if (enable)
+ val |= SCN_BIT(bpid);
+ else
+ val &= ~SCN_BIT(bpid);
+ __bm_out(&portal->addr, SCN_REG(bpid), val);
+}
+
+
+uint32_t __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
+{
+ return __bm_in(&portal->addr, PTR_MOVE(REG_ISR, (n << 2)));
+}
+
+
+void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n, uint32_t val)
+{
+ __bm_out(&portal->addr, PTR_MOVE(REG_ISR, (n << 2)), val);
+}
+
diff --git a/sys/contrib/ncsw/Peripherals/BM/bman_private.h b/sys/contrib/ncsw/Peripherals/BM/bman_private.h
new file mode 100644
index 0000000..2d70428
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/bman_private.h
@@ -0,0 +1,249 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File bman_private.h
+
+ @Description BM header
+*//***************************************************************************/
+#ifndef __BMAN_PRIV_H
+#define __BMAN_PRIV_H
+
+#include "fsl_bman.h"
+
+#define __ERR_MODULE__ MODULE_BM
+
+#if defined(DEBUG) || !defined(DISABLE_ASSERTIONS)
+/* Optionally compile-in assertion-checking */
+#define BM_CHECKING
+#endif /* defined(DEBUG) || ... */
+
+/* TODO: NB, we currently assume that CORE_MemoryBarier() and lwsync() imply compiler barriers
+ * and that dcbzl(), dcbfl(), and dcbi() won't fall victim to compiler or
+ * execution reordering with respect to other code/instructions that manipulate
+ * the same cacheline. */
+#ifdef CORE_E500MC
+
+#if defined(_DIAB_TOOL)
+#define hwsync() \
+do { \
+__asm__ __volatile__ ("sync"); \
+} while(0)
+
+#define lwsync() \
+do { \
+__asm__ __volatile__ ("lwsync"); \
+} while(0)
+
+__asm__ __volatile__ void dcbf (volatile void * addr)
+{
+%reg addr
+ dcbf r0, addr
+}
+
+__asm__ __volatile__ void dcbt_ro (volatile void * addr)
+{
+%reg addr
+ dcbt r0, addr
+}
+
+__asm__ __volatile__ void dcbt_rw (volatile void * addr)
+{
+%reg addr
+ dcbtst r0, addr
+}
+
+__asm__ __volatile__ void dcbzl (volatile void * addr)
+{
+%reg addr
+ dcbzl r0, addr
+}
+
+#define dcbz_64(p) \
+ do { \
+ dcbzl(p); \
+ } while (0)
+
+#define dcbf_64(p) \
+ do { \
+ dcbf(p); \
+ } while (0)
+
+/* Commonly used combo */
+#define dcbit_ro(p) \
+ do { \
+ dcbi(p); \
+ dcbt_ro(p); \
+ } while (0)
+
+#else /* GNU C */
+#define hwsync() \
+ do { \
+ __asm__ __volatile__ ("sync" : : : "memory"); \
+ } while(0)
+
+#define lwsync() \
+ do { \
+ __asm__ __volatile__ ("lwsync" : : : "memory"); \
+ } while(0)
+
+#define dcbf(addr) \
+ do { \
+ __asm__ __volatile__ ("dcbf 0, %0" : : "r" (addr)); \
+ } while(0)
+
+#define dcbt_ro(addr) \
+ do { \
+ __asm__ __volatile__ ("dcbt 0, %0" : : "r" (addr)); \
+ } while(0)
+
+#define dcbt_rw(addr) \
+ do { \
+ __asm__ __volatile__ ("dcbtst 0, %0" : : "r" (addr)); \
+ } while(0)
+
+#define dcbzl(p) \
+ do { \
+ __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p)); \
+ } while(0)
+
+#define dcbz_64(p) \
+ do { \
+ dcbzl(p); \
+ } while (0)
+
+#define dcbf_64(p) \
+ do { \
+ dcbf(p); \
+ } while (0)
+
+/* Commonly used combo */
+#define dcbit_ro(p) \
+ do { \
+ dcbi(p); \
+ dcbt_ro(p); \
+ } while (0)
+
+#endif /* _DIAB_TOOL */
+
+#else
+#define hwsync CORE_MemoryBarrier
+#define lwsync hwsync
+
+#define dcbf(p) \
+ do { \
+ __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p)); \
+ } while(0)
+#define dcbt_ro(p) \
+ do { \
+ __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p)); \
+ lwsync(); \
+ } while(0)
+#define dcbt_rw(p) \
+ do { \
+ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p)); \
+ } while(0)
+#define dcbz(p) \
+ do { \
+ __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p)); \
+ } while (0)
+#define dcbz_64(p) \
+ do { \
+ dcbz((uint32_t)p + 32); \
+ dcbz(p); \
+ } while (0)
+#define dcbf_64(p) \
+ do { \
+ dcbf((uint32_t)p + 32); \
+ dcbf(p); \
+ } while (0)
+/* Commonly used combo */
+#define dcbit_ro(p) \
+ do { \
+ dcbi(p); \
+ dcbi((uint32_t)p + 32); \
+ dcbt_ro(p); \
+ dcbt_ro((uint32_t)p + 32); \
+ } while (0)
+
+#endif /* CORE_E500MC */
+
+#define dcbi(p) dcbf(p)
+
+struct bm_addr {
+ void *addr_ce; /* cache-enabled */
+ void *addr_ci; /* cache-inhibited */
+};
+
+/* RCR state */
+struct bm_rcr {
+ struct bm_rcr_entry *ring, *cursor;
+ uint8_t ci, available, ithresh, vbit;
+#ifdef BM_CHECKING
+ uint32_t busy;
+ e_BmPortalProduceMode pmode;
+ e_BmPortalRcrConsumeMode cmode;
+#endif /* BM_CHECKING */
+};
+
+/* MC state */
+struct bm_mc {
+ struct bm_mc_command *cr;
+ struct bm_mc_result *rr;
+ uint8_t rridx, vbit;
+#ifdef BM_CHECKING
+ enum {
+ /* Can only be _mc_start()ed */
+ mc_idle,
+ /* Can only be _mc_commit()ed or _mc_abort()ed */
+ mc_user,
+ /* Can only be _mc_retry()ed */
+ mc_hw
+ } state;
+#endif /* BM_CHECKING */
+};
+
+/********************/
+/* Portal structure */
+/********************/
+
+struct bm_portal {
+ struct bm_addr addr;
+ struct bm_rcr rcr;
+ struct bm_mc mc;
+};
+
+
+#endif /* __BMAN_PRIV_H */
diff --git a/sys/contrib/ncsw/Peripherals/BM/fsl_bman.h b/sys/contrib/ncsw/Peripherals/BM/fsl_bman.h
new file mode 100644
index 0000000..4731060
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/BM/fsl_bman.h
@@ -0,0 +1,347 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File fsl_bman.h
+
+ @Description BM header
+*//***************************************************************************/
+#ifndef __FSL_BMAN_H
+#define __FSL_BMAN_H
+
+#include "std_ext.h"
+
+
+/*************************************************/
+/* BMan s/w corenet portal, low-level i/face */
+/*************************************************/
+typedef enum {
+ e_BmPortalPCI = 0, /* PI index, cache-inhibited */
+ e_BmPortalPCE, /* PI index, cache-enabled */
+ e_BmPortalPVB /* valid-bit */
+} e_BmPortalProduceMode;
+
+typedef enum {
+ e_BmPortalRcrCCI = 0, /* CI index, cache-inhibited */
+ e_BmPortalRcrCCE /* CI index, cache-enabled */
+} e_BmPortalRcrConsumeMode;
+
+/* Portal constants */
+#define BM_RCR_SIZE 8
+
+/* Hardware constants */
+enum bm_isr_reg {
+ bm_isr_status = 0,
+ bm_isr_enable = 1,
+ bm_isr_disable = 2,
+ bm_isr_inhibit = 3
+};
+
+/* Represents s/w corenet portal mapped data structures */
+struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
+struct bm_mc_command; /* MC (Management Command) command */
+struct bm_mc_result; /* MC result */
+
+/* This type represents a s/w corenet portal space, and is used for creating the
+ * portal objects within it (RCR, etc) */
+struct bm_portal;
+
+/* This wrapper represents a bit-array for the depletion state of the 64 Bman
+ * buffer pools. */
+struct bman_depletion {
+ uint32_t __state[2];
+};
+#define __bmdep_word(x) ((x) >> 5)
+#define __bmdep_shift(x) ((x) & 0x1f)
+#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
+static __inline__ void bman_depletion_init(struct bman_depletion *c)
+{
+ c->__state[0] = c->__state[1] = 0;
+}
+static __inline__ void bman_depletion_fill(struct bman_depletion *c)
+{
+ c->__state[0] = c->__state[1] = (uint32_t)~0;
+}
+static __inline__ int bman_depletion_get(const struct bman_depletion *c, uint8_t bpid)
+{
+ return (int)(c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid));
+}
+static __inline__ void bman_depletion_set(struct bman_depletion *c, uint8_t bpid)
+{
+ c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
+}
+static __inline__ void bman_depletion_unset(struct bman_depletion *c, uint8_t bpid)
+{
+ c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
+}
+
+/* ------------------------------ */
+/* --- Portal enumeration API --- */
+
+/* ------------------------------ */
+/* --- Buffer pool allocation --- */
+#define BM_POOL_THRESH_SW_ENTER 0
+#define BM_POOL_THRESH_SW_EXIT 1
+#define BM_POOL_THRESH_HW_ENTER 2
+#define BM_POOL_THRESH_HW_EXIT 3
+
+/* --------------- */
+/* --- RCR API --- */
+
+/* Create/destroy */
+t_Error bm_rcr_init(struct bm_portal *portal,
+ e_BmPortalProduceMode pmode,
+ e_BmPortalRcrConsumeMode cmode);
+void bm_rcr_finish(struct bm_portal *portal);
+
+/* Start/abort RCR entry */
+struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal);
+void bm_rcr_abort(struct bm_portal *portal);
+
+/* For PI modes only. This presumes a started but uncommitted RCR entry. If
+ * there's no more room in the RCR, this function returns NULL. Otherwise it
+ * returns the next RCR entry and increments an internal PI counter without
+ * flushing it to h/w. */
+struct bm_rcr_entry *bm_rcr_pend_and_next(struct bm_portal *portal, uint8_t myverb);
+
+/* Commit RCR entries, including pending ones (aka "write PI") */
+void bm_rcr_pci_commit(struct bm_portal *portal, uint8_t myverb);
+void bm_rcr_pce_prefetch(struct bm_portal *portal);
+void bm_rcr_pce_commit(struct bm_portal *portal, uint8_t myverb);
+void bm_rcr_pvb_commit(struct bm_portal *portal, uint8_t myverb);
+
+/* Track h/w consumption. Returns non-zero if h/w had consumed previously
+ * unconsumed RCR entries. */
+uint8_t bm_rcr_cci_update(struct bm_portal *portal);
+void bm_rcr_cce_prefetch(struct bm_portal *portal);
+uint8_t bm_rcr_cce_update(struct bm_portal *portal);
+/* Returns the number of available RCR entries */
+uint8_t bm_rcr_get_avail(struct bm_portal *portal);
+/* Returns the number of unconsumed RCR entries */
+uint8_t bm_rcr_get_fill(struct bm_portal *portal);
+
+/* Read/write the RCR interrupt threshold */
+uint8_t bm_rcr_get_ithresh(struct bm_portal *portal);
+void bm_rcr_set_ithresh(struct bm_portal *portal, uint8_t ithresh);
+
+
+/* ------------------------------ */
+/* --- Management command API --- */
+
+/* Create/destroy */
+t_Error bm_mc_init(struct bm_portal *portal);
+void bm_mc_finish(struct bm_portal *portal);
+
+/* Start/abort mgmt command */
+struct bm_mc_command *bm_mc_start(struct bm_portal *portal);
+void bm_mc_abort(struct bm_portal *portal);
+
+/* Writes 'verb' with appropriate 'vbit'. Invalidates and pre-fetches the
+ * response. */
+void bm_mc_commit(struct bm_portal *portal, uint8_t myverb);
+
+/* Poll for result. If NULL, invalidates and prefetches for the next call. */
+struct bm_mc_result *bm_mc_result(struct bm_portal *portal);
+
+
+/* ------------------------------------- */
+/* --- Portal interrupt register API --- */
+
+/* For a quick explanation of the Bman interrupt model, see the comments in the
+ * equivalent section of the qman_portal.h header.
+ */
+
+/* Create/destroy */
+t_Error bm_isr_init(struct bm_portal *portal);
+void bm_isr_finish(struct bm_portal *portal);
+
+/* BSCN masking is a per-portal configuration */
+void bm_isr_bscn_mask(struct bm_portal *portal, uint8_t bpid, int enable);
+
+/* Used by all portal interrupt registers except 'inhibit' */
+#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
+#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
+
+/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
+ * the disable register" rather than "disable the ability to write". */
+#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
+#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
+#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
+#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
+#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
+#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
+#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
+#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
+
+/* Don't use these, use the wrappers above*/
+uint32_t __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n);
+void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n, uint32_t val);
+
+/* ------------------------------------------------------- */
+/* --- Bman data structures (and associated constants) --- */
+/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
+ * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
+ * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
+
+#define BM_RCR_VERB_VBIT 0x80
+#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
+#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
+#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
+#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
+
+#define BM_MCC_VERB_VBIT 0x80
+#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
+#define BM_MCC_VERB_CMD_ACQUIRE 0x10
+#define BM_MCC_VERB_CMD_QUERY 0x40
+#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+_Packed struct bm_buffer {
+ volatile uint8_t reserved1;
+ volatile uint8_t bpid;
+ volatile uint16_t hi; /* High 16-bits of 48-bit address */
+ volatile uint32_t lo; /* Low 32-bits of 48-bit address */
+} _PackedType;
+
+/* See 1.5.3.5.4: "Release Command" */
+_Packed struct bm_rcr_entry {
+ _Packed union {
+ _Packed struct {
+ volatile uint8_t __dont_write_directly__verb;
+ volatile uint8_t bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
+ volatile uint8_t reserved1[62];
+ } _PackedType;
+ volatile struct bm_buffer bufs[8];
+ } _PackedType;
+} _PackedType;
+
+/* See 1.5.3.1: "Acquire Command" */
+/* See 1.5.3.2: "Query Command" */
+_Packed struct bm_mc_command {
+ volatile uint8_t __dont_write_directly__verb;
+ _Packed union {
+ _Packed struct bm_mcc_acquire {
+ volatile uint8_t bpid;
+ volatile uint8_t reserved1[62];
+ } _PackedType acquire;
+ _Packed struct bm_mcc_query {
+ volatile uint8_t reserved1[63];
+ } _PackedType query;
+ } _PackedType;
+} _PackedType;
+
+/* See 1.5.3.3: "Acquire Reponse" */
+/* See 1.5.3.4: "Query Reponse" */
+_Packed struct bm_mc_result {
+ _Packed union {
+ _Packed struct {
+ volatile uint8_t verb;
+ volatile uint8_t reserved1[63];
+ } _PackedType;
+ _Packed union {
+ _Packed struct {
+ volatile uint8_t reserved1;
+ volatile uint8_t bpid;
+ volatile uint8_t reserved2[62];
+ } _PackedType;
+ volatile struct bm_buffer bufs[8];
+ } _PackedType acquire;
+ _Packed struct {
+ volatile uint8_t reserved1[32];
+ /* "availability state" and "depletion state" */
+ _Packed struct {
+ volatile uint8_t reserved1[8];
+ /* Access using bman_depletion_***() */
+ volatile struct bman_depletion state;
+ } _PackedType as, ds;
+ } _PackedType query;
+ } _PackedType;
+} _PackedType;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+#define BM_MCR_VERB_VBIT 0x80
+#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
+#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
+#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
+#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
+#define BM_MCR_VERB_CMD_ERR_ECC 0x70
+#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
+/* Determine the "availability state" of pool 'p' from a query result 'r' */
+#define BM_MCR_QUERY_AVAILABILITY(r,p) bman_depletion_get(&r->query.as.state,p)
+/* Determine the "depletion state" of pool 'p' from a query result 'r' */
+#define BM_MCR_QUERY_DEPLETION(r,p) bman_depletion_get(&r->query.ds.state,p)
+
+
+/* Portal and Buffer Pools */
+/* ----------------------- */
+
+/* Flags to bman_create_portal() */
+#define BMAN_PORTAL_FLAG_IRQ 0x00000001 /* use interrupt handler */
+#define BMAN_PORTAL_FLAG_IRQ_FAST 0x00000002 /* ... for fast-path too! */
+#define BMAN_PORTAL_FLAG_COMPACT 0x00000004 /* use compaction algorithm */
+#define BMAN_PORTAL_FLAG_RECOVER 0x00000008 /* recovery mode */
+#define BMAN_PORTAL_FLAG_WAIT 0x00000010 /* wait if RCR is full */
+#define BMAN_PORTAL_FLAG_WAIT_INT 0x00000020 /* if wait, interruptible? */
+#define BMAN_PORTAL_FLAG_CACHE 0x00000400 /* use cache-able area for rings */
+
+/* Flags to bman_new_pool() */
+#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
+#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
+#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
+#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
+#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
+#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
+
+/* Flags to bman_release() */
+#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
+#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
+#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
+#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
+
+/* Flags to bman_acquire() */
+#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
+
+
+#endif /* __FSL_BMAN_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/HC/hc.c b/sys/contrib/ncsw/Peripherals/FM/HC/hc.c
new file mode 100644
index 0000000..134d13b
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/HC/hc.c
@@ -0,0 +1,1584 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "sprint_ext.h"
+#include "string_ext.h"
+
+#include "fm_common.h"
+#include "fm_hc.h"
+
+
+#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
+#define HC_HCOR_OPCODE_KG_SCM 0x1
+#define HC_HCOR_OPCODE_SYNC 0x2
+#define HC_HCOR_OPCODE_CC 0x3
+#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
+
+#define HC_HCOR_GBL 0x20000000
+
+#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(t_FmPcdKgInterModuleSchemeRegs)+sizeof(t_FmPcdKgPortRegs))
+#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
+#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(t_FmPcdKgInterModuleSchemeRegs)+sizeof(t_FmPcdPlcrInterModuleProfileRegs))
+#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrInterModuleProfileRegs)+sizeof(uint32_t))
+#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
+
+#define BUILD_FD(len) \
+do { \
+ memset(&fmFd, 0, sizeof(t_DpaaFD)); \
+ DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
+ DPAA_FD_SET_OFFSET(&fmFd, 0); \
+ DPAA_FD_SET_LENGTH(&fmFd, len); \
+} while (0)
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/**************************************************************************//**
+ @Description PCD KG scheme registers
+*//***************************************************************************/
+typedef _Packed struct t_FmPcdKgSchemeRegsWithoutCounter {
+ volatile uint32_t kgse_mode; /**< MODE */
+ volatile uint32_t kgse_ekfc; /**< Extract Known Fields Command */
+ volatile uint32_t kgse_ekdv; /**< Extract Known Default Value */
+ volatile uint32_t kgse_bmch; /**< Bit Mask Command High */
+ volatile uint32_t kgse_bmcl; /**< Bit Mask Command Low */
+ volatile uint32_t kgse_fqb; /**< Frame Queue Base */
+ volatile uint32_t kgse_hc; /**< Hash Command */
+ volatile uint32_t kgse_ppc; /**< Policer Profile Command */
+ volatile uint32_t kgse_gec[FM_PCD_KG_NUM_OF_GENERIC_REGS];
+ /**< Generic Extract Command */
+ volatile uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
+ volatile uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
+ volatile uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
+ volatile uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
+} _PackedType t_FmPcdKgSchemeRegsWithoutCounter;
+
+typedef _Packed struct t_FmPcdKgPortRegs {
+ volatile uint32_t spReg;
+ volatile uint32_t cppReg;
+} _PackedType t_FmPcdKgPortRegs;
+
+typedef _Packed struct t_HcFrame {
+ volatile uint32_t opcode;
+ volatile uint32_t actionReg;
+ volatile uint32_t extraReg;
+ volatile uint32_t commandSequence;
+ union {
+ t_FmPcdKgInterModuleSchemeRegs schemeRegs;
+ t_FmPcdKgInterModuleSchemeRegs schemeRegsWithoutCounter;
+ t_FmPcdPlcrInterModuleProfileRegs profileRegs;
+ volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
+ t_FmPcdKgPortRegs portRegsForRead;
+ volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
+ t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
+ } hcSpecificData;
+} _PackedType t_HcFrame;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+typedef struct t_FmHc {
+ t_Handle h_FmPcd;
+ t_Handle h_HcPortDev;
+ t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
+ t_Handle h_QmArg; /**< A handle to the QM module */
+ uint8_t padTill16;
+
+ uint32_t seqNum;
+ volatile bool wait[32];
+} t_FmHc;
+
+
+static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, volatile uint32_t *p_SeqNum)
+{
+ t_Error err = E_OK;
+ uint32_t savedSeqNum;
+ uint32_t intFlags;
+ uint32_t timeout=100;
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+ *p_SeqNum = p_FmHc->seqNum;
+ savedSeqNum = p_FmHc->seqNum;
+ p_FmHc->seqNum = (uint32_t)((p_FmHc->seqNum+1)%32);
+ ASSERT_COND(!p_FmHc->wait[savedSeqNum]);
+ p_FmHc->wait[savedSeqNum] = TRUE;
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ DBG(TRACE, ("Send Hc, SeqNum %d, FD@0x%x, fd offset 0x%x",
+ savedSeqNum,DPAA_FD_GET_ADDR(p_FmFd),DPAA_FD_GET_OFFSET(p_FmFd)));
+ err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
+ if(err)
+ RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
+
+ while (p_FmHc->wait[savedSeqNum] && --timeout)
+ XX_UDelay(100);
+
+ if (!timeout)
+ RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
+
+ return err;
+}
+
+static t_Error CcHcDoDynamicChange(t_FmHc *p_FmHc, t_Handle p_OldPointer, t_Handle p_NewPointer)
+{
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ t_Error err = E_OK;
+
+ ASSERT_COND(p_FmHc);
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
+ p_HcFrame->actionReg = FmPcdCcGetNodeAddrOffsetFromNodeInfo(p_FmHc->h_FmPcd, p_NewPointer);
+ if(p_HcFrame->actionReg == (uint32_t)ILLEGAL_BASE)
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something wrong with base address"));
+ }
+
+ p_HcFrame->actionReg |= 0xc0000000;
+ p_HcFrame->extraReg = FmPcdCcGetNodeAddrOffsetFromNodeInfo(p_FmHc->h_FmPcd, p_OldPointer);
+ if(p_HcFrame->extraReg == (uint32_t)ILLEGAL_BASE)
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something wrong with base address"));
+ }
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ XX_FreeSmart(p_HcFrame);
+
+ return E_OK;
+}
+
+static t_Error HcDynamicChange(t_FmHc *p_FmHc,t_List *h_OldPointersLst, t_List *h_NewPointersLst, t_Handle *h_Params)
+{
+
+ t_List *p_PosOld, *p_PosNew;
+ uint16_t i = 0;
+ t_Error err = E_OK;
+ uint8_t numOfModifiedPtr;
+
+ SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_NewPointersLst) == LIST_NumOfObjs(h_OldPointersLst)),E_INVALID_STATE);
+
+ numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_NewPointersLst);
+ p_PosNew = NCSW_LIST_FIRST(h_NewPointersLst);
+ p_PosOld = NCSW_LIST_FIRST(h_OldPointersLst);
+ for(i = 0; i < numOfModifiedPtr; i++)
+ {
+ err = CcHcDoDynamicChange(p_FmHc, p_PosOld, p_PosNew);
+ if(err)
+ {
+ FmPcdCcReleaseModifiedDataStructure(p_FmHc->h_FmPcd, h_OldPointersLst, h_NewPointersLst, i, h_Params);
+ RETURN_ERROR(MAJOR, err, ("For part of nodes changes are done - situation is danger"));
+ }
+ p_PosNew = NCSW_LIST_NEXT(p_PosNew);
+ p_PosOld = NCSW_LIST_NEXT(p_PosOld);
+ }
+
+ err = FmPcdCcReleaseModifiedDataStructure(p_FmHc->h_FmPcd, h_OldPointersLst, h_NewPointersLst, i, h_Params);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ return E_OK;
+}
+
+
+t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
+{
+ t_FmHc *p_FmHc;
+ t_FmPortParams fmPortParam;
+ t_Error err = E_OK;
+
+ p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
+ if (!p_FmHc)
+ {
+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
+ return NULL;
+ }
+ memset(p_FmHc,0,sizeof(t_FmHc));
+
+ p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
+ p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
+ p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
+
+ if (!FmIsMaster(p_FmHcParams->h_Fm))
+ return (t_Handle)p_FmHc;
+
+/*
+TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
+TKT038900 - FM dma lockup occur due to AXI slave protocol violation
+*/
+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
+ p_FmHc->padTill16 = 16 - (sizeof(t_FmHc) % 16);
+#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
+ memset(&fmPortParam, 0, sizeof(fmPortParam));
+ fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
+ fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
+ fmPortParam.portId = p_FmHcParams->params.portId;
+ fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
+ fmPortParam.h_Fm = p_FmHcParams->h_Fm;
+
+ fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
+ fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
+ fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
+
+ p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
+ if(!p_FmHc->h_HcPortDev)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
+ XX_Free(p_FmHc);
+ return NULL;
+ }
+
+ /* final init */
+ if ((err = FM_PORT_Init(p_FmHc->h_HcPortDev)) != E_OK)
+ {
+ REPORT_ERROR(MAJOR, err, ("FM HC port!"));
+ FmHcFree(p_FmHc);
+ return NULL;
+ }
+
+ if ((err = FM_PORT_Enable(p_FmHc->h_HcPortDev)) != E_OK)
+ {
+ REPORT_ERROR(MAJOR, err, ("FM HC port!"));
+ FmHcFree(p_FmHc);
+ return NULL;
+ }
+
+ return (t_Handle)p_FmHc;
+}
+
+void FmHcFree(t_Handle h_FmHc)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+
+ if (!p_FmHc)
+ return;
+
+ if (p_FmHc->h_HcPortDev)
+ FM_PORT_Free(p_FmHc->h_HcPortDev);
+
+ XX_Free(p_FmHc);
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FmHcDumpRegs(t_Handle h_FmHc)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmHc->h_HcPortDev, E_INVALID_HANDLE);
+
+ return FM_PORT_DumpRegs(p_FmHc->h_HcPortDev);
+
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_HcFrame *p_HcFrame;
+ uint32_t intFlags;
+
+ ASSERT_COND(p_FmHc);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+ p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
+
+ DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
+ p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
+
+ if (!(p_FmHc->wait[p_HcFrame->commandSequence]))
+ REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
+ else
+ p_FmHc->wait[p_HcFrame->commandSequence] = FALSE;
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+}
+
+t_Handle FmHcPcdKgSetScheme(t_Handle h_FmHc, t_FmPcdKgSchemeParams *p_Scheme)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Error err = E_OK;
+ t_FmPcdKgInterModuleSchemeRegs schemeRegs;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ uint32_t intFlags;
+ uint8_t physicalSchemeId, relativeSchemeId;
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ {
+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ return NULL;
+ }
+
+ if(!p_Scheme->modify)
+ {
+ /* check that schemeId is in range */
+ if(p_Scheme->id.relativeSchemeId >= FmPcdKgGetNumOfPartitionSchemes(p_FmHc->h_FmPcd))
+ {
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of range"));
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ relativeSchemeId = p_Scheme->id.relativeSchemeId;
+
+ if (FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE))
+ {
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ physicalSchemeId = FmPcdKgGetPhysicalSchemeId(p_FmHc->h_FmPcd, relativeSchemeId);
+
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ p_HcFrame->extraReg = 0xFFFFF800;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ /* check if this scheme is already used */
+ if (FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is already used"));
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+ }
+ else
+ {
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1);
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
+ if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ {
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+ err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, TRUE);
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ if (err)
+ {
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+ }
+
+ err = FmPcdKgBuildScheme(p_FmHc->h_FmPcd, p_Scheme, &schemeRegs);
+ if(err)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_Scheme->schemeCounter.update);
+ p_HcFrame->extraReg = 0xFFFFF800;
+ memcpy(&p_HcFrame->hcSpecificData.schemeRegs, &schemeRegs, sizeof(t_FmPcdKgInterModuleSchemeRegs));
+ if(!p_Scheme->schemeCounter.update)
+ {
+ p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = schemeRegs.kgse_dv0;
+ p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = schemeRegs.kgse_dv1;
+ p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = schemeRegs.kgse_ccbs;
+ p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = schemeRegs.kgse_mv;
+ }
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ FmPcdKgValidateSchemeSw(p_FmHc->h_FmPcd, relativeSchemeId);
+
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+
+ XX_FreeSmart(p_HcFrame);
+
+ return (t_Handle)(UINT_TO_PTR(physicalSchemeId + 1));
+}
+
+t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Error err = E_OK;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ uint8_t relativeSchemeId;
+ uint8_t physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
+
+ if ((err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+ }
+
+ err = FmPcdKgCheckInvalidateSchemeSw(p_FmHc->h_FmPcd, relativeSchemeId);
+ if (err)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ }
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
+ p_HcFrame->extraReg = 0xFFFFF800;
+ memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(t_FmPcdKgInterModuleSchemeRegs));
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ FmPcdKgInvalidateSchemeSw(p_FmHc->h_FmPcd, relativeSchemeId);
+
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+
+ XX_FreeSmart(p_HcFrame);
+
+ return E_OK;
+}
+
+t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Error err = E_OK;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ uint8_t relativeSchemeId;
+ uint8_t physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+ uint32_t tmpReg32 = 0;
+
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
+ if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ if (FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Lock of the scheme FAILED"));
+
+ if(!FmPcdKgGetPointedOwners(p_FmHc->h_FmPcd, relativeSchemeId) ||
+ !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
+ {
+
+ if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
+ {
+ if((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) && (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME))
+
+ {
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ }
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ p_HcFrame->extraReg = 0xFFFFF800;
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ /* check if this scheme is already used */
+ if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is already used"));
+ }
+ tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
+
+ ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
+
+ p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
+ p_HcFrame->extraReg = 0x80000000;
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ XX_FreeSmart(p_HcFrame);
+ }
+ else if (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR)
+ {
+
+ if((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
+ (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
+ }
+ err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
+ if(err)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+ }
+ }
+
+ FmPcdKgUpatePointedOwner(p_FmHc->h_FmPcd, relativeSchemeId,TRUE);
+ FmPcdKgUpdateRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId,requiredAction);
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+
+ return E_OK;
+}
+
+uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Error err = E_OK;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ uint32_t retVal;
+ uint8_t relativeSchemeId;
+ uint8_t physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
+ if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ {
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+ return 0;
+ }
+
+ if ((err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) != E_OK)
+ {
+ REPORT_ERROR(MAJOR, err, ("Scheme lock"));
+ return 0;
+ }
+
+ /* first read scheme and check that it is valid */
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ {
+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ return 0;
+ }
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ p_HcFrame->extraReg = 0xFFFFF800;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return 0;
+ }
+
+ if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
+ {
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
+ XX_FreeSmart(p_HcFrame);
+ return 0;
+ }
+
+ retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
+
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+
+ XX_FreeSmart(p_HcFrame);
+
+ return retVal;
+}
+
+t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Error err = E_OK;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ uint8_t relativeSchemeId, physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
+ if( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ if ((err = FmPcdKgSchemeTryLock(p_FmHc->h_FmPcd, relativeSchemeId, FALSE)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /* first read scheme and check that it is valid */
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ p_HcFrame->extraReg = 0xFFFFF800;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ /* check that scheme is valid */
+ if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
+ {
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
+ }
+
+ /* Write scheme back, with modified counter */
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
+ p_HcFrame->extraReg = 0xFFFFF800;
+ /* write counter */
+ p_HcFrame->hcSpecificData.schemeRegs.kgse_spc = value;
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence);
+
+ FmPcdKgReleaseSchemeLock(p_FmHc->h_FmPcd, relativeSchemeId);
+ XX_FreeSmart(p_HcFrame);
+
+ return err;
+}
+
+t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ uint32_t i;
+ t_Error err = E_OK;
+
+ ASSERT_COND(p_FmHc);
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+
+ for(i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
+ {
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
+ p_HcFrame->extraReg = 0xFFFFF800;
+ memcpy((void*)&p_HcFrame->hcSpecificData.clsPlanEntries, (void *)&p_Set->vectors[i-p_Set->baseEntry], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+ }
+ XX_FreeSmart(p_HcFrame);
+
+ return err;
+}
+
+t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
+
+ /* clear clsPlan entries in memory */
+ p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
+ if (!p_ClsPlanSet)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSetd"));
+ memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
+
+ p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
+ p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
+ ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
+
+ if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ XX_Free(p_ClsPlanSet);
+
+ FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
+
+ return E_OK;
+}
+
+t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_HcFrame *p_HcFrame;
+ uint32_t intFlags;
+ t_DpaaFD fmFd;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
+ memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
+ BUILD_FD(sizeof(t_HcFrame));
+
+ err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence);
+
+ XX_FreeSmart(p_HcFrame);
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ return err;
+}
+
+
+t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ t_Error err;
+ uint32_t tmpReg32 = 0;
+ uint32_t requiredActionTmp, pointedOwnersTmp;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
+
+ if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
+
+ if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE))
+ return ERROR_CODE(E_BUSY);
+
+
+ requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
+ pointedOwnersTmp = FmPcdPlcrGetPointedOwners(p_FmHc->h_FmPcd, absoluteProfileId);
+
+ if(!pointedOwnersTmp || !(requiredActionTmp & requiredAction))
+ {
+
+ if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
+ {
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ /* first read scheme and check that it is valid */
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
+ p_HcFrame->extraReg = 0x00008000;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ /* check that profile is valid */
+ if (!FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode))
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer is already used"));
+ }
+
+ tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
+ if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
+ }
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
+ p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
+ p_HcFrame->extraReg = 0x00008000;
+ p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
+ if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
+ }
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
+ p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
+ p_HcFrame->extraReg = 0x00008000;
+ p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
+ if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
+ }
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
+ p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
+ p_HcFrame->extraReg = 0x00008000;
+ p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+ XX_FreeSmart(p_HcFrame);
+ }
+ }
+
+ FmPcdPlcrUpatePointedOwner(p_FmHc->h_FmPcd, absoluteProfileId, TRUE);
+ FmPcdPlcrUpdateRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId, requiredAction);
+
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+
+ return E_OK;
+}
+
+t_Handle FmHcPcdPlcrSetProfile(t_Handle h_FmHc,t_FmPcdPlcrProfileParams *p_Profile)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_FmPcdPlcrInterModuleProfileRegs profileRegs;
+ t_Error err = E_OK;
+ uint32_t intFlags;
+ uint16_t profileIndx;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+
+ if (p_Profile->modify)
+ {
+ profileIndx = (uint16_t)(PTR_TO_UINT(p_Profile->id.h_Profile)-1);
+ if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, profileIndx, FALSE))
+ return NULL;
+ }
+ else
+ {
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+ err = FmPcdPlcrGetAbsoluteProfileId(p_FmHc->h_FmPcd,
+ p_Profile->id.newParams.profileType,
+ p_Profile->id.newParams.h_FmPort,
+ p_Profile->id.newParams.relativeProfileId,
+ &profileIndx);
+ if (err)
+ {
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+ err = FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, profileIndx, TRUE);
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ if (err)
+ return NULL;
+ }
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ {
+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ return NULL;
+ }
+
+ if(!p_Profile->modify)
+ {
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(profileIndx);
+ p_HcFrame->extraReg = 0x00008000;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx);
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ /* check if this scheme is already used */
+ if (FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode))
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx);
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer is already used"));
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+ }
+
+ memset(&profileRegs, 0, sizeof(t_FmPcdPlcrInterModuleProfileRegs));
+ err = FmPcdPlcrBuildProfile(p_FmHc->h_FmPcd, p_Profile, &profileRegs);
+ if(err)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
+ p_HcFrame->extraReg = 0x00008000;
+ memcpy(&p_HcFrame->hcSpecificData.profileRegs, &profileRegs, sizeof(t_FmPcdPlcrInterModuleProfileRegs));
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx);
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return NULL;
+ }
+
+ FmPcdPlcrValidateProfileSw(p_FmHc->h_FmPcd, profileIndx);
+
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, profileIndx);
+
+ XX_FreeSmart(p_HcFrame);
+
+ return UINT_TO_PTR((uint64_t)profileIndx+1);
+}
+
+t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+ t_Error err = E_OK;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+
+ if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE))
+ return ERROR_CODE(E_BUSY);
+
+ FmPcdPlcrInvalidateProfileSw(p_FmHc->h_FmPcd, absoluteProfileId);
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
+ p_HcFrame->actionReg |= 0x00008000;
+ p_HcFrame->extraReg = 0x00008000;
+ memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrInterModuleProfileRegs));
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+
+ XX_FreeSmart(p_HcFrame);
+
+ return E_OK;
+}
+
+t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
+{
+
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+ t_Error err = E_OK;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+
+ if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE))
+ return ERROR_CODE(E_BUSY);
+
+ /* first read scheme and check that it is valid */
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
+ p_HcFrame->extraReg = 0x00008000;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ /* check that profile is valid */
+ if (!FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode))
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer is already used"));
+ }
+
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
+ p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
+ p_HcFrame->extraReg = 0x00008000;
+ p_HcFrame->hcSpecificData.singleRegForWrite = value;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+
+ XX_FreeSmart(p_HcFrame);
+
+ return E_OK;
+}
+
+uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+ t_Error err = E_OK;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ uint32_t retVal = 0;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
+
+ if (FmPcdPlcrProfileTryLock(p_FmHc->h_FmPcd, absoluteProfileId, FALSE))
+ return 0;
+
+ /* first read scheme and check that it is valid */
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ {
+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ return 0;
+ }
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
+ p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
+ p_HcFrame->extraReg = 0x00008000;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ XX_FreeSmart(p_HcFrame);
+ return 0;
+ }
+
+ /* check that profile is valid */
+ if (!FmPcdPlcrHwProfileIsValid(p_HcFrame->hcSpecificData.profileRegs.fmpl_pemode))
+ {
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+ XX_FreeSmart(p_HcFrame);
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("invalid Policer profile"));
+ return 0;
+ }
+
+ switch (counter)
+ {
+ case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
+ break;
+ case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ FmPcdPlcrReleaseProfileLock(p_FmHc->h_FmPcd, absoluteProfileId);
+
+ XX_FreeSmart(p_HcFrame);
+
+ return retVal;
+}
+
+t_Error FmHcPcdCcModifyTreeNextEngine(t_Handle h_FmHc, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Error err = E_OK;
+ uint32_t intFlags;
+ t_List h_OldPointersLst, h_NewPointersLst;
+ t_Handle h_Params;
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+ err = FmPcdCcTreeTryLock(h_CcTree);
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ if (err)
+ return err;
+
+ INIT_LIST(&h_OldPointersLst);
+ INIT_LIST(&h_NewPointersLst);
+
+ err = FmPcdCcModifyNextEngineParamTree(p_FmHc->h_FmPcd, h_CcTree, grpId, index, p_FmPcdCcNextEngineParams,
+ &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+ if(err)
+ {
+ FmPcdCcTreeReleaseLock(h_CcTree);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+
+ FmPcdCcTreeReleaseLock(h_CcTree);
+
+ return err;
+}
+
+
+t_Error FmHcPcdCcModifyNodeMissNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Handle h_Params;
+ t_List h_OldPointersLst, h_NewPointersLst;
+ t_Error err = E_OK;
+ t_List h_List;
+ uint32_t intFlags;
+
+ INIT_LIST(&h_List);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+
+ if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK)
+ {
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ return err;
+ }
+
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+
+ INIT_LIST(&h_OldPointersLst);
+ INIT_LIST(&h_NewPointersLst);
+
+ err = FmPcdCcModifyMissNextEngineParamNode(p_FmHc->h_FmPcd, h_CcNode, p_FmPcdCcNextEngineParams, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+ if(err)
+ {
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+
+
+ return E_OK;
+}
+
+t_Error FmHcPcdCcRemoveKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Handle h_Params;
+ t_List h_OldPointersLst, h_NewPointersLst;
+ t_Error err = E_OK;
+ t_List h_List;
+ uint32_t intFlags;
+
+ INIT_LIST(&h_List);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+
+ if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK)
+ {
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ return err;
+ }
+
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+
+ INIT_LIST(&h_OldPointersLst);
+ INIT_LIST(&h_NewPointersLst);
+
+
+ err = FmPcdCcRemoveKey(p_FmHc->h_FmPcd,h_CcNode,keyIndex, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+ if(err)
+ {
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+
+ return err;
+
+}
+
+t_Error FmHcPcdCcAddKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Handle h_Params;
+ t_List h_OldPointersLst, h_NewPointersLst;
+ t_Error err = E_OK;
+ t_List h_List;
+ uint32_t intFlags;
+
+ INIT_LIST(&h_List);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+
+ if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK)
+ {
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ return err;
+ }
+
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+
+ INIT_LIST(&h_OldPointersLst);
+ INIT_LIST(&h_NewPointersLst);
+
+
+ err = FmPcdCcAddKey(p_FmHc->h_FmPcd,h_CcNode,keyIndex,keySize, p_KeyParams, &h_OldPointersLst,&h_NewPointersLst, &h_Params);
+ if(err)
+ {
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+
+ return err;
+}
+
+
+t_Error FmHcPcdCcModifyKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_List h_OldPointersLst, h_NewPointersLst;
+ t_Error err = E_OK;
+ t_List h_List;
+ uint32_t intFlags;
+ t_Handle h_Params;
+
+ UNUSED(keySize);
+
+ INIT_LIST(&h_List);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+
+ if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK)
+ {
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ return err;
+ }
+
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+
+ INIT_LIST(&h_OldPointersLst);
+ INIT_LIST(&h_NewPointersLst);
+
+ err = FmPcdCcModifyKey(p_FmHc->h_FmPcd, h_CcNode, keyIndex, keySize, p_Key, p_Mask, &h_OldPointersLst,&h_NewPointersLst, &h_Params);
+ if(err)
+ {
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+
+ return err;
+}
+
+t_Error FmHcPcdCcModifyNodeNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_Error err = E_OK;
+ t_List h_OldPointersLst, h_NewPointersLst;
+ t_List h_List;
+ uint32_t intFlags;
+ t_Handle h_Params;
+
+ INIT_LIST(&h_List);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+
+ if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK)
+ {
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ return err;
+ }
+
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+
+ INIT_LIST(&h_OldPointersLst);
+ INIT_LIST(&h_NewPointersLst);
+
+ err = FmPcdCcModiyNextEngineParamNode(p_FmHc->h_FmPcd, h_CcNode, keyIndex, p_FmPcdCcNextEngineParams, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+ if(err)
+ {
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+ return err;
+}
+
+
+t_Error FmHcPcdCcModifyKeyAndNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_List h_OldPointersLst, h_NewPointersLst;
+ t_Error err = E_OK;
+ t_List h_List;
+ uint32_t intFlags;
+ t_Handle h_Params;
+
+ INIT_LIST(&h_OldPointersLst);
+ INIT_LIST(&h_NewPointersLst);
+ INIT_LIST(&h_List);
+
+ intFlags = FmPcdLock(p_FmHc->h_FmPcd);
+
+ if ((err = FmPcdCcNodeTreeTryLock(p_FmHc->h_FmPcd, h_CcNode, &h_List)) != E_OK)
+ {
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+ return err;
+ }
+
+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
+
+
+ err = FmPcdCcModifyKeyAndNextEngine(p_FmHc->h_FmPcd,h_CcNode,keyIndex,keySize, p_KeyParams, &h_OldPointersLst,&h_NewPointersLst, &h_Params);
+ if(err)
+ {
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = HcDynamicChange(p_FmHc, &h_OldPointersLst, &h_NewPointersLst, &h_Params);
+
+ FmPcdCcNodeTreeReleaseLock(&h_List);
+
+
+ return err;
+}
+
+
+t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ t_Error err = E_OK;
+
+ ASSERT_COND(p_FmHc);
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ /* first read SP register */
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
+ p_HcFrame->extraReg = 0xFFFFF800;
+
+ BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ /* spReg is the first reg, so we can use it both for read and for write */
+ if(add)
+ p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
+ else
+ p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
+
+ p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ XX_FreeSmart(p_HcFrame);
+
+ return E_OK;
+}
+
+t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ t_HcFrame *p_HcFrame;
+ t_DpaaFD fmFd;
+ t_Error err = E_OK;
+
+ ASSERT_COND(p_FmHc);
+
+ p_HcFrame = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + p_FmHc->padTill16), 0, 16);
+ if (!p_HcFrame)
+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame obj"));
+ memset(p_HcFrame, 0, sizeof(t_HcFrame));
+ /* first read SP register */
+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
+ p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
+ p_HcFrame->extraReg = 0xFFFFF800;
+ p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
+
+ BUILD_FD(sizeof(t_HcFrame));
+
+ if ((err = EnQFrm(p_FmHc, &fmFd, &p_HcFrame->commandSequence)) != E_OK)
+ {
+ XX_FreeSmart(p_HcFrame);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ XX_FreeSmart(p_HcFrame);
+
+ return E_OK;
+}
+
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c
new file mode 100644
index 0000000..d543132
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c
@@ -0,0 +1,1941 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File dtsec.c
+
+ @Description FM dTSEC ...
+*//***************************************************************************/
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "xx_ext.h"
+#include "endian_ext.h"
+#include "crc_mac_addr_ext.h"
+#include "debug_ext.h"
+
+#include "fm_common.h"
+#include "dtsec.h"
+
+
+/*****************************************************************************/
+/* Internal routines */
+/*****************************************************************************/
+
+static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
+{
+ if(ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
+ if(p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
+ if(p_Dtsec->addr == 0)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
+ if(((p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)) &&
+ p_Dtsec->p_DtsecDriverParam->halfDuplex)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
+ if(p_Dtsec->p_DtsecDriverParam->halfDuplex && (p_Dtsec->p_DtsecDriverParam)->loopback)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
+#ifdef FM_NO_RX_PREAM_ERRATA_DTSECx1
+ if(p_Dtsec->p_DtsecDriverParam->preambleRxEn)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
+#endif /* FM_NO_RX_PREAM_ERRATA_DTSECx1 */
+ if(((p_Dtsec->p_DtsecDriverParam)->preambleTxEn || (p_Dtsec->p_DtsecDriverParam)->preambleRxEn) &&( (p_Dtsec->p_DtsecDriverParam)->preambleLength != 0x7))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
+ if((p_Dtsec->p_DtsecDriverParam)->fifoTxWatermarkH<((p_Dtsec->p_DtsecDriverParam)->fifoTxThr+8))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoTxWatermarkH has to be at least 8 larger than fifoTxThr"));
+ if((p_Dtsec->p_DtsecDriverParam)->halfDuplex &&
+ (p_Dtsec->p_DtsecDriverParam->txTimeStampEn || p_Dtsec->p_DtsecDriverParam->rxTimeStampEn))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
+ if((p_Dtsec->p_DtsecDriverParam)->actOnRxPauseFrame && (p_Dtsec->p_DtsecDriverParam)->controlFrameAccept )
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
+ if((p_Dtsec->p_DtsecDriverParam)->packetAlignmentPadding > MAX_PACKET_ALIGNMENT)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
+ if(((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg1 > MAX_INTER_PACKET_GAP) ||
+ ((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg2 > MAX_INTER_PACKET_GAP) ||
+ ((p_Dtsec->p_DtsecDriverParam)->backToBackIpg > MAX_INTER_PACKET_GAP))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
+ if((p_Dtsec->p_DtsecDriverParam)->alternateBackoffVal > MAX_INTER_PALTERNATE_BEB)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
+ if((p_Dtsec->p_DtsecDriverParam)->maxRetransmission > MAX_RETRANSMISSION)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
+ if((p_Dtsec->p_DtsecDriverParam)->collisionWindow > MAX_COLLISION_WINDOW)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
+
+ /* If Auto negotiation process is disabled, need to */
+ /* Set up the PHY using the MII Management Interface */
+ if (p_Dtsec->p_DtsecDriverParam->tbiPhyAddr > MAX_PHYS)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
+ if(!p_Dtsec->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
+ if(!p_Dtsec->f_Event)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
+ return E_OK;
+}
+
+static uint8_t GetMiiDiv(int32_t refClk)
+{
+ uint32_t div,tmpClk;
+ int minRange;
+
+ div = 1;
+ minRange = (int)(refClk/40 - 1);
+
+ tmpClk = (uint32_t)ABS(refClk/60 - 1);
+ if (tmpClk < minRange)
+ {
+ div = 2;
+ minRange = (int)tmpClk;
+ }
+ tmpClk = (uint32_t)ABS(refClk/60 - 1);
+ if (tmpClk < minRange)
+ {
+ div = 3;
+ minRange = (int)tmpClk;
+ }
+ tmpClk = (uint32_t)ABS(refClk/80 - 1);
+ if (tmpClk < minRange)
+ {
+ div = 4;
+ minRange = (int)tmpClk;
+ }
+ tmpClk = (uint32_t)ABS(refClk/100 - 1);
+ if (tmpClk < minRange)
+ {
+ div = 5;
+ minRange = (int)tmpClk;
+ }
+ tmpClk = (uint32_t)ABS(refClk/140 - 1);
+ if (tmpClk < minRange)
+ {
+ div = 6;
+ minRange = (int)tmpClk;
+ }
+ tmpClk = (uint32_t)ABS(refClk/280 - 1);
+ if (tmpClk < minRange)
+ {
+ div = 7;
+ minRange = (int)tmpClk;
+ }
+
+ return (uint8_t)div;
+}
+
+/* ........................................................................... */
+
+static void SetDefaultParam(t_DtsecDriverParam *p_DtsecDriverParam)
+{
+ p_DtsecDriverParam->errorDisabled = DEFAULT_errorDisabled;
+
+ p_DtsecDriverParam->promiscuousEnable = DEFAULT_promiscuousEnable;
+
+ p_DtsecDriverParam->pauseExtended = DEFAULT_pauseExtended;
+ p_DtsecDriverParam->pauseTime = DEFAULT_pauseTime;
+
+ p_DtsecDriverParam->halfDuplex = DEFAULT_halfDuplex;
+ p_DtsecDriverParam->halfDulexFlowControlEn = DEFAULT_halfDulexFlowControlEn;
+ p_DtsecDriverParam->txTimeStampEn = DEFAULT_txTimeStampEn;
+ p_DtsecDriverParam->rxTimeStampEn = DEFAULT_rxTimeStampEn;
+
+ p_DtsecDriverParam->packetAlignmentPadding = DEFAULT_packetAlignment;
+ p_DtsecDriverParam->controlFrameAccept = DEFAULT_controlFrameAccept;
+ p_DtsecDriverParam->groupHashExtend = DEFAULT_groupHashExtend;
+ p_DtsecDriverParam->broadcReject = DEFAULT_broadcReject;
+ p_DtsecDriverParam->rxShortFrame = DEFAULT_rxShortFrame;
+ p_DtsecDriverParam->exactMatch = DEFAULT_exactMatch;
+ p_DtsecDriverParam->debugMode = DEFAULT_debugMode;
+
+ p_DtsecDriverParam->loopback = DEFAULT_loopback;
+ p_DtsecDriverParam->tbiPhyAddr = DEFAULT_tbiPhyAddr;
+ p_DtsecDriverParam->actOnRxPauseFrame = DEFAULT_actOnRxPauseFrame;
+ p_DtsecDriverParam->actOnTxPauseFrame = DEFAULT_actOnTxPauseFrame;
+
+ p_DtsecDriverParam->preambleLength = DEFAULT_PreAmLength;
+ p_DtsecDriverParam->preambleRxEn = DEFAULT_PreAmRxEn;
+ p_DtsecDriverParam->preambleTxEn = DEFAULT_PreAmTxEn;
+ p_DtsecDriverParam->lengthCheckEnable = DEFAULT_lengthCheckEnable;
+ p_DtsecDriverParam->padAndCrcEnable = DEFAULT_padAndCrcEnable;
+ p_DtsecDriverParam->crcEnable = DEFAULT_crcEnable;
+
+ p_DtsecDriverParam->nonBackToBackIpg1 = DEFAULT_nonBackToBackIpg1;
+ p_DtsecDriverParam->nonBackToBackIpg2 = DEFAULT_nonBackToBackIpg2;
+ p_DtsecDriverParam->minIfgEnforcement = DEFAULT_minIfgEnforcement;
+ p_DtsecDriverParam->backToBackIpg = DEFAULT_backToBackIpg;
+
+ p_DtsecDriverParam->alternateBackoffVal = DEFAULT_altBackoffVal;
+ p_DtsecDriverParam->alternateBackoffEnable = DEFAULT_altBackoffEnable;
+ p_DtsecDriverParam->backPressureNoBackoff = DEFAULT_backPressureNoBackoff;
+ p_DtsecDriverParam->noBackoff = DEFAULT_noBackoff;
+ p_DtsecDriverParam->excessDefer = DEFAULT_excessDefer;
+ p_DtsecDriverParam->maxRetransmission = DEFAULT_maxRetransmission;
+ p_DtsecDriverParam->collisionWindow = DEFAULT_collisionWindow;
+
+ p_DtsecDriverParam->maxFrameLength = DEFAULT_maxFrameLength;
+
+ p_DtsecDriverParam->fifoTxThr = DEFAULT_fifoTxThr;
+ p_DtsecDriverParam->fifoTxWatermarkH = DEFAULT_fifoTxWatermarkH;
+
+ p_DtsecDriverParam->fifoRxWatermarkL = DEFAULT_fifoRxWatermarkL;
+}
+
+static void DtsecException(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ uint32_t event;
+ t_DtsecMemMap *p_DtsecMemMap;
+
+ ASSERT_COND(p_Dtsec);
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+ ASSERT_COND(p_DtsecMemMap);
+
+ event = GET_UINT32(p_DtsecMemMap->ievent);
+ /* handle only MDIO events */
+ event &= (IMASK_MMRDEN | IMASK_MMWREN);
+ if(event)
+ {
+ event &= GET_UINT32(p_DtsecMemMap->imask);
+
+ WRITE_UINT32(p_DtsecMemMap->ievent, event);
+
+ if(event & IMASK_MMRDEN)
+ p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
+ if(event & IMASK_MMWREN)
+ p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
+ }
+}
+
+static void UpdateStatistics(t_Dtsec *p_Dtsec)
+{
+ t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap;
+ uint32_t car1 = GET_UINT32(p_DtsecMemMap->car1);
+ uint32_t car2 = GET_UINT32(p_DtsecMemMap->car2);
+
+ if(car1)
+ {
+ WRITE_UINT32(p_DtsecMemMap->car1, car1);
+ if(car1 & CAR1_TR64)
+ p_Dtsec->internalStatistics.tr64 += VAL22BIT;
+ if(car1 & CAR1_TR127)
+ p_Dtsec->internalStatistics.tr127 += VAL22BIT;
+ if(car1 & CAR1_TR255)
+ p_Dtsec->internalStatistics.tr255 += VAL22BIT;
+ if(car1 & CAR1_TR511)
+ p_Dtsec->internalStatistics.tr511 += VAL22BIT;
+ if(car1 & CAR1_TRK1)
+ p_Dtsec->internalStatistics.tr1k += VAL22BIT;
+ if(car1 & CAR1_TRMAX)
+ p_Dtsec->internalStatistics.trmax += VAL22BIT;
+ if(car1 & CAR1_TRMGV)
+ p_Dtsec->internalStatistics.trmgv += VAL22BIT;
+ if(car1 & CAR1_RBYT)
+ p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
+ if(car1 & CAR1_RPKT)
+ p_Dtsec->internalStatistics.rpkt += VAL22BIT;
+ if(car1 & CAR1_RMCA)
+ p_Dtsec->internalStatistics.rmca += VAL22BIT;
+ if(car1 & CAR1_RBCA)
+ p_Dtsec->internalStatistics.rbca += VAL22BIT;
+ if(car1 & CAR1_RXPF)
+ p_Dtsec->internalStatistics.rxpf += VAL16BIT;
+ if(car1 & CAR1_RALN)
+ p_Dtsec->internalStatistics.raln += VAL16BIT;
+ if(car1 & CAR1_RFLR)
+ p_Dtsec->internalStatistics.rflr += VAL16BIT;
+ if(car1 & CAR1_RCDE)
+ p_Dtsec->internalStatistics.rcde += VAL16BIT;
+ if(car1 & CAR1_RCSE)
+ p_Dtsec->internalStatistics.rcse += VAL16BIT;
+ if(car1 & CAR1_RUND)
+ p_Dtsec->internalStatistics.rund += VAL16BIT;
+ if(car1 & CAR1_ROVR)
+ p_Dtsec->internalStatistics.rovr += VAL16BIT;
+ if(car1 & CAR1_RFRG)
+ p_Dtsec->internalStatistics.rfrg += VAL16BIT;
+ if(car1 & CAR1_RJBR)
+ p_Dtsec->internalStatistics.rjbr += VAL16BIT;
+ if(car1 & CAR1_RDRP)
+ p_Dtsec->internalStatistics.rdrp += VAL16BIT;
+ }
+ if(car2)
+ {
+ WRITE_UINT32(p_DtsecMemMap->car2, car2);
+ if(car2 & CAR2_TFCS)
+ p_Dtsec->internalStatistics.tfcs += VAL12BIT;
+ if(car2 & CAR2_TBYT)
+ p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
+ if(car2 & CAR2_TPKT)
+ p_Dtsec->internalStatistics.tpkt += VAL22BIT;
+ if(car2 & CAR2_TMCA)
+ p_Dtsec->internalStatistics.tmca += VAL22BIT;
+ if(car2 & CAR2_TBCA)
+ p_Dtsec->internalStatistics.tbca += VAL22BIT;
+ if(car2 & CAR2_TXPF)
+ p_Dtsec->internalStatistics.txpf += VAL16BIT;
+ if(car2 & CAR2_TDRP)
+ p_Dtsec->internalStatistics.tdrp += VAL16BIT;
+ }
+}
+
+/* .............................................................................. */
+
+static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
+
+ return (uint16_t)GET_UINT32(p_Dtsec->p_MemMap->maxfrm);
+}
+
+static void DtsecErrException(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ uint32_t event;
+ t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ event = GET_UINT32(p_DtsecMemMap->ievent);
+ /* do not handle MDIO events */
+ event &= ~(IMASK_MMRDEN | IMASK_MMWREN);
+
+ event &= GET_UINT32(p_DtsecMemMap->imask);
+
+ WRITE_UINT32(p_DtsecMemMap->ievent, event);
+
+ if(event & IMASK_BREN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
+ if(event & IMASK_RXCEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
+ if(event & IMASK_MSROEN)
+ UpdateStatistics(p_Dtsec);
+ if(event & IMASK_GTSCEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
+ if(event & IMASK_BTEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
+ if(event & IMASK_TXCEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
+ if(event & IMASK_TXEEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
+ if(event & IMASK_LCEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
+ if(event & IMASK_CRLEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
+ if(event & IMASK_XFUNEN)
+ {
+#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
+ uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
+ /* a. Write 0x00E0_0C00 to DTSEC_ID */
+ /* This is a read only regidter */
+
+ /* b. Read and save the value of TPKT */
+ tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
+
+ /* c. Read the register at dTSEC address offset 0x32C */
+ tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
+
+ /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
+ if((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
+ {
+ /* If they are not equal, save the value of this register and wait for at least
+ * MAXFRM*16 ns */
+ XX_UDelay((uint32_t)(NCSW_MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
+ }
+
+ /* e. Read and save TPKT again and read the register at dTSEC address offset
+ 0x32C again*/
+ tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
+ tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
+
+ /* f. Compare the value of TPKT saved in step b to value read in step e. Also
+ compare bits [9:15] of the register at offset 0x32C saved in step d to the value
+ of bits [9:15] saved in step e. If the two registers values are unchanged, then
+ the transmit portion of the dTSEC controller is locked up and the user should
+ proceed to the recover sequence. */
+ if((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
+ {
+ /* recover sequence */
+
+ /* a.Write a 1 to RCTRL[GRS]*/
+
+ WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
+
+ /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
+ for(i = 0 ; i < 100 ; i++ )
+ {
+ if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN)
+ break;
+ XX_UDelay(1);
+ }
+ if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN)
+ WRITE_UINT32(p_DtsecMemMap->ievent, IMASK_GRSCEN);
+ else
+ DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
+
+
+ /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
+ FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
+
+ /* d.Wait 4 Tx clocks (32 ns) */
+ XX_UDelay(1);
+
+ /* e.Write a 0 to bit n of FM_RSTC. */
+ /* cleared by FMAN */
+ }
+ else
+ {
+ /* If either value has changed, the dTSEC controller is not locked up and the
+ controller should be allowed to proceed normally by writing the reset value
+ of 0x0824_0101 to DTSEC_ID. */
+ /* Register is read only */
+ }
+#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
+
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
+ }
+ if(event & IMASK_MAGEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
+ if(event & IMASK_GRSCEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
+ if(event & IMASK_TDPEEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
+ if(event & IMASK_RDPEEN)
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
+
+ /* - masked interrupts */
+ ASSERT_COND(!(event & IMASK_ABRTEN));
+ ASSERT_COND(!(event & IMASK_IFERREN));
+}
+
+static void Dtsec1588Exception(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ uint32_t event;
+ t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ if (p_Dtsec->ptpTsuEnabled)
+ {
+ event = GET_UINT32(p_DtsecMemMap->tmr_pevent);
+ event &= GET_UINT32(p_DtsecMemMap->tmr_pemask);
+ if(event)
+ {
+ WRITE_UINT32(p_DtsecMemMap->tmr_pevent, event);
+ ASSERT_COND(event & PEMASK_TSRE);
+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
+ }
+ }
+}
+
+/* ........................................................................... */
+
+static void FreeInitResources(t_Dtsec *p_Dtsec)
+{
+ /*TODO - need to ask why with mdioIrq != 0*/
+ if ((p_Dtsec->mdioIrq != 0) && (p_Dtsec->mdioIrq != NO_IRQ))
+ {
+ XX_DisableIntr(p_Dtsec->mdioIrq);
+ XX_FreeIntr(p_Dtsec->mdioIrq);
+ }
+ else if (p_Dtsec->mdioIrq == 0)
+ FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
+ FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
+ FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
+
+ /* release the driver's group hash table */
+ FreeHashTable(p_Dtsec->p_MulticastAddrHash);
+ p_Dtsec->p_MulticastAddrHash = NULL;
+
+ /* release the driver's individual hash table */
+ FreeHashTable(p_Dtsec->p_UnicastAddrHash);
+ p_Dtsec->p_UnicastAddrHash = NULL;
+}
+
+/* ........................................................................... */
+
+static void HardwareClearAddrInPaddr(t_Dtsec *p_Dtsec, uint8_t paddrNum)
+{
+ WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match1, 0x0);
+ WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match2, 0x0);
+}
+
+/* ........................................................................... */
+
+static void HardwareAddAddrInPaddr(t_Dtsec *p_Dtsec, uint64_t *p_Addr, uint8_t paddrNum)
+{
+ uint32_t tmpReg32 = 0;
+ uint64_t addr = *p_Addr;
+ t_DtsecMemMap *p_DtsecMemMap = (t_DtsecMemMap*)p_Dtsec->p_MemMap;
+
+ tmpReg32 = (uint32_t)(addr);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match1, tmpReg32);
+
+ tmpReg32 = (uint32_t)(addr>>32);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match2, tmpReg32);
+}
+
+/* ........................................................................... */
+
+static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
+{
+ t_DtsecMemMap *p_MemMap;
+
+ ASSERT_COND(p_Dtsec);
+
+ p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
+ ASSERT_COND(p_MemMap);
+
+ /* Assert the graceful transmit stop bit */
+ if (mode & e_COMM_MODE_RX)
+ WRITE_UINT32(p_MemMap->rctrl,
+ GET_UINT32(p_MemMap->rctrl) | RCTRL_GRS);
+
+#ifdef FM_GRS_ERRATA_DTSEC_A002
+ XX_UDelay(100);
+#endif /* FM_GRS_ERRATA_DTSEC_A002 */
+
+#ifdef FM_GTS_ERRATA_DTSEC_A004
+ DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
+#else /* not FM_GTS_ERRATA_DTSEC_A004 */
+ if (mode & e_COMM_MODE_TX)
+ WRITE_UINT32(p_MemMap->tctrl,
+ GET_UINT32(p_MemMap->tctrl) | TCTRL_GTS);
+#endif /* not FM_GTS_ERRATA_DTSEC_A004 */
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
+{
+ t_DtsecMemMap *p_MemMap;
+
+ ASSERT_COND(p_Dtsec);
+
+ p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
+ ASSERT_COND(p_MemMap);
+
+ /* clear the graceful receive stop bit */
+ if(mode & e_COMM_MODE_TX)
+ WRITE_UINT32(p_MemMap->tctrl,
+ GET_UINT32(p_MemMap->tctrl) & ~TCTRL_GTS);
+
+ if(mode & e_COMM_MODE_RX)
+ WRITE_UINT32(p_MemMap->rctrl,
+ GET_UINT32(p_MemMap->rctrl) & ~RCTRL_GRS);
+
+ return E_OK;
+}
+
+
+/*****************************************************************************/
+/* dTSEC Configs modification functions */
+/*****************************************************************************/
+
+
+/* .............................................................................. */
+
+static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
+{
+
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+
+ p_Dtsec->p_DtsecDriverParam->loopback = newVal;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+
+ p_Dtsec->p_DtsecDriverParam->maxFrameLength = newVal;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+
+ p_Dtsec->p_DtsecDriverParam->padAndCrcEnable = newVal;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+
+ p_Dtsec->p_DtsecDriverParam->halfDuplex = newVal;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
+{
+#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
+UNUSED(h_Dtsec);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
+
+#else
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+
+ p_Dtsec->p_DtsecDriverParam->lengthCheckEnable = newVal;
+
+ return E_OK;
+#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
+}
+
+static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ uint32_t bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+
+ if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
+ {
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Dtsec->exceptions |= bitMask;
+ else
+ p_Dtsec->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+ }
+ else
+ {
+ if(!p_Dtsec->ptpTsuEnabled)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
+ switch(exception){
+ case(e_FM_MAC_EX_1G_1588_TS_RX_ERR):
+ if(enable)
+ p_Dtsec->enTsuErrExeption = TRUE;
+ else
+ p_Dtsec->enTsuErrExeption = FALSE;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+ }
+ }
+ return E_OK;
+}
+/*****************************************************************************/
+/* dTSEC Run Time API functions */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_MemMap ;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE);
+
+ p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
+
+ tmpReg32 = GET_UINT32(p_MemMap->maccfg1);
+ if (mode & e_COMM_MODE_RX)
+ tmpReg32 |= MACCFG1_RX_EN;
+ if (mode & e_COMM_MODE_TX)
+ tmpReg32 |= MACCFG1_TX_EN;
+ WRITE_UINT32(p_MemMap->maccfg1, tmpReg32);
+
+ GracefulRestart(p_Dtsec, mode);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_MemMap ;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE);
+
+ p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
+
+ GracefulStop(p_Dtsec, mode);
+
+ tmpReg32 = GET_UINT32(p_MemMap->maccfg1);
+ if (mode & e_COMM_MODE_RX)
+ tmpReg32 &= ~MACCFG1_RX_EN;
+ if (mode & e_COMM_MODE_TX)
+ tmpReg32 &= ~MACCFG1_TX_EN;
+ WRITE_UINT32(p_MemMap->maccfg1, tmpReg32);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ uint32_t ptv = 0;
+ t_DtsecMemMap *p_MemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE);
+
+ p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
+
+ if (pauseTime)
+ {
+#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
+ {
+ if (pauseTime <= 320)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE,
+ ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
+ " value should be greater than 320."));
+ }
+#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
+
+#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ pauseTime += 2;
+ }
+#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
+
+ ptv = GET_UINT32(p_MemMap->ptv);
+ ptv |= pauseTime;
+ WRITE_UINT32(p_MemMap->ptv, ptv);
+
+ /* trigger the transmission of a flow-control pause frame */
+ WRITE_UINT32(p_MemMap->maccfg1,
+ GET_UINT32(p_MemMap->maccfg1) | MACCFG1_TX_FLOW);
+ }
+ else
+ {
+ WRITE_UINT32(p_MemMap->maccfg1,
+ GET_UINT32(p_MemMap->maccfg1) & ~MACCFG1_TX_FLOW);
+ }
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_MemMap;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE);
+
+ p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
+
+ tmpReg32 = GET_UINT32(p_MemMap->maccfg1);
+ if (en)
+ tmpReg32 &= ~MACCFG1_RX_FLOW;
+ else
+ tmpReg32 |= MACCFG1_RX_FLOW;
+ WRITE_UINT32(p_MemMap->maccfg1, tmpReg32);
+
+ return E_OK;
+}
+
+
+/* .............................................................................. */
+
+static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+#ifdef FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3
+ if((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("1588TimeStamp in 10/100 SGMII"));
+#endif /* FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3 */
+ p_Dtsec->ptpTsuEnabled = TRUE;
+ WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) | RCTRL_RTSE);
+ WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) | TCTRL_TTSE);
+
+ return E_OK;
+}
+
+static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+
+ p_Dtsec->ptpTsuEnabled = FALSE;
+ WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) & ~RCTRL_RTSE);
+ WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) & ~TCTRL_TTSE);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
+
+ if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+ memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
+
+ if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
+ {
+ p_Statistics->eStatPkts64 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr64))
+ + p_Dtsec->internalStatistics.tr64; /**< r-10G tr-DT 64 byte frame counter */
+ p_Statistics->eStatPkts65to127 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr127))
+ + p_Dtsec->internalStatistics.tr127; /**< r-10G 65 to 127 byte frame counter */
+ p_Statistics->eStatPkts128to255 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr255))
+ + p_Dtsec->internalStatistics.tr255; /**< r-10G 128 to 255 byte frame counter */
+ p_Statistics->eStatPkts256to511 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr511))
+ + p_Dtsec->internalStatistics.tr511; /**< r-10G 256 to 511 byte frame counter */
+ p_Statistics->eStatPkts512to1023 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr1k))
+ + p_Dtsec->internalStatistics.tr1k; /**< r-10G 512 to 1023 byte frame counter */
+ p_Statistics->eStatPkts1024to1518 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmax))
+ + p_Dtsec->internalStatistics.trmax; /**< r-10G 1024 to 1518 byte frame counter */
+ p_Statistics->eStatPkts1519to1522 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmgv))
+ + p_Dtsec->internalStatistics.trmgv; /**< r-10G 1519 to 1522 byte good frame count */
+ /* MIB II */
+ p_Statistics->ifInOctets = GET_UINT32(p_DtsecMemMap->rbyt)
+ + p_Dtsec->internalStatistics.rbyt; /**< Total number of byte received. */
+ p_Statistics->ifInPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rpkt))
+ + p_Dtsec->internalStatistics.rpkt; /**< Total number of packets received.*/
+ p_Statistics->ifInMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rmca))
+ + p_Dtsec->internalStatistics.rmca; /**< Total number of multicast frame received*/
+ p_Statistics->ifInBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rbca))
+ + p_Dtsec->internalStatistics.rbca; /**< Total number of broadcast frame received */
+ p_Statistics->ifOutOctets = GET_UINT32(p_DtsecMemMap->tbyt)
+ + p_Dtsec->internalStatistics.tbyt; /**< Total number of byte sent. */
+ p_Statistics->ifOutPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tpkt))
+ + p_Dtsec->internalStatistics.tpkt; /**< Total number of packets sent .*/
+ p_Statistics->ifOutMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tmca))
+ + p_Dtsec->internalStatistics.tmca; /**< Total number of multicast frame sent */
+ p_Statistics->ifOutBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tbca))
+ + p_Dtsec->internalStatistics.tbca; /**< Total number of multicast frame sent */
+ }
+/* */
+ p_Statistics->eStatFragments = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rfrg))
+ + p_Dtsec->internalStatistics.rfrg; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
+ p_Statistics->eStatJabbers = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rjbr))
+ + p_Dtsec->internalStatistics.rjbr; /**< Total number of packets longer than valid maximum length octets */
+
+ p_Statistics->eStatsDropEvents = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rdrp))
+ + p_Dtsec->internalStatistics.rdrp; /**< number of dropped packets due to internal errors of the MAC Client. */
+ p_Statistics->eStatCRCAlignErrors = (MASK16BIT & GET_UINT32(p_DtsecMemMap->raln))
+ + p_Dtsec->internalStatistics.raln; /**< Incremented when frames of correct length but with CRC error are received.*/
+
+ p_Statistics->eStatUndersizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rund))
+ + p_Dtsec->internalStatistics.rund; /**< Total number of packets that were less than 64 octets long with a good CRC.*/
+ p_Statistics->eStatOversizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rovr))
+ + p_Dtsec->internalStatistics.rovr; /**< T,B.D*/
+/* Pause */
+ p_Statistics->reStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rxpf))
+ + p_Dtsec->internalStatistics.rxpf; /**< Pause MAC Control received */
+ p_Statistics->teStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->txpf))
+ + p_Dtsec->internalStatistics.txpf; /**< Pause MAC Control sent */
+
+ p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents; /**< Frames received, but discarded due to problems within the MAC RX. */
+
+ p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents
+ + p_Statistics->eStatCRCAlignErrors
+ + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rflr))
+ + p_Dtsec->internalStatistics.rflr
+ + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcde))
+ + p_Dtsec->internalStatistics.rcde
+ + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcse))
+ + p_Dtsec->internalStatistics.rcse;
+
+ p_Statistics->ifOutDiscards = (MASK16BIT & GET_UINT32(p_DtsecMemMap->tdrp))
+ + p_Dtsec->internalStatistics.tdrp; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
+ p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
+ + (MASK12BIT & GET_UINT32(p_DtsecMemMap->tfcs))
+ + p_Dtsec->internalStatistics.tfcs;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+ uint32_t tmpReg32 = 0;
+ uint64_t addr;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+ /* Initialize MAC Station Address registers (1 & 2) */
+ /* Station address have to be swapped (big endian to little endian */
+ addr = ((*(uint64_t *)p_EnetAddr) >> 16);
+ p_Dtsec->addr = addr;
+
+ tmpReg32 = (uint32_t)(addr);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32);
+
+ tmpReg32 = (uint32_t)(addr>>32);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecResetCounters (t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+
+ /* clear HW counters */
+ WRITE_UINT32(p_Dtsec->p_MemMap->ecntrl, GET_UINT32(p_Dtsec->p_MemMap->ecntrl) | ECNTRL_CLRCNT);
+
+ /* clear SW counters holding carries */
+ memset((char *)&p_Dtsec->internalStatistics, (char)0x0, sizeof(t_InternalStatistics));
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
+ uint64_t ethAddr;
+ uint8_t paddrNum;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ if (ethAddr & GROUP_ADDRESS)
+ /* Multicast address has no effect in PADDR */
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
+
+ /* Make sure no PADDR contains this address */
+ for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
+ if (p_Dtsec->indAddrRegUsed[paddrNum])
+ if (p_Dtsec->paddr[paddrNum] == ethAddr)
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
+
+ /* Find first unused PADDR */
+ for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
+ if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
+ {
+ /* mark this PADDR as used */
+ p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
+ /* store address */
+ p_Dtsec->paddr[paddrNum] = ethAddr;
+
+ /* put in hardware */
+ HardwareAddAddrInPaddr(p_Dtsec, &ethAddr, paddrNum);
+ p_Dtsec->numOfIndAddrInRegs++;
+
+ return E_OK;
+ }
+
+ /* No free PADDR */
+ RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
+ uint64_t ethAddr;
+ uint8_t paddrNum;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ /* Find used PADDR containing this address */
+ for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
+ {
+ if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
+ (p_Dtsec->paddr[paddrNum] == ethAddr))
+ {
+ /* mark this PADDR as not used */
+ p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
+ /* clear in hardware */
+ HardwareClearAddrInPaddr(p_Dtsec, paddrNum);
+ p_Dtsec->numOfIndAddrInRegs--;
+
+ return E_OK;
+ }
+ }
+
+ RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+ uint32_t crc;
+ uint8_t crcMirror, reg;
+ uint32_t bitMask;
+ t_EthHashEntry *p_HashEntry;
+ uint64_t ethAddr;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ /* CRC calculation */
+ GET_MAC_ADDR_CRC(ethAddr, crc);
+
+ /* calculate the "crc mirror" */
+ crcMirror = MIRROR((uint8_t)crc);
+
+ /* 3 MSB bits define the register */
+ reg = (uint8_t)(crcMirror >> 5);
+ /* 5 LSB bits define the bit within the register */
+ bitMask = 0x80000000 >> (crcMirror & 0x1f);
+
+ /* Create element to be added to the driver hash table */
+ p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
+ p_HashEntry->addr = ethAddr;
+ INIT_LIST(&p_HashEntry->node);
+
+ if (ethAddr & GROUP_ADDRESS)
+ {
+ /* Group Address */
+ LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror]));
+ /* Set the appropriate bit in GADDR0-7 */
+ WRITE_UINT32(p_DtsecMemMap->gaddr[reg],
+ GET_UINT32(p_DtsecMemMap->gaddr[reg]) | bitMask);
+ }
+ else
+ {
+ LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror]));
+ /* Set the appropriate bit in IADDR0-7 */
+ WRITE_UINT32(p_DtsecMemMap->igaddr[reg],
+ GET_UINT32(p_DtsecMemMap->igaddr[reg]) | bitMask);
+ }
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+ t_List *p_Pos;
+ uint32_t crc;
+ uint8_t crcMirror, reg;
+ uint32_t bitMask;
+ t_EthHashEntry *p_HashEntry = NULL;
+ uint64_t ethAddr;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ /* CRC calculation */
+ GET_MAC_ADDR_CRC(ethAddr, crc);
+
+ /* calculate the "crc mirror" */
+ crcMirror = MIRROR((uint8_t)crc);
+
+ /* 3 MSB bits define the register */
+ reg =(uint8_t)( crcMirror >> 5);
+ /* 5 LSB bits define the bit within the register */
+ bitMask = 0x80000000 >> (crcMirror & 0x1f);
+
+ if (ethAddr & GROUP_ADDRESS)
+ {
+ /* Group Address */
+ LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror]))
+ {
+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
+ if(p_HashEntry->addr == ethAddr)
+ {
+ LIST_DelAndInit(&p_HashEntry->node);
+ XX_Free(p_HashEntry);
+ break;
+ }
+ }
+ if(LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror]))
+ WRITE_UINT32(p_DtsecMemMap->gaddr[reg],
+ GET_UINT32(p_DtsecMemMap->gaddr[reg]) & ~bitMask);
+ }
+ else
+ {
+ /* Individual Address */
+ LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror]))
+ {
+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
+ if(p_HashEntry->addr == ethAddr)
+ {
+ LIST_DelAndInit(&p_HashEntry->node);
+ XX_Free(p_HashEntry);
+ break;
+ }
+ }
+ if(LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror]))
+ WRITE_UINT32(p_DtsecMemMap->igaddr[reg],
+ GET_UINT32(p_DtsecMemMap->igaddr[reg]) & ~bitMask);
+ }
+
+ /* address does not exist */
+ ASSERT_COND(p_HashEntry != NULL);
+
+ return E_OK;
+}
+
+
+/* .............................................................................. */
+
+static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ tmpReg32 = GET_UINT32(p_DtsecMemMap->rctrl);
+
+ if (newVal)
+ tmpReg32 |= RCTRL_PROM;
+ else
+ tmpReg32 &= ~RCTRL_PROM;
+
+ WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ p_Dtsec->statisticsLevel = statisticsLevel;
+
+ switch (p_Dtsec->statisticsLevel)
+ {
+ case(e_FM_MAC_NONE_STATISTICS):
+ WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff);
+ WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff);
+ WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) & ~ECNTRL_STEN);
+ WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) & ~IMASK_MSROEN);
+ p_Dtsec->exceptions &= ~IMASK_MSROEN;
+ break;
+ case(e_FM_MAC_PARTIAL_STATISTICS):
+ WRITE_UINT32(p_DtsecMemMap->cam1, CAM1_ERRORS_ONLY);
+ WRITE_UINT32(p_DtsecMemMap->cam2, CAM2_ERRORS_ONLY);
+ WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN);
+ WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN);
+ p_Dtsec->exceptions |= IMASK_MSROEN;
+ break;
+ case(e_FM_MAC_FULL_STATISTICS):
+ WRITE_UINT32(p_DtsecMemMap->cam1,0);
+ WRITE_UINT32(p_DtsecMemMap->cam2,0);
+ WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN);
+ WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN);
+ p_Dtsec->exceptions |= IMASK_MSROEN;
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+ SANITY_CHECK_RETURN_ERROR(p_DtsecMemMap, E_INVALID_HANDLE);
+
+ if ((!fullDuplex) && (speed >= e_ENET_SPEED_1000))
+ RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
+
+ p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
+ p_Dtsec->halfDuplex = !fullDuplex;
+
+ tmpReg32 = GET_UINT32(p_DtsecMemMap->maccfg2);
+ if(p_Dtsec->halfDuplex)
+ tmpReg32 &= ~MACCFG2_FULL_DUPLEX;
+ else
+ tmpReg32 |= MACCFG2_FULL_DUPLEX;
+
+ tmpReg32 &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
+ if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
+ tmpReg32 |= MACCFG2_NIBBLE_MODE;
+ else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)||
+ (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000))
+ tmpReg32 |= MACCFG2_BYTE_MODE;
+ WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32);
+
+ tmpReg32 = GET_UINT32(p_DtsecMemMap->ecntrl);
+ if (!(tmpReg32 & ECNTRL_CFG_RO))
+ {
+ if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
+ tmpReg32 |= ECNTRL_R100M;
+ else
+ tmpReg32 &= ~ECNTRL_R100M;
+ WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32);
+ }
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
+
+ *macId = p_Dtsec->macId;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecMemMap *p_DtsecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+ *macVersion = GET_UINT32(p_DtsecMemMap->tsec_id1);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ uint32_t tmpReg, bitMask = 0;
+ t_DtsecMemMap *p_DtsecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
+
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
+ {
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Dtsec->exceptions |= bitMask;
+ else
+ p_Dtsec->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ tmpReg = GET_UINT32(p_DtsecMemMap->imask);
+ if(enable)
+ tmpReg |= bitMask;
+ else
+ tmpReg &= ~bitMask;
+ WRITE_UINT32(p_DtsecMemMap->imask, tmpReg);
+
+ /* warn if MIB OVFL is disabled and statistic gathering is enabled */
+ if((exception == e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL) &&
+ !enable &&
+ (p_Dtsec->statisticsLevel != e_FM_MAC_NONE_STATISTICS))
+ DBG(WARNING, ("Disabled MIB counters overflow exceptions. Counters value may be inaccurate due to unregistered overflow"));
+
+ }
+ else
+ {
+ if(!p_Dtsec->ptpTsuEnabled)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
+ tmpReg = GET_UINT32(p_DtsecMemMap->tmr_pemask);
+ switch(exception){
+ case(e_FM_MAC_EX_1G_1588_TS_RX_ERR):
+ if(enable)
+ {
+ p_Dtsec->enTsuErrExeption = TRUE;
+ WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg | PEMASK_TSRE);
+ }
+ else
+ {
+ p_Dtsec->enTsuErrExeption = FALSE;
+ WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg & ~PEMASK_TSRE);
+ }
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+ }
+ }
+
+ return E_OK;
+}
+
+/* ........................................................................... */
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+static t_Error DtsecDumpRegs(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ int i = 0;
+
+ DECLARE_DUMP;
+
+ if (p_Dtsec->p_MemMap)
+ {
+
+ DUMP_TITLE(p_Dtsec->p_MemMap, ("MAC %d: ", p_Dtsec->macId));
+ DUMP_VAR(p_Dtsec->p_MemMap, tsec_id1);
+ DUMP_VAR(p_Dtsec->p_MemMap, tsec_id2);
+ DUMP_VAR(p_Dtsec->p_MemMap, ievent);
+ DUMP_VAR(p_Dtsec->p_MemMap, imask);
+ DUMP_VAR(p_Dtsec->p_MemMap, edis);
+ DUMP_VAR(p_Dtsec->p_MemMap, ecntrl);
+ DUMP_VAR(p_Dtsec->p_MemMap, ptv);
+ DUMP_VAR(p_Dtsec->p_MemMap, tmr_ctrl);
+ DUMP_VAR(p_Dtsec->p_MemMap, tmr_pevent);
+ DUMP_VAR(p_Dtsec->p_MemMap, tmr_pemask);
+ DUMP_VAR(p_Dtsec->p_MemMap, tctrl);
+ DUMP_VAR(p_Dtsec->p_MemMap, rctrl);
+ DUMP_VAR(p_Dtsec->p_MemMap, maccfg1);
+ DUMP_VAR(p_Dtsec->p_MemMap, maccfg2);
+ DUMP_VAR(p_Dtsec->p_MemMap, ipgifg);
+ DUMP_VAR(p_Dtsec->p_MemMap, hafdup);
+ DUMP_VAR(p_Dtsec->p_MemMap, maxfrm);
+
+ DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr1);
+ DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr2);
+
+ DUMP_SUBSTRUCT_ARRAY(i, 8)
+ {
+ DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match1);
+ DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match2);
+ }
+ }
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+
+/*****************************************************************************/
+/* FM Init & Free API */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+static t_Error DtsecInit(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_DtsecDriverParam *p_DtsecDriverParam;
+ t_DtsecMemMap *p_DtsecMemMap;
+ int i;
+ uint32_t tmpReg32;
+ uint64_t addr;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE);
+
+ CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
+
+ p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
+ p_Dtsec->halfDuplex = p_DtsecDriverParam->halfDuplex;
+ p_Dtsec->debugMode = p_DtsecDriverParam->debugMode;
+ p_DtsecMemMap = p_Dtsec->p_MemMap;
+
+ /*************dtsec_id2******************/
+ tmpReg32 = GET_UINT32(p_DtsecMemMap->tsec_id2);
+
+ if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RMII_100))
+ if(tmpReg32 & ID2_INT_REDUCED_OFF)
+ {
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for reduced interface in current DTSEC version"));
+ }
+
+ if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)||
+ (p_Dtsec->enetMode == e_ENET_MODE_MII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_MII_100))
+ if(tmpReg32 & ID2_INT_NORMAL_OFF)
+ {
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for normal interface in current DTSEC version"));
+ }
+ /*************dtsec_id2******************/
+
+ /***************EDIS************************/
+ WRITE_UINT32(p_DtsecMemMap->edis, p_DtsecDriverParam->errorDisabled);
+ /***************EDIS************************/
+
+ /***************ECNTRL************************/
+ tmpReg32 = 0;
+ if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000))
+ tmpReg32 |= ECNTRL_GMIIM;
+ if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000))
+ tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM);
+ if (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)
+ tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM | ECNTRL_QSGMIIM);
+ if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10)||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100))
+ tmpReg32 |= ECNTRL_RPM;
+ if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RMII_100))
+ tmpReg32 |= ECNTRL_R100M;
+ if ((p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_RMII_100))
+ tmpReg32 |= ECNTRL_RMM;
+ WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32);
+ /***************ECNTRL************************/
+
+ /***************PTV************************/
+ tmpReg32 = 0;
+#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ p_DtsecDriverParam->pauseTime += 2;
+ }
+#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
+ if (p_DtsecDriverParam->pauseTime)
+ tmpReg32 |= (uint32_t)p_DtsecDriverParam->pauseTime;
+
+ if (p_DtsecDriverParam->pauseExtended)
+ tmpReg32 |= ((uint32_t)p_DtsecDriverParam->pauseExtended) << PTV_PTE_OFST;
+ WRITE_UINT32(p_DtsecMemMap->ptv, tmpReg32);
+ /***************PTV************************/
+
+ /***************TCTRL************************/
+ tmpReg32 = 0;
+ if(p_DtsecDriverParam->halfDuplex)
+ {
+ if(p_DtsecDriverParam->halfDulexFlowControlEn)
+ tmpReg32 |= TCTRL_THDF;
+ }
+ else
+ {
+ if(p_DtsecDriverParam->txTimeStampEn)
+ tmpReg32 |= TCTRL_TTSE;
+ }
+ WRITE_UINT32(p_DtsecMemMap->tctrl, tmpReg32);
+ /***************TCTRL************************/
+
+ /***************RCTRL************************/
+ tmpReg32 = 0;
+ if (p_DtsecDriverParam->packetAlignmentPadding)
+ tmpReg32 |= ((uint32_t)(0x0000001f & p_DtsecDriverParam->packetAlignmentPadding)) << 16;
+ if (p_DtsecDriverParam->controlFrameAccept)
+ tmpReg32 |= RCTRL_CFA;
+ if (p_DtsecDriverParam->groupHashExtend)
+ tmpReg32 |= RCTRL_GHTX;
+ if(p_DtsecDriverParam->rxTimeStampEn)
+ tmpReg32 |= RCTRL_RTSE;
+ if (p_DtsecDriverParam->broadcReject)
+ tmpReg32 |= RCTRL_BC_REJ;
+ if (p_DtsecDriverParam->rxShortFrame)
+ tmpReg32 |= RCTRL_RSF;
+ if (p_DtsecDriverParam->promiscuousEnable)
+ tmpReg32 |= RCTRL_PROM;
+ if (p_DtsecDriverParam->exactMatch)
+ tmpReg32 |= RCTRL_EMEN;
+
+ WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32);
+ /***************RCTRL************************/
+
+ /* Assign a Phy Address to the TBI (TBIPA). */
+ /* Done also in case that TBI is not selected to avoid */
+ /* conflict with the external PHY’s Physical address */
+ WRITE_UINT32(p_DtsecMemMap->tbipa, p_DtsecDriverParam->tbiPhyAddr);
+
+ /* Reset the management interface */
+ WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, MIIMCFG_RESET_MGMT);
+ WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, ~MIIMCFG_RESET_MGMT);
+ /* Setup the MII Mgmt clock speed */
+ WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg,
+ (uint32_t)GetMiiDiv((int32_t)(((p_Dtsec->fmMacControllerDriver.clkFreq*10)/2)/8)));
+
+ if(p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)
+ {
+ uint16_t tmpReg16;
+
+ /* Configure the TBI PHY Control Register */
+ tmpReg16 = PHY_TBICON_SPEED2 | PHY_TBICON_SRESET;
+
+ DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16);
+
+ tmpReg16 = PHY_TBICON_SPEED2;
+
+ DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16);
+
+ if(!p_DtsecDriverParam->halfDuplex)
+ tmpReg16 |= PHY_CR_FULLDUPLEX | 0x8000 | PHY_CR_ANE;
+
+ DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16);
+
+ tmpReg16 = 0x01a0;
+ DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 4, tmpReg16);
+
+ tmpReg16 = 0x1340;
+ DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16);
+ }
+
+ /***************TMR_CTL************************/
+ WRITE_UINT32(p_DtsecMemMap->tmr_ctrl, 0);
+
+ if(p_Dtsec->ptpTsuEnabled)
+ {
+ tmpReg32 = 0;
+ if (p_Dtsec->enTsuErrExeption)
+ tmpReg32 |= PEMASK_TSRE;
+ WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg32);
+ WRITE_UINT32(p_DtsecMemMap->tmr_pevent, tmpReg32);
+ }
+
+ /***************DEBUG************************/
+ tmpReg32 = 0;
+ if(p_DtsecDriverParam->debugMode)
+ WRITE_UINT32(p_DtsecMemMap->tsec_id1, TSEC_ID1_DEBUG);
+ /***************DEBUG************************/
+
+ /***************MACCFG1***********************/
+ WRITE_UINT32(p_DtsecMemMap->maccfg1, MACCFG1_SOFT_RESET);
+ WRITE_UINT32(p_DtsecMemMap->maccfg1, 0);
+ tmpReg32 = 0;
+ if(p_DtsecDriverParam->loopback)
+ tmpReg32 |= MACCFG1_LOOPBACK;
+ if(p_DtsecDriverParam->actOnRxPauseFrame)
+ tmpReg32 |= MACCFG1_RX_FLOW;
+ if(p_DtsecDriverParam->actOnTxPauseFrame)
+ tmpReg32 |= MACCFG1_TX_FLOW;
+ WRITE_UINT32(p_DtsecMemMap->maccfg1, tmpReg32);
+ /***************MACCFG1***********************/
+
+ /***************MACCFG2***********************/
+ tmpReg32 = 0;
+ if( (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RMII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_MII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_MII_100) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
+ tmpReg32 |= MACCFG2_NIBBLE_MODE;
+ else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
+ (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)||
+ (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)||
+ (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000))
+ tmpReg32 |= MACCFG2_BYTE_MODE;
+
+ tmpReg32 |= (((uint32_t)p_DtsecDriverParam->preambleLength) & 0x0000000f)<< PREAMBLE_LENGTH_SHIFT;
+
+ if(p_DtsecDriverParam->preambleRxEn)
+ tmpReg32 |= MACCFG2_PRE_AM_Rx_EN;
+ if(p_DtsecDriverParam->preambleTxEn)
+ tmpReg32 |= MACCFG2_PRE_AM_Tx_EN;
+ if(p_DtsecDriverParam->lengthCheckEnable)
+ tmpReg32 |= MACCFG2_LENGTH_CHECK;
+ if(p_DtsecDriverParam->padAndCrcEnable)
+ tmpReg32 |= MACCFG2_PAD_CRC_EN;
+ if(p_DtsecDriverParam->crcEnable)
+ tmpReg32 |= MACCFG2_CRC_EN;
+ if(!p_DtsecDriverParam->halfDuplex)
+ tmpReg32 |= MACCFG2_FULL_DUPLEX;
+ WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32);
+ /***************MACCFG2***********************/
+
+ /***************IPGIFG************************/
+ tmpReg32 = 0;
+ ASSERT_COND(p_DtsecDriverParam->nonBackToBackIpg1 <= p_DtsecDriverParam->nonBackToBackIpg2);
+ tmpReg32 = (uint32_t)((((uint32_t)p_DtsecDriverParam->nonBackToBackIpg1 <<
+ IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_1) |
+ (((uint32_t)p_DtsecDriverParam->nonBackToBackIpg2 <<
+ IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_2) |
+ (((uint32_t)p_DtsecDriverParam->minIfgEnforcement <<
+ IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT) & IPGIFG_MIN_IFG_ENFORCEMENT) |
+ ((uint32_t)p_DtsecDriverParam->backToBackIpg & IPGIFG_BACK_TO_BACK_IPG));
+ WRITE_UINT32(p_DtsecMemMap->ipgifg, tmpReg32);
+ /***************IPGIFG************************/
+
+ /***************HAFDUP************************/
+ tmpReg32 = 0;
+ if(p_DtsecDriverParam->alternateBackoffEnable)
+ {
+ tmpReg32 = (uint32_t) (HAFDUP_ALT_BEB | (((uint32_t)p_DtsecDriverParam->alternateBackoffVal & 0x0000000f) <<
+ HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
+ }
+
+ if(p_DtsecDriverParam->backPressureNoBackoff)
+ tmpReg32 |= HAFDUP_BP_NO_BACKOFF;
+ if(p_DtsecDriverParam->noBackoff)
+ tmpReg32 |= HAFDUP_NO_BACKOFF;
+ if(p_DtsecDriverParam->excessDefer)
+ tmpReg32 |= HAFDUP_EXCESS_DEFER;
+ tmpReg32 |= (((uint32_t)p_DtsecDriverParam->maxRetransmission <<
+ HAFDUP_RETRANSMISSION_MAX_SHIFT )& HAFDUP_RETRANSMISSION_MAX);
+ tmpReg32|= ((uint32_t)p_DtsecDriverParam->collisionWindow & HAFDUP_COLLISION_WINDOW);
+
+ WRITE_UINT32(p_DtsecMemMap->hafdup, tmpReg32);
+ /***************HAFDUP************************/
+
+ /***************MAXFRM************************/
+ /* Initialize MAXFRM */
+ WRITE_UINT32(p_DtsecMemMap->maxfrm,
+ p_DtsecDriverParam->maxFrameLength);
+ err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm,
+ e_FM_MAC_1G,
+ p_Dtsec->fmMacControllerDriver.macId,
+ p_DtsecDriverParam->maxFrameLength);
+ if (err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ /***************MAXFRM************************/
+
+ /***************CAM1************************/
+ WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff);
+ WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff);
+
+ /***************IMASK************************/
+ WRITE_UINT32(p_DtsecMemMap->imask, p_Dtsec->exceptions);
+ /***************IMASK************************/
+
+ /***************IEVENT************************/
+ WRITE_UINT32(p_DtsecMemMap->ievent, EVENTS_MASK);
+
+ /***************MACSTNADDR1/2*****************/
+ /* Initialize MAC Station Address registers (1 & 2) */
+ /* Station address have to be swapped (big endian to little endian */
+ addr = p_Dtsec->addr;
+
+ tmpReg32 = (uint32_t)(addr);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32);
+
+ tmpReg32 = (uint32_t)(addr>>32);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32);
+ /***************MACSTNADDR1/2*****************/
+
+ /***************DEBUG*****************/
+ WRITE_UINT32(p_DtsecMemMap->tx_threshold, (uint32_t)(p_DtsecDriverParam->fifoTxThr & 0x7f));
+ WRITE_UINT32(p_DtsecMemMap->tx_watermark_high, (uint32_t)(p_DtsecDriverParam->fifoTxWatermarkH & 0x7f));
+ WRITE_UINT32(p_DtsecMemMap->rx_watermark_low, (uint32_t)(p_DtsecDriverParam->fifoRxWatermarkL & 0x7f));
+ /***************DEBUG*****************/
+
+ /*****************HASH************************/
+ for(i=0 ; i<NUM_OF_HASH_REGS ; i++)
+ {
+ /* Initialize IADDRx */
+ WRITE_UINT32(p_DtsecMemMap->igaddr[i], 0);
+ /* Initialize GADDRx */
+ WRITE_UINT32(p_DtsecMemMap->gaddr[i], 0);
+ }
+
+ p_Dtsec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
+ if(!p_Dtsec->p_MulticastAddrHash)
+ {
+ FreeInitResources(p_Dtsec);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
+ }
+
+ p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
+ if(!p_Dtsec->p_UnicastAddrHash)
+ {
+ FreeInitResources(p_Dtsec);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
+ }
+
+ /* register err intr handler for dtsec to FPM (err)*/
+ FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR, DtsecErrException , p_Dtsec);
+ /* register 1588 intr handler for TMR to FPM (normal)*/
+ FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL, Dtsec1588Exception , p_Dtsec);
+ /* register normal intr handler for dtsec to main interrupt controller. */
+ if (p_Dtsec->mdioIrq != NO_IRQ)
+ {
+ XX_SetIntr(p_Dtsec->mdioIrq, DtsecException, p_Dtsec);
+ XX_EnableIntr(p_Dtsec->mdioIrq);
+ }
+
+ XX_Free(p_DtsecDriverParam);
+ p_Dtsec->p_DtsecDriverParam = NULL;
+
+ err = DtsecSetStatistics(p_Dtsec, e_FM_MAC_FULL_STATISTICS);
+ if(err)
+ {
+ FreeInitResources(p_Dtsec);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+/* ........................................................................... */
+
+static t_Error DtsecFree(t_Handle h_Dtsec)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+
+ FreeInitResources(p_Dtsec);
+
+ if (p_Dtsec->p_DtsecDriverParam)
+ {
+ XX_Free(p_Dtsec->p_DtsecDriverParam);
+ p_Dtsec->p_DtsecDriverParam = NULL;
+ }
+ XX_Free (h_Dtsec);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
+{
+ p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
+ p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
+
+ p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
+ p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
+ p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
+
+ p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
+
+ p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
+ p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
+ p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
+ p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
+
+ p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
+ p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
+
+ p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
+
+ p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
+ p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
+
+ p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
+ p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
+
+ p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
+ p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
+
+ p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
+ p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
+
+ p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
+ p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
+ p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
+
+ p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
+ p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_FmMacControllerDriver->f_FM_MAC_DumpRegs = DtsecDumpRegs;
+#endif /* (defined(DEBUG_ERRORS) && ... */
+}
+
+
+/*****************************************************************************/
+/* dTSEC Config Main Entry */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
+{
+ t_Dtsec *p_Dtsec;
+ t_DtsecDriverParam *p_DtsecDriverParam;
+ uintptr_t baseAddr;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
+
+ baseAddr = p_FmMacParam->baseAddr;
+ /* allocate memory for the UCC GETH data structure. */
+ p_Dtsec = (t_Dtsec *) XX_Malloc(sizeof(t_Dtsec));
+ if (!p_Dtsec)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
+ return NULL;
+ }
+ /* Zero out * p_Dtsec */
+ memset(p_Dtsec, 0, sizeof(t_Dtsec));
+ InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
+
+ /* allocate memory for the dTSEC driver parameters data structure. */
+ p_DtsecDriverParam = (t_DtsecDriverParam *) XX_Malloc(sizeof(t_DtsecDriverParam));
+ if (!p_DtsecDriverParam)
+ {
+ XX_Free(p_Dtsec);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
+ return NULL;
+ }
+ /* Zero out */
+ memset(p_DtsecDriverParam, 0, sizeof(t_DtsecDriverParam));
+
+ /* Plant parameter structure pointer */
+ p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
+
+ SetDefaultParam(p_DtsecDriverParam);
+
+ for (i=0; i < sizeof(p_FmMacParam->addr); i++)
+ p_Dtsec->addr |= ((uint64_t)p_FmMacParam->addr[i] << ((5-i) * 8));
+
+ p_Dtsec->p_MemMap = (t_DtsecMemMap *)UINT_TO_PTR(baseAddr);
+ p_Dtsec->p_MiiMemMap = (t_MiiAccessMemMap *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
+ p_Dtsec->enetMode = p_FmMacParam->enetMode;
+ p_Dtsec->macId = p_FmMacParam->macId;
+ p_Dtsec->exceptions = DEFAULT_exceptions;
+ p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
+ p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
+ p_Dtsec->f_Event = p_FmMacParam->f_Event;
+ p_Dtsec->h_App = p_FmMacParam->h_App;
+
+ return p_Dtsec;
+}
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h
new file mode 100644
index 0000000..4bb7a86
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.h
@@ -0,0 +1,634 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File dtsec.h
+
+ @Description FM dTSEC ...
+*//***************************************************************************/
+#ifndef __DTSEC_H
+#define __DTSEC_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "list_ext.h"
+#include "dtsec_mii_acc.h"
+#include "fm_mac.h"
+
+
+#define PEMASK_TSRE 0x00010000
+
+#define IMASK_BREN 0x80000000
+#define IMASK_RXCEN 0x40000000
+#define IMASK_MSROEN 0x04000000
+#define IMASK_GTSCEN 0x02000000
+#define IMASK_BTEN 0x01000000
+#define IMASK_TXCEN 0x00800000
+#define IMASK_TXEEN 0x00400000
+#define IMASK_LCEN 0x00040000
+#define IMASK_CRLEN 0x00020000
+#define IMASK_XFUNEN 0x00010000
+#define IMASK_ABRTEN 0x00008000
+#define IMASK_IFERREN 0x00004000
+#define IMASK_MAGEN 0x00000800
+#define IMASK_MMRDEN 0x00000400
+#define IMASK_MMWREN 0x00000200
+#define IMASK_GRSCEN 0x00000100
+#define IMASK_TDPEEN 0x00000002
+#define IMASK_RDPEEN 0x00000001
+
+#define EVENTS_MASK ((uint32_t)(IMASK_BREN | \
+ IMASK_RXCEN | \
+ IMASK_MSROEN | \
+ IMASK_GTSCEN | \
+ IMASK_BTEN | \
+ IMASK_TXCEN | \
+ IMASK_TXEEN | \
+ IMASK_ABRTEN | \
+ IMASK_LCEN | \
+ IMASK_CRLEN | \
+ IMASK_XFUNEN | \
+ IMASK_IFERREN | \
+ IMASK_MAGEN | \
+ IMASK_MMRDEN | \
+ IMASK_MMWREN | \
+ IMASK_GRSCEN | \
+ IMASK_TDPEEN | \
+ IMASK_RDPEEN))
+
+#define GET_EXCEPTION_FLAG(bitMask, exception) switch(exception){ \
+ case e_FM_MAC_EX_1G_BAB_RX: \
+ bitMask = IMASK_BREN; break; \
+ case e_FM_MAC_EX_1G_RX_CTL: \
+ bitMask = IMASK_RXCEN; break; \
+ case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
+ bitMask = IMASK_GTSCEN ; break; \
+ case e_FM_MAC_EX_1G_BAB_TX: \
+ bitMask = IMASK_BTEN ; break; \
+ case e_FM_MAC_EX_1G_TX_CTL: \
+ bitMask = IMASK_TXCEN ; break; \
+ case e_FM_MAC_EX_1G_TX_ERR: \
+ bitMask = IMASK_TXEEN ; break; \
+ case e_FM_MAC_EX_1G_LATE_COL: \
+ bitMask = IMASK_LCEN ; break; \
+ case e_FM_MAC_EX_1G_COL_RET_LMT: \
+ bitMask = IMASK_CRLEN ; break; \
+ case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
+ bitMask = IMASK_XFUNEN ; break; \
+ case e_FM_MAC_EX_1G_MAG_PCKT: \
+ bitMask = IMASK_MAGEN ; break; \
+ case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
+ bitMask = IMASK_MMRDEN; break; \
+ case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
+ bitMask = IMASK_MMWREN ; break; \
+ case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
+ bitMask = IMASK_GRSCEN; break; \
+ case e_FM_MAC_EX_1G_TX_DATA_ERR: \
+ bitMask = IMASK_TDPEEN; break; \
+ case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
+ bitMask = IMASK_MSROEN ; break; \
+ default: bitMask = 0;break;}
+
+
+#define MAX_PACKET_ALIGNMENT 31
+#define MAX_INTER_PACKET_GAP 0x7f
+#define MAX_INTER_PALTERNATE_BEB 0x0f
+#define MAX_RETRANSMISSION 0x0f
+#define MAX_COLLISION_WINDOW 0x03ff
+
+
+/********************* From mac ext ******************************************/
+typedef uint32_t t_ErrorDisable;
+
+#define ERROR_DISABLE_TRANSMIT 0x00400000
+#define ERROR_DISABLE_LATE_COLLISION 0x00040000
+#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
+#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
+#define ERROR_DISABLE_TxABORT 0x00008000
+#define ERROR_DISABLE_INTERFACE 0x00004000
+#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
+#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
+
+/*****************************************************************************/
+#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
+
+#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
+
+#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
+
+#define DTSEC_TO_MII_OFFSET 0x1120 /* number of pattern match registers (entries) */
+
+#define DEFAULT_errorDisabled 0
+#define DEFAULT_promiscuousEnable FALSE
+#define DEFAULT_pauseExtended 0x0
+#define DEFAULT_pauseTime 0xf000
+#define DEFAULT_halfDuplex FALSE
+#define DEFAULT_halfDulexFlowControlEn FALSE
+#define DEFAULT_txTimeStampEn FALSE
+#define DEFAULT_rxTimeStampEn FALSE
+#define DEFAULT_packetAlignment 0
+#define DEFAULT_controlFrameAccept FALSE
+#define DEFAULT_groupHashExtend FALSE
+#define DEFAULT_broadcReject FALSE
+#define DEFAULT_rxShortFrame TRUE
+#define DEFAULT_exactMatch FALSE
+#define DEFAULT_debugMode FALSE
+#define DEFAULT_loopback FALSE
+#define DEFAULT_actOnRxPauseFrame TRUE
+#define DEFAULT_actOnTxPauseFrame TRUE
+
+#define DEFAULT_PreAmLength 0x7
+#define DEFAULT_PreAmRxEn FALSE
+#define DEFAULT_PreAmTxEn FALSE
+#define DEFAULT_lengthCheckEnable FALSE
+#define DEFAULT_padAndCrcEnable TRUE
+#define DEFAULT_crcEnable FALSE
+
+#define DEFAULT_nonBackToBackIpg1 0x40
+#define DEFAULT_nonBackToBackIpg2 0x60
+#define DEFAULT_minIfgEnforcement 0x50
+#define DEFAULT_backToBackIpg 0x60
+
+#define DEFAULT_altBackoffVal 0x0A
+#define DEFAULT_altBackoffEnable FALSE
+#define DEFAULT_backPressureNoBackoff FALSE
+#define DEFAULT_noBackoff FALSE
+#define DEFAULT_excessDefer TRUE
+#define DEFAULT_maxRetransmission 0x0F
+#define DEFAULT_collisionWindow 0x37
+
+#define DEFAULT_maxFrameLength 0x600
+
+#define DEFAULT_collisionWindow 0x37
+
+#define DEFAULT_fifoTxThr 0x10
+#define DEFAULT_fifoTxWatermarkH 0x7e
+#define DEFAULT_fifoRxWatermarkL 0x08
+#define DEFAULT_tbiPhyAddr 5
+
+#define DEFAULT_exceptions ((uint32_t)(IMASK_BREN | \
+ IMASK_RXCEN | \
+ IMASK_BTEN | \
+ IMASK_TXCEN | \
+ IMASK_TXEEN | \
+ IMASK_ABRTEN | \
+ IMASK_LCEN | \
+ IMASK_CRLEN | \
+ IMASK_XFUNEN | \
+ IMASK_IFERREN | \
+ IMASK_MAGEN | \
+ IMASK_TDPEEN | \
+ IMASK_RDPEEN))
+
+
+#define MAX_PHYS 32 /* maximum number of phys */
+
+#define DTSEC_ID1_ID 0xffff0000
+#define DTSEC_ID1_REV_MJ 0x0000FF00
+#define DTSEC_ID1_REV_MN 0x000000ff
+
+#define ID2_INT_REDUCED_OFF 0x00010000
+#define ID2_INT_NORMAL_OFF 0x00020000
+
+#define ECNTRL_CLRCNT 0x00004000
+#define ECNTRL_AUTOZ 0x00002000
+#define ECNTRL_STEN 0x00001000
+#define ECNTRL_CFG_RO 0x80000000
+#define ECNTRL_GMIIM 0x00000040
+#define ECNTRL_TBIM 0x00000020
+#define ECNTRL_SGMIIM 0x00000002
+#define ECNTRL_RPM 0x00000010
+#define ECNTRL_R100M 0x00000008
+#define ECNTRL_RMM 0x00000004
+#define ECNTRL_QSGMIIM 0x00000001
+
+#define TCTRL_THDF 0x00000800
+#define TCTRL_TTSE 0x00000040
+#define TCTRL_GTS 0x00000020
+#define TCTRL_TFC_PAUSE 0x00000010
+
+/* PTV offsets */
+#define PTV_PTE_OFST 16
+
+#define RCTRL_CFA 0x00008000
+#define RCTRL_GHTX 0x00000400
+#define RCTRL_RTSE 0x00000040
+#define RCTRL_GRS 0x00000020
+#define RCTRL_BC_REJ 0x00000010
+#define RCTRL_MPROM 0x00000008
+#define RCTRL_RSF 0x00000004
+#define RCTRL_EMEN 0x00000002
+#define RCTRL_UPROM 0x00000001
+#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
+
+#define TMR_CTL_ESFDP 0x00000800
+#define TMR_CTL_ESFDE 0x00000400
+
+#define TSEC_ID1_DEBUG 0x00e00c00
+#define DEBUG_ENABLE 0x80000000
+#define DPERROR_Tx_ERROR_ON_SEC 0x00400000
+#define DPERROR_Tx_ERROR_ON_WRITE 0x10000000
+#define DPERROR_Rx_ERROR_ON_SEC 0x00000040
+#define DPERROR_Rx_ERROR_ON_WRITE 0x00001000
+#define DPERROR_STT 0x80000000
+#define DPERROR_STR 0x00008000
+
+#define MACCFG1_SOFT_RESET 0x80000000
+#define MACCFG1_LOOPBACK 0x00000100
+#define MACCFG1_RX_FLOW 0x00000020
+#define MACCFG1_TX_FLOW 0x00000010
+#define MACCFG1_TX_EN 0x00000001
+#define MACCFG1_RX_EN 0x00000004
+#define MACCFG1_RESET_RxMC 0x00080000
+#define MACCFG1_RESET_TxMC 0x00040000
+#define MACCFG1_RESET_RxFUN 0x00020000
+#define MACCFG1_RESET_TxFUN 0x00010000
+
+#define MACCFG2_NIBBLE_MODE 0x00000100
+#define MACCFG2_BYTE_MODE 0x00000200
+#define MACCFG2_PRE_AM_Rx_EN 0x00000080
+#define MACCFG2_PRE_AM_Tx_EN 0x00000040
+#define MACCFG2_LENGTH_CHECK 0x00000010
+#define MACCFG2_MAGIC_PACKET_EN 0x00000008
+#define MACCFG2_PAD_CRC_EN 0x00000004
+#define MACCFG2_CRC_EN 0x00000002
+#define MACCFG2_FULL_DUPLEX 0x00000001
+
+#define PREAMBLE_LENGTH_SHIFT 12
+
+#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
+#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
+#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
+
+#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
+#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
+#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
+#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
+
+#define HAFDUP_ALT_BEB 0x00080000
+#define HAFDUP_BP_NO_BACKOFF 0x00040000
+#define HAFDUP_NO_BACKOFF 0x00020000
+#define HAFDUP_EXCESS_DEFER 0x00010000
+#define HAFDUP_COLLISION_WINDOW 0x000003ff
+
+#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
+#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
+#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
+
+#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
+
+#define DEBUG_GET_FIFO_READ_INDEX 0x007f0000
+#define DEBUG_GET_FIFO_WRITE_INDEX 0x0000007f
+/* Pause Time Value Register */
+#define PTV_PTE_SHIFT 16
+
+#define MASK22BIT 0x003FFFFF
+#define MASK16BIT 0x0000FFFF
+#define MASK12BIT 0x00000FFF
+#define MASK8BIT 0x000000FF
+
+#define VAL32BIT 0x100000000LL
+#define VAL22BIT 0x00400000
+#define VAL16BIT 0x00010000
+#define VAL12BIT 0x00001000
+
+/* PHY Control Register */
+#define PHY_CR_LOOPBACK 0x4000
+#define PHY_CR_SPEED0 0x2000
+#define PHY_CR_ANE 0x1000
+#define PHY_CR_FULLDUPLEX 0x0100
+#define PHY_CR_SPEED1 0x0040
+
+#define PHY_TBICON_SRESET 0x8000
+#define PHY_TBICON_SPEED2 0x0020
+
+/* CAR1/2 bits */
+#define CAR1_TR64 0x80000000
+#define CAR1_TR127 0x40000000
+#define CAR1_TR255 0x20000000
+#define CAR1_TR511 0x10000000
+#define CAR1_TRK1 0x08000000
+#define CAR1_TRMAX 0x04000000
+#define CAR1_TRMGV 0x02000000
+
+#define CAR1_RBYT 0x00010000
+#define CAR1_RPKT 0x00008000
+#define CAR1_RMCA 0x00002000
+#define CAR1_RBCA 0x00001000
+#define CAR1_RXPF 0x00000400
+#define CAR1_RALN 0x00000100
+#define CAR1_RFLR 0x00000080
+#define CAR1_RCDE 0x00000040
+#define CAR1_RCSE 0x00000020
+#define CAR1_RUND 0x00000010
+#define CAR1_ROVR 0x00000008
+#define CAR1_RFRG 0x00000004
+#define CAR1_RJBR 0x00000002
+#define CAR1_RDRP 0x00000001
+
+#define CAR2_TFCS 0x00040000
+#define CAR2_TBYT 0x00002000
+#define CAR2_TPKT 0x00001000
+#define CAR2_TMCA 0x00000800
+#define CAR2_TBCA 0x00000400
+#define CAR2_TXPF 0x00000200
+#define CAR2_TDRP 0x00000001
+
+#define CAM1_ERRORS_ONLY (CAR1_RXPF | \
+ CAR1_RALN | \
+ CAR1_RFLR | \
+ CAR1_RCDE | \
+ CAR1_RCSE | \
+ CAR1_RUND | \
+ CAR1_ROVR | \
+ CAR1_RFRG | \
+ CAR1_RJBR | \
+ CAR1_RDRP)
+
+#define CAM2_ERRORS_ONLY (CAR2_TFCS | CAR2_TXPF | CAR2_TDRP)
+
+typedef struct t_InternalStatistics
+{
+ uint64_t tr64;
+ uint64_t tr127;
+ uint64_t tr255;
+ uint64_t tr511;
+ uint64_t tr1k;
+ uint64_t trmax;
+ uint64_t trmgv;
+ uint64_t rfrg;
+ uint64_t rjbr;
+ uint64_t rdrp;
+ uint64_t raln;
+ uint64_t rund;
+ uint64_t rovr;
+ uint64_t rxpf;
+ uint64_t txpf;
+ uint64_t rbyt;
+ uint64_t rpkt;
+ uint64_t rmca;
+ uint64_t rbca;
+ uint64_t rflr;
+ uint64_t rcde;
+ uint64_t rcse;
+ uint64_t tbyt;
+ uint64_t tpkt;
+ uint64_t tmca;
+ uint64_t tbca;
+ uint64_t tdrp;
+ uint64_t tfcs;
+} t_InternalStatistics;
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct
+{
+ uint32_t exact_match1; /* octets 1-4 */
+ uint32_t exact_match2; /* octets 5-6 */
+} _PackedType macRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t tsec_id1; /* 0x000 ETSEC_ID register */
+ volatile uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
+ volatile uint32_t ievent; /* 0x008 Interrupt event register */
+ volatile uint32_t imask; /* 0x00C Interrupt mask register */
+ volatile uint32_t edis; /* 0x010 Error disabled register */
+ volatile uint32_t ecntrl; /* 0x014 E control register */
+ volatile uint32_t ptv; /* 0x018 Pause time value register */
+ volatile uint32_t tbipa; /* 0x01C TBI PHY address register */
+ volatile uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
+ volatile uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
+ volatile uint32_t tmr_pemask; /* 0x028 Timer event mask register */
+ volatile uint32_t DTSEC_RESERVED2; /* 0x02C */
+ volatile uint32_t iobistctl; /* 0x030 IO BIST Control register */
+ volatile uint32_t DTSEC_RESERVED3[3]; /* 0x034 */
+
+ volatile uint32_t tctrl; /* 0x040 Transmit control register */
+ volatile uint32_t DTSEC_RESERVED4[3]; /* 0x044-0x04C */
+ volatile uint32_t rctrl; /* 0x050 Receive control register */
+ volatile uint32_t DTSEC_RESERVED5[11]; /* 0x054- 0x07C */
+
+ volatile uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address registers 0-7 */
+ volatile uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
+ volatile uint32_t ETSEC_RESERVED6[16]; /* 0x0C0-0x0FC */
+
+ volatile uint32_t maccfg1; /* 0x100 MAC configuration #1 */
+ volatile uint32_t maccfg2; /* 0x104 MAC configuration #2 */
+ volatile uint32_t ipgifg; /* 0x108 IPG/IFG */
+ volatile uint32_t hafdup; /* 0x10C Half-duplex */
+ volatile uint32_t maxfrm; /* 0x110 Maximum frame */
+ volatile uint32_t DTSEC_RESERVED7[3]; /* 0x114-0x11C register */
+ t_MiiAccessMemMap miiMemMap;
+ volatile uint32_t ifctrl; /* 0x138 MII Mgmt:interface control */
+ volatile uint32_t ifstat; /* 0x13C Interface status */
+ volatile uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
+ volatile uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
+ volatile macRegs macaddr[DTSEC_NUM_OF_PADDRS]; /* 0x148-0x1BC mac exact match addresses 1-15, parts 1-2 */
+ volatile uint32_t DTSEC_RESERVED8[16]; /* 0x1C0-0x1FC register */
+
+ /* RMON MIB REGISTERS */
+ /* TRANSMIT and RECEIVE COUNTERS */
+
+ volatile uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
+ volatile uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame counter */
+ volatile uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame counter */
+ volatile uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame counter */
+ volatile uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame counter */
+ volatile uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame counter */
+ volatile uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good VLAN frame count */
+
+ /* RECEIVE COUNTERS */
+ volatile uint32_t rbyt; /* 0x21C receive byte counter */
+ volatile uint32_t rpkt; /* 0x220 receive packet counter */
+ volatile uint32_t rfcs; /* 0x224 receive FCS error counter */
+ volatile uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
+ volatile uint32_t rbca; /* 0x22C receive broadcast packet counter */
+ volatile uint32_t rxcf; /* 0x230 receive control frame packet counter */
+ volatile uint32_t rxpf; /* 0x234 receive PAUSE frame packet counter */
+ volatile uint32_t rxuo; /* 0x238 receive unknown OP code counter */
+ volatile uint32_t raln; /* 0x23C receive alignment error counter */
+ volatile uint32_t rflr; /* 0x240 receive frame length error counter */
+ volatile uint32_t rcde; /* 0x244 receive code error counter */
+ volatile uint32_t rcse; /* 0x248 receive carrier sense error counter */
+ volatile uint32_t rund; /* 0x24C receive undersize packet counter */
+ volatile uint32_t rovr; /* 0x250 receive oversize packet counter */
+ volatile uint32_t rfrg; /* 0x254 receive fragments counter */
+ volatile uint32_t rjbr; /* 0x258 receive jabber counter */
+ volatile uint32_t rdrp; /* 0x25C receive drop */
+
+ /* TRANSMIT COUNTERS */
+ volatile uint32_t tbyt; /* 0x260 transmit byte counter */
+ volatile uint32_t tpkt; /* 0x264 transmit packet counter */
+ volatile uint32_t tmca; /* 0x268 transmit multicast packet counter */
+ volatile uint32_t tbca; /* 0x26C transmit broadcast packet counter */
+ volatile uint32_t txpf; /* 0x270 transmit PAUSE control frame counter */
+ volatile uint32_t tdfr; /* 0x274 transmit deferral packet counter */
+ volatile uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
+ volatile uint32_t tscl; /* 0x27C transmit single collision packet counter */
+ volatile uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
+ volatile uint32_t tlcl; /* 0x284 transmit late collision packet counter */
+ volatile uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
+ volatile uint32_t tncl; /* 0x28C transmit total collision counter */
+ volatile uint32_t DTSEC_RESERVED9; /* 0x290 */
+ volatile uint32_t tdrp; /* 0x294 transmit drop frame counter */
+ volatile uint32_t tjbr; /* 0x298 transmit jabber frame counter */
+ volatile uint32_t tfcs; /* 0x29C transmit FCS error counter */
+ volatile uint32_t txcf; /* 0x2A0 transmit control frame counter */
+ volatile uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
+ volatile uint32_t tund; /* 0x2A8 transmit undersize frame counter */
+ volatile uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
+
+ /* GENERAL REGISTERS */
+ volatile uint32_t car1; /* 0x2B0 carry register one register* */
+ volatile uint32_t car2; /* 0x2B4 carry register two register* */
+ volatile uint32_t cam1; /* 0x2B8 carry register one mask register */
+ volatile uint32_t cam2; /* 0x2BC carry register two mask register */
+ volatile uint32_t DTSEC_RESERVED10[16]; /* 0x2C0-0x2FC */
+
+ /* Debug and Factory Test Registers */
+ volatile uint32_t debug; /* 0x300 DEBUG - Debug Register */
+ volatile uint32_t dperror; /* 0x304 DPERROR - Parity Error Register */
+ volatile uint32_t hwassert; /* 0x308 HWASSERT */
+ volatile uint32_t RESERVED11; /* 0x30C Reserved */
+ volatile uint32_t rx_fifo_ptr; /* 0x310 RXFIFOPTR - Rx FIFO R/W Pointer Register */
+ volatile uint32_t rx_fifo_dath; /* 0x314 RXFIFODATH - Rx FIFO Data Register */
+ volatile uint32_t rx_fifo_datl; /* 0x318 RXFIFODATL - Rx FIFO Data Register */
+ volatile uint32_t rx_fifo_stat; /* 0x31C RXFIFOSTAT - Rx FIFO Status Register */
+ volatile uint32_t tx_fifo_ptr; /* 0x320 TXFIFOPTR - Tx FIFO R/W Pointer Register */
+ volatile uint32_t tx_fifo_dath; /* 0x324 TXFIFODATH - Rx FIFO Data Register */
+ volatile uint32_t tx_fifo_datl; /* 0x328 TXFIFODATL - Rx FIFO Data Register */
+ volatile uint32_t tx_fifo_stat; /* 0x32C TXFIFOSTAT - Tx FIFO Status Register */
+ volatile uint32_t pkt_rcv_cnt; /* 0x330 PKTRCVCNT - Number of packets accepted and written to Rx FIFO */
+ volatile uint32_t RESERVED12[3]; /* 0x334-0x33C Reserved */
+ volatile uint32_t tx_threshold; /* 0x340 Transmit threshold; Number of entries (4 bytes units) before starting to transmit to the MAC */
+ volatile uint32_t tx_watermark_high;/* 0x344 Transmit watermark high; Number of entries (4 byte units) before de-asserting Ready to packet Interface */
+ volatile uint32_t rx_watermark_low; /* 0x348 Receive watermark low; Number of entries (4 byte units) before unloading to packet Interface */
+} _PackedType t_DtsecMemMap;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+typedef struct {
+ uint32_t errorDisabled;
+ bool halfDuplex;
+ uint16_t pauseTime;
+ uint16_t pauseExtended;
+ uint8_t tbiPhyAddr; /**< TBI Physical address (1-31) [DEFAULT_tbiPhyAddr] */
+
+ bool autoZeroCounters;
+ bool promiscuousEnable;
+
+ bool halfDulexFlowControlEn;
+ bool txTimeStampEn;
+ bool rxTimeStampEn;
+
+ uint8_t packetAlignmentPadding;
+ bool controlFrameAccept;
+ bool groupHashExtend;
+ bool broadcReject;
+ bool rxShortFrame;
+ bool exactMatch;
+
+ bool debugMode;
+
+ bool loopback;
+ bool actOnRxPauseFrame;
+ bool actOnTxPauseFrame;
+
+ uint8_t nonBackToBackIpg1;
+ uint8_t nonBackToBackIpg2;
+ uint8_t minIfgEnforcement;
+ uint8_t backToBackIpg;
+
+ uint8_t preambleLength;
+ bool preambleRxEn;
+ bool preambleTxEn;
+ bool lengthCheckEnable;
+ bool magicPacketEnable;
+ bool padAndCrcEnable;
+ bool crcEnable;
+
+ bool alternateBackoffEnable;
+ uint8_t alternateBackoffVal;
+ bool backPressureNoBackoff;
+ bool noBackoff;
+ bool excessDefer;
+ uint8_t maxRetransmission;
+ uint16_t collisionWindow;
+
+ uint16_t maxFrameLength;
+
+ uint8_t fifoTxThr;
+ uint8_t fifoTxWatermarkH;
+ uint8_t fifoRxWatermarkL;
+} t_DtsecDriverParam;
+
+typedef struct {
+ t_FmMacControllerDriver fmMacControllerDriver;
+ t_Handle h_App; /**< Handle to the upper layer application */
+ t_DtsecMemMap *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
+ t_MiiAccessMemMap *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
+ uint64_t addr; /**< MAC address of device; */
+ e_EnetMode enetMode; /**< Ethernet physical interface */
+ t_FmMacExceptionCallback *f_Exception;
+ int mdioIrq;
+ t_FmMacExceptionCallback *f_Event;
+ bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
+ uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
+ uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
+ bool debugMode;
+ bool halfDuplex;
+ t_InternalStatistics internalStatistics;
+ t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
+ t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
+ uint8_t macId;
+ uint32_t exceptions;
+ bool ptpTsuEnabled;
+ bool enTsuErrExeption;
+ e_FmMacStatisticsLevel statisticsLevel;
+
+ t_DtsecDriverParam *p_DtsecDriverParam;
+} t_Dtsec;
+
+
+t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
+t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
+
+
+#endif /* __DTSEC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c
new file mode 100644
index 0000000..be85fa2
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c
@@ -0,0 +1,120 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File dtsec_mii_acc.c
+
+ @Description FM dtsec MII register access MAC ...
+*//***************************************************************************/
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "fm_mac.h"
+#include "dtsec.h"
+
+
+/*****************************************************************************/
+t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
+ uint8_t phyAddr,
+ uint8_t reg,
+ uint16_t data)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_MiiAccessMemMap *p_MiiAccess;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
+
+ p_MiiAccess = p_Dtsec->p_MiiMemMap;
+
+ /* Stop the MII management read cycle */
+ WRITE_UINT32(p_MiiAccess->miimcom, 0);
+ /* Dummy read to make sure MIIMCOM is written */
+ tmpReg = GET_UINT32(p_MiiAccess->miimcom);
+
+ /* Setting up MII Management Address Register */
+ tmpReg = (uint32_t)((phyAddr << MIIMADD_PHY_ADDR_SHIFT) | reg);
+ WRITE_UINT32(p_MiiAccess->miimadd, tmpReg);
+
+ /* Setting up MII Management Control Register with data */
+ WRITE_UINT32(p_MiiAccess->miimcon, (uint32_t)data);
+ /* Dummy read to make sure MIIMCON is written */
+ tmpReg = GET_UINT32(p_MiiAccess->miimcon);
+
+ /* Wait till MII management write is complete */
+ while ((GET_UINT32(p_MiiAccess->miimind)) & MIIMIND_BUSY) ;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
+ uint8_t phyAddr,
+ uint8_t reg,
+ uint16_t *p_Data)
+{
+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
+ t_MiiAccessMemMap *p_MiiAccess;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
+
+ p_MiiAccess = p_Dtsec->p_MiiMemMap;
+
+ /* Setting up the MII Management Address Register */
+ tmpReg = (uint32_t)((phyAddr << MIIMADD_PHY_ADDR_SHIFT) | reg);
+ WRITE_UINT32(p_MiiAccess->miimadd, tmpReg);
+
+ /* Perform an MII management read cycle */
+ WRITE_UINT32(p_MiiAccess->miimcom, MIIMCOM_READ_CYCLE);
+ /* Dummy read to make sure MIIMCOM is written */
+ tmpReg = GET_UINT32(p_MiiAccess->miimcom);
+
+ /* Wait till MII management read is complete */
+ while ((GET_UINT32(p_MiiAccess->miimind)) & MIIMIND_BUSY) ;
+
+ /* Read MII management status */
+ *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->miimstat);
+
+ WRITE_UINT32(p_MiiAccess->miimcom, 0);
+ /* Dummy read to make sure MIIMCOM is written */
+ tmpReg = GET_UINT32(p_MiiAccess->miimcom);
+
+ if (*p_Data == 0xffff)
+ RETURN_ERROR(MINOR, E_NO_DEVICE,
+ ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
+ phyAddr, reg));
+
+ return E_OK;
+}
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h
new file mode 100644
index 0000000..7c529c2
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.h
@@ -0,0 +1,78 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DTSEC_MII_ACC_H
+#define __DTSEC_MII_ACC_H
+
+#include "std_ext.h"
+
+
+/* MII Management Configuration Register */
+#define MIIMCFG_RESET_MGMT 0x80000000
+#define MIIMCFG_MGMT_CLOCK_SELECT 0x00000007
+
+/* MII Management Command Register */
+#define MIIMCOM_READ_CYCLE 0x00000001
+#define MIIMCOM_SCAN_CYCLE 0x00000002
+
+/* MII Management Address Register */
+#define MIIMADD_PHY_ADDR_SHIFT 8
+
+/* MII Management Indicator Register */
+#define MIIMIND_BUSY 0x00000001
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/*----------------------------------------------------*/
+/* MII Configuration Control Memory Map Registers */
+/*----------------------------------------------------*/
+typedef _Packed struct t_MiiAccessMemMap
+{
+ volatile uint32_t miimcfg; /* MII Mgmt:configuration */
+ volatile uint32_t miimcom; /* MII Mgmt:command */
+ volatile uint32_t miimadd; /* MII Mgmt:address */
+ volatile uint32_t miimcon; /* MII Mgmt:control 3 */
+ volatile uint32_t miimstat; /* MII Mgmt:status */
+ volatile uint32_t miimind; /* MII Mgmt:indicators */
+} _PackedType t_MiiAccessMemMap ;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+#endif /* __DTSEC_MII_ACC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c
new file mode 100644
index 0000000..4eb3954
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.c
@@ -0,0 +1,560 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_mac.c
+
+ @Description FM MAC ...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "error_ext.h"
+#include "fm_ext.h"
+
+#include "fm_common.h"
+#include "fm_mac.h"
+
+
+/* ........................................................................... */
+
+t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
+
+ if(ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
+ p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
+ else
+ p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
+
+ if (!p_FmMacControllerDriver)
+ return NULL;
+
+ p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
+ p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
+ p_FmMacControllerDriver->macId = p_FmMacParam->macId;
+ p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
+
+ return (t_Handle)p_FmMacControllerDriver;
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_Init (t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->resetOnInit &&
+ (FmResetMac(p_FmMacControllerDriver->h_Fm,
+ ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ? e_FM_MAC_10G : e_FM_MAC_1G),
+ p_FmMacControllerDriver->macId) != E_OK))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
+
+ if ((p_FmMacControllerDriver->clkFreq = FmGetClockFreq(p_FmMacControllerDriver->h_Fm)) == 0)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
+
+ if (p_FmMacControllerDriver->f_FM_MAC_Init)
+ return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_Free (t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_Free)
+ return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ p_FmMacControllerDriver->resetOnInit = enable;
+
+ return E_OK;
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+/* ........................................................................... */
+
+t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
+ return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+
+/*****************************************************************************/
+/* Run Time Control */
+/*****************************************************************************/
+
+/* ........................................................................... */
+
+t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_Enable)
+ return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_Disable)
+ return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
+ return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
+ return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_SetTxAutoPauseFrames (t_Handle h_FmMac, uint16_t pauseTime)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
+ return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac, pauseTime);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
+ return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
+ return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_SetException)
+ return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
+ return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics)
+ return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
+ return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
+ return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
+ return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
+ return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
+ return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
+ return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_GetId)
+ return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
+ return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
+ return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
+ return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
+ return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
+
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+
+/* ........................................................................... */
+
+uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
+ return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
+
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+ return 0;
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/*****************************************************************************/
+t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
+{
+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
+
+ if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
+ return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h
new file mode 100644
index 0000000..9a64f14
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/fm_mac.h
@@ -0,0 +1,197 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_mac.h
+
+ @Description FM MAC ...
+*//***************************************************************************/
+#ifndef __FM_MAC_H
+#define __FM_MAC_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "list_ext.h"
+#include "fm_mac_ext.h"
+
+
+#define __ERR_MODULE__ MODULE_FM_MAC
+
+
+#define DEFAULT_resetOnInit FALSE
+
+
+typedef struct {
+ uint64_t addr; /* Ethernet Address */
+ t_List node;
+} t_EthHashEntry;
+#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
+
+typedef struct {
+ uint16_t size;
+ t_List *p_Lsts;
+} t_EthHash;
+
+typedef struct {
+ t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
+ t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
+
+ t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
+ t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
+ t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
+ t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
+ t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
+ t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
+ t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
+ t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+ t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+ t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
+
+ t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
+ t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
+ t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
+ t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
+ t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
+
+ t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac, uint16_t pauseTime);
+ t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
+
+ t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
+ t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
+
+ t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+ t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+ t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+ t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+ t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+
+ t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
+ t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
+
+ t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
+
+ t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
+
+ uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
+
+ t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
+ t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+ t_Handle h_Fm;
+ e_EnetMode enetMode;
+ uint8_t macId;
+ bool resetOnInit;
+ uint16_t clkFreq;
+} t_FmMacControllerDriver;
+
+
+t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
+t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
+uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
+
+
+/* ........................................................................... */
+
+static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
+{
+ t_EthHashEntry *p_HashEntry = NULL;
+ if (!LIST_IsEmpty(p_AddrLst))
+ {
+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
+ LIST_DelAndInit(&p_HashEntry->node);
+ }
+ return p_HashEntry;
+}
+
+/* ........................................................................... */
+
+static __inline__ void FreeHashTable(t_EthHash *p_Hash)
+{
+ t_EthHashEntry *p_HashEntry;
+ int i = 0;
+
+ if (!p_Hash || !p_Hash->p_Lsts)
+ return;
+
+ for(i=0; i<p_Hash->size; i++)
+ {
+ p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
+ while (p_HashEntry)
+ {
+ XX_Free(p_HashEntry);
+ p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
+ }
+ }
+
+ XX_Free(p_Hash->p_Lsts);
+ XX_Free(p_Hash);
+}
+
+/* ........................................................................... */
+
+static __inline__ t_EthHash * AllocHashTable(uint16_t size)
+{
+ uint32_t i;
+ t_EthHash *p_Hash;
+
+ /* Allocate address hash table */
+ p_Hash = (t_EthHash *)XX_Malloc(size*sizeof(t_EthHash *));
+ if (!p_Hash)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
+ return NULL;
+ }
+ p_Hash->size = size;
+
+ p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
+ if (!p_Hash->p_Lsts)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
+ XX_Free(p_Hash);
+ return NULL;
+ }
+
+ for(i=0 ; i<p_Hash->size; i++)
+ INIT_LIST(&p_Hash->p_Lsts[i]);
+
+ return p_Hash;
+}
+
+
+#endif /* __FM_MAC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c
new file mode 100644
index 0000000..cbe3535
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c
@@ -0,0 +1,1268 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File tgec.c
+
+ @Description FM 10G MAC ...
+*//***************************************************************************/
+
+#include "std_ext.h"
+#include "string_ext.h"
+#include "error_ext.h"
+#include "xx_ext.h"
+#include "endian_ext.h"
+#include "crc_mac_addr_ext.h"
+#include "debug_ext.h"
+
+#include "fm_common.h"
+#include "tgec.h"
+
+
+/*****************************************************************************/
+/* Internal routines */
+/*****************************************************************************/
+
+static t_Error CheckInitParameters(t_Tgec *p_Tgec)
+{
+ if(ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
+#if (FM_MAX_NUM_OF_10G_MACS > 0)
+ if(p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
+#endif
+ if(p_Tgec->addr == 0)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
+ if(!p_Tgec->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
+ if(!p_Tgec->f_Event)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static void SetDefaultParam(t_TgecDriverParam *p_TgecDriverParam)
+{
+ p_TgecDriverParam->wanModeEnable = DEFAULT_wanModeEnable;
+ p_TgecDriverParam->promiscuousModeEnable = DEFAULT_promiscuousModeEnable;
+ p_TgecDriverParam->pauseForwardEnable = DEFAULT_pauseForwardEnable;
+ p_TgecDriverParam->pauseIgnore = DEFAULT_pauseIgnore;
+ p_TgecDriverParam->txAddrInsEnable = DEFAULT_txAddrInsEnable;
+
+ p_TgecDriverParam->loopbackEnable = DEFAULT_loopbackEnable;
+ p_TgecDriverParam->cmdFrameEnable = DEFAULT_cmdFrameEnable;
+ p_TgecDriverParam->rxErrorDiscard = DEFAULT_rxErrorDiscard;
+ p_TgecDriverParam->phyTxenaOn = DEFAULT_phyTxenaOn;
+ p_TgecDriverParam->sendIdleEnable = DEFAULT_sendIdleEnable;
+ p_TgecDriverParam->noLengthCheckEnable = DEFAULT_noLengthCheckEnable;
+ p_TgecDriverParam->lgthCheckNostdr = DEFAULT_lgthCheckNostdr;
+ p_TgecDriverParam->timeStampEnable = DEFAULT_timeStampEnable;
+ p_TgecDriverParam->rxSfdAny = DEFAULT_rxSfdAny;
+ p_TgecDriverParam->rxPblFwd = DEFAULT_rxPblFwd;
+ p_TgecDriverParam->txPblFwd = DEFAULT_txPblFwd;
+
+ p_TgecDriverParam->txIpgLength = DEFAULT_txIpgLength;
+ p_TgecDriverParam->maxFrameLength = DEFAULT_maxFrameLength;
+
+ p_TgecDriverParam->debugMode = DEFAULT_debugMode;
+
+ p_TgecDriverParam->pauseTime = DEFAULT_pauseTime;
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+ p_TgecDriverParam->skipFman11Workaround = DEFAULT_skipFman11Workaround;
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+}
+
+/* ........................................................................... */
+
+static void TgecErrException(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ uint32_t event;
+ t_TgecMemMap *p_TgecMemMap = p_Tgec->p_MemMap;
+
+ event = GET_UINT32(p_TgecMemMap->ievent);
+ /* do not handle MDIO events */
+ event &= ~(IMASK_MDIO_SCAN_EVENTMDIO | IMASK_MDIO_CMD_CMPL);
+
+ event &= GET_UINT32(p_TgecMemMap->imask);
+
+ WRITE_UINT32(p_TgecMemMap->ievent, event);
+
+ if (event & IMASK_REM_FAULT)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
+ if (event & IMASK_LOC_FAULT)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
+ if (event & IMASK_1TX_ECC_ER)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
+ if (event & IMASK_TX_FIFO_UNFL)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
+ if (event & IMASK_TX_FIFO_OVFL)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
+ if (event & IMASK_TX_ER)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
+ if (event & IMASK_RX_FIFO_OVFL)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
+ if (event & IMASK_RX_ECC_ER)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
+ if (event & IMASK_RX_JAB_FRM)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
+ if (event & IMASK_RX_OVRSZ_FRM)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
+ if (event & IMASK_RX_RUNT_FRM)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
+ if (event & IMASK_RX_FRAG_FRM)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
+ if (event & IMASK_RX_LEN_ER)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
+ if (event & IMASK_RX_CRC_ER)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
+ if (event & IMASK_RX_ALIGN_ER)
+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
+}
+
+static void TgecException(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ uint32_t event;
+ t_TgecMemMap *p_TgecMemMap = p_Tgec->p_MemMap;
+
+ event = GET_UINT32(p_TgecMemMap->ievent);
+ /* handle only MDIO events */
+ event &= (IMASK_MDIO_SCAN_EVENTMDIO | IMASK_MDIO_CMD_CMPL);
+ event &= GET_UINT32(p_TgecMemMap->imask);
+
+ WRITE_UINT32(p_TgecMemMap->ievent, event);
+
+ if(event & IMASK_MDIO_SCAN_EVENTMDIO)
+ p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
+ if(event & IMASK_MDIO_CMD_CMPL)
+ p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
+}
+
+static void FreeInitResources(t_Tgec *p_Tgec)
+{
+ if ((p_Tgec->mdioIrq != 0) && (p_Tgec->mdioIrq != NO_IRQ))
+ {
+ XX_DisableIntr(p_Tgec->mdioIrq);
+ XX_FreeIntr(p_Tgec->mdioIrq);
+ }
+ else if (p_Tgec->mdioIrq == 0)
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, (NO_MSG));
+ FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
+
+ /* release the driver's group hash table */
+ FreeHashTable(p_Tgec->p_MulticastAddrHash);
+ p_Tgec->p_MulticastAddrHash = NULL;
+
+ /* release the driver's individual hash table */
+ FreeHashTable(p_Tgec->p_UnicastAddrHash);
+ p_Tgec->p_UnicastAddrHash = NULL;
+}
+
+/* .............................................................................. */
+
+static void HardwareClearAddrInPaddr(t_Tgec *p_Tgec, uint8_t paddrNum)
+{
+ if (paddrNum != 0)
+ return; /* At this time MAC has only one address */
+
+ WRITE_UINT32(p_Tgec->p_MemMap->mac_addr_2, 0x0);
+ WRITE_UINT32(p_Tgec->p_MemMap->mac_addr_3, 0x0);
+}
+
+/* ........................................................................... */
+
+static void HardwareAddAddrInPaddr(t_Tgec *p_Tgec, uint64_t *p_Addr, uint8_t paddrNum)
+{
+ uint32_t tmpReg32 = 0;
+ uint64_t addr = *p_Addr;
+ t_TgecMemMap *p_TgecMemMap = p_Tgec->p_MemMap;
+
+ if (paddrNum != 0)
+ return; /* At this time MAC has only one address */
+
+ tmpReg32 = (uint32_t)(addr>>16);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_TgecMemMap->mac_addr_2, tmpReg32);
+
+ tmpReg32 = (uint32_t)(addr);
+ SwapUint32P(&tmpReg32);
+ tmpReg32 >>= 16;
+ WRITE_UINT32(p_TgecMemMap->mac_addr_3, tmpReg32);
+}
+
+/*****************************************************************************/
+/* 10G MAC API routines */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_MemMap ;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
+
+ p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap);
+
+ tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
+
+ switch (mode)
+ {
+ case e_COMM_MODE_NONE:
+ tmpReg32 &= ~(CMD_CFG_TX_EN | CMD_CFG_RX_EN);
+ break;
+ case e_COMM_MODE_RX :
+ tmpReg32 |= CMD_CFG_RX_EN ;
+ break;
+ case e_COMM_MODE_TX :
+ tmpReg32 |= CMD_CFG_TX_EN ;
+ break;
+ case e_COMM_MODE_RX_AND_TX:
+ tmpReg32 |= (CMD_CFG_TX_EN | CMD_CFG_RX_EN);
+ break;
+ }
+
+ WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_MemMap ;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
+
+ p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap);
+
+ tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
+ switch (mode)
+ {
+ case e_COMM_MODE_RX:
+ tmpReg32 &= ~CMD_CFG_RX_EN;
+ break;
+ case e_COMM_MODE_TX:
+ tmpReg32 &= ~CMD_CFG_TX_EN;
+ break;
+ case e_COMM_MODE_RX_AND_TX:
+ tmpReg32 &= ~(CMD_CFG_TX_EN | CMD_CFG_RX_EN);
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+
+ tmpReg32 = GET_UINT32(p_TgecMemMap->cmd_conf_ctrl);
+
+ if (newVal)
+ tmpReg32 |= CMD_CFG_PROMIS_EN;
+ else
+ tmpReg32 &= ~CMD_CFG_PROMIS_EN;
+
+ WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, tmpReg32);
+
+ return E_OK;
+}
+
+
+/*****************************************************************************/
+/* Tgec Configs modification functions */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+
+#ifdef FM_NO_TGEC_LOOPBACK
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("no loopback in this chip rev!"));
+ }
+#endif /* FM_NO_TGEC_LOOPBACK */
+
+ p_Tgec->p_TgecDriverParam->loopbackEnable = newVal;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+
+ p_Tgec->p_TgecDriverParam->wanModeEnable = newVal;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+
+ p_Tgec->p_TgecDriverParam->maxFrameLength = newVal;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
+{
+#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
+UNUSED(h_Tgec);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
+
+#else
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ UNUSED(newVal);
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+
+ p_Tgec->p_TgecDriverParam->noLengthCheckEnable = !newVal;
+
+ return E_OK;
+#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
+}
+
+/* .............................................................................. */
+
+static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ uint32_t bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+#ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
+ if((revInfo.majorRev <=2) &&
+ enable &&
+ ((exception == e_FM_MAC_EX_10G_LOC_FAULT) || (exception == e_FM_MAC_EX_10G_REM_FAULT)))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_MAC_EX_10G_LOC_FAULT and e_FM_MAC_EX_10G_REM_FAULT !"));
+ }
+#endif /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */
+
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Tgec->exceptions |= bitMask;
+ else
+ p_Tgec->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+/* .............................................................................. */
+
+static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+
+ p_Tgec->p_TgecDriverParam->skipFman11Workaround = TRUE;
+
+ return E_OK;
+}
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+
+/*****************************************************************************/
+/* Tgec Run Time API functions */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ uint32_t ptv = 0;
+ t_TgecMemMap *p_MemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_STATE);
+
+ p_MemMap = (t_TgecMemMap*)(p_Tgec->p_MemMap);
+
+ ptv = (uint32_t)pauseTime;
+
+ WRITE_UINT32(p_MemMap->pause_quant, ptv);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_MemMap;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_STATE);
+
+ p_MemMap = (t_TgecMemMap*)(p_Tgec->p_MemMap);
+ tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
+ if (en)
+ tmpReg32 |= CMD_CFG_PAUSE_IGNORE;
+ else
+ tmpReg32 &= ~CMD_CFG_PAUSE_IGNORE;
+ WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
+
+ return E_OK;
+}
+
+/* Counters handling */
+/* .............................................................................. */
+
+static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+
+ p_Statistics->eStatPkts64 = GET_UINT64(p_TgecMemMap->R64);
+ p_Statistics->eStatPkts65to127 = GET_UINT64(p_TgecMemMap->R127);
+ p_Statistics->eStatPkts128to255 = GET_UINT64(p_TgecMemMap->R255);
+ p_Statistics->eStatPkts256to511 = GET_UINT64(p_TgecMemMap->R511);
+ p_Statistics->eStatPkts512to1023 = GET_UINT64(p_TgecMemMap->R1023);
+ p_Statistics->eStatPkts1024to1518 = GET_UINT64(p_TgecMemMap->R1518);
+ p_Statistics->eStatPkts1519to1522 = GET_UINT64(p_TgecMemMap->R1519X);
+/* */
+ p_Statistics->eStatFragments = GET_UINT64(p_TgecMemMap->TRFRG);
+ p_Statistics->eStatJabbers = GET_UINT64(p_TgecMemMap->TRJBR);
+
+ p_Statistics->eStatsDropEvents = GET_UINT64(p_TgecMemMap->RDRP);
+ p_Statistics->eStatCRCAlignErrors = GET_UINT64(p_TgecMemMap->RALN);
+
+ p_Statistics->eStatUndersizePkts = GET_UINT64(p_TgecMemMap->TRUND);
+ p_Statistics->eStatOversizePkts = GET_UINT64(p_TgecMemMap->TROVR);
+/* Pause */
+ p_Statistics->reStatPause = GET_UINT64(p_TgecMemMap->RXPF);
+ p_Statistics->teStatPause = GET_UINT64(p_TgecMemMap->TXPF);
+
+
+/* MIB II */
+ p_Statistics->ifInOctets = GET_UINT64(p_TgecMemMap->ROCT);
+ p_Statistics->ifInMcastPkts = GET_UINT64(p_TgecMemMap->RMCA);
+ p_Statistics->ifInBcastPkts = GET_UINT64(p_TgecMemMap->RBCA);
+ p_Statistics->ifInPkts = GET_UINT64(p_TgecMemMap->RUCA)
+ + p_Statistics->ifInMcastPkts
+ + p_Statistics->ifInBcastPkts;
+ p_Statistics->ifInDiscards = 0;
+ p_Statistics->ifInErrors = GET_UINT64(p_TgecMemMap->RERR);
+
+ p_Statistics->ifOutOctets = GET_UINT64(p_TgecMemMap->TOCT);
+ p_Statistics->ifOutMcastPkts = GET_UINT64(p_TgecMemMap->TMCA);
+ p_Statistics->ifOutBcastPkts = GET_UINT64(p_TgecMemMap->TBCA);
+ p_Statistics->ifOutPkts = GET_UINT64(p_TgecMemMap->TUCA);
+ p_Statistics->ifOutDiscards = 0;
+ p_Statistics->ifOutErrors = GET_UINT64(p_TgecMemMap->TERR);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+ SANITY_CHECK_RETURN_ERROR(p_TgecMemMap, E_INVALID_HANDLE);
+
+ WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, GET_UINT32(p_TgecMemMap->cmd_conf_ctrl) | CMD_CFG_EN_TIMESTAMP);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+ SANITY_CHECK_RETURN_ERROR(p_TgecMemMap, E_INVALID_HANDLE);
+
+ WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, GET_UINT32(p_TgecMemMap->cmd_conf_ctrl) & ~CMD_CFG_EN_TIMESTAMP);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+ uint32_t tmpReg32 = 0;
+ uint64_t addr;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+
+ /* Initialize MAC Station Address registers (1 & 2) */
+ /* Station address have to be swapped (big endian to little endian */
+
+ addr = ((*(uint64_t *)p_EnetAddr) >> 16);
+ p_Tgec->addr = addr;
+
+ tmpReg32 = (uint32_t)(addr>>16);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_TgecMemMap->mac_addr_0, tmpReg32);
+
+ tmpReg32 = (uint32_t)(addr);
+ SwapUint32P(&tmpReg32);
+ tmpReg32 >>= 16;
+ WRITE_UINT32(p_TgecMemMap->mac_addr_1, tmpReg32);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecResetCounters (t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_MemMap ;
+ uint32_t tmpReg32, cmdConfCtrl;
+ int i;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
+
+ p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap);
+
+ cmdConfCtrl = GET_UINT32(p_MemMap->cmd_conf_ctrl);
+
+ cmdConfCtrl |= CMD_CFG_STAT_CLR;
+
+ WRITE_UINT32(p_MemMap->cmd_conf_ctrl, cmdConfCtrl);
+
+ for (i=0; i<1000; i++)
+ {
+ tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
+ if (!(tmpReg32 & CMD_CFG_STAT_CLR))
+ break;
+ }
+
+ cmdConfCtrl &= ~CMD_CFG_STAT_CLR;
+ WRITE_UINT32(p_MemMap->cmd_conf_ctrl, cmdConfCtrl);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
+{
+ t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
+ uint64_t ethAddr;
+ uint8_t paddrNum;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ if (ethAddr & GROUP_ADDRESS)
+ /* Multicast address has no effect in PADDR */
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
+
+ /* Make sure no PADDR contains this address */
+ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
+ {
+ if (p_Tgec->indAddrRegUsed[paddrNum])
+ {
+ if (p_Tgec->paddr[paddrNum] == ethAddr)
+ {
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
+ }
+ }
+ }
+
+ /* Find first unused PADDR */
+ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
+ {
+ if (!(p_Tgec->indAddrRegUsed[paddrNum]))
+ {
+ /* mark this PADDR as used */
+ p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
+ /* store address */
+ p_Tgec->paddr[paddrNum] = ethAddr;
+
+ /* put in hardware */
+ HardwareAddAddrInPaddr(p_Tgec, &ethAddr, paddrNum);
+ p_Tgec->numOfIndAddrInRegs++;
+
+ return E_OK;
+ }
+ }
+
+ /* No free PADDR */
+ RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
+}
+
+/* .............................................................................. */
+
+static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
+{
+ t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
+ uint64_t ethAddr;
+ uint8_t paddrNum;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
+
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ /* Find used PADDR containing this address */
+ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
+ {
+ if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
+ (p_Tgec->paddr[paddrNum] == ethAddr))
+ {
+ /* mark this PADDR as not used */
+ p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
+ /* clear in hardware */
+ HardwareClearAddrInPaddr(p_Tgec, paddrNum);
+ p_Tgec->numOfIndAddrInRegs--;
+
+ return E_OK;
+ }
+ }
+
+ RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
+}
+
+/* .............................................................................. */
+
+static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+ t_EthHashEntry *p_HashEntry;
+ uint32_t crc;
+ uint32_t hash;
+ uint64_t ethAddr;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ if (!(ethAddr & GROUP_ADDRESS))
+ /* Unicast addresses not supported in hash */
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
+
+ /* CRC calculation */
+ GET_MAC_ADDR_CRC(ethAddr, crc);
+ crc = MIRROR_32(crc);
+
+ hash = (crc >> HASH_CTRL_MCAST_SHIFT) & HASH_ADDR_MASK; /* Take 9 MSB bits */
+
+ /* Create element to be added to the driver hash table */
+ p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
+ p_HashEntry->addr = ethAddr;
+ INIT_LIST(&p_HashEntry->node);
+
+ LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
+ WRITE_UINT32(p_TgecMemMap->hashtable_ctrl, (hash | HASH_CTRL_MCAST_EN));
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+ t_EthHashEntry *p_HashEntry = NULL;
+ t_List *p_Pos;
+ uint32_t crc;
+ uint32_t hash;
+ uint64_t ethAddr;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
+
+ /* CRC calculation */
+ GET_MAC_ADDR_CRC(ethAddr, crc);
+ crc = MIRROR_32(crc);
+
+ hash = (crc >> HASH_CTRL_MCAST_SHIFT) & HASH_ADDR_MASK; /* Take 9 MSB bits */
+
+ LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
+ {
+
+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
+ if(p_HashEntry->addr == ethAddr)
+ {
+ LIST_DelAndInit(&p_HashEntry->node);
+ XX_Free(p_HashEntry);
+ break;
+ }
+ }
+ if(LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
+ WRITE_UINT32(p_TgecMemMap->hashtable_ctrl, (hash & ~HASH_CTRL_MCAST_EN));
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
+
+ UNUSED(p_Tgec);
+ UNUSED(macId);
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
+}
+
+/* .............................................................................. */
+
+static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMemMap *p_TgecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+ *macVersion = GET_UINT32(p_TgecMemMap->tgec_id);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ uint32_t bitMask = 0, tmpReg;
+ t_TgecMemMap *p_TgecMemMap;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
+
+ p_TgecMemMap = p_Tgec->p_MemMap;
+#ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
+ if((revInfo.majorRev <=2) &&
+ enable &&
+ ((exception == e_FM_MAC_EX_10G_LOC_FAULT) || (exception == e_FM_MAC_EX_10G_REM_FAULT)))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_MAC_EX_10G_LOC_FAULT and e_FM_MAC_EX_10G_REM_FAULT !"));
+ }
+#endif /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */
+
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Tgec->exceptions |= bitMask;
+ else
+ p_Tgec->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ tmpReg = GET_UINT32(p_TgecMemMap->imask);
+ if(enable)
+ tmpReg |= bitMask;
+ else
+ tmpReg &= ~bitMask;
+ WRITE_UINT32(p_TgecMemMap->imask, tmpReg);
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
+
+ return (uint16_t)GET_UINT32(p_Tgec->p_MemMap->maxfrm);
+}
+
+/* .............................................................................. */
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
+{
+ t_Error err;
+
+ XX_Print("Applying 10G tx-ecc error workaround (10GMAC-A004) ...");
+ /* enable and set promiscuous */
+ WRITE_UINT32(p_Tgec->p_MemMap->cmd_conf_ctrl, CMD_CFG_PROMIS_EN | CMD_CFG_TX_EN | CMD_CFG_RX_EN);
+ err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
+ /* disable */
+ WRITE_UINT32(p_Tgec->p_MemMap->cmd_conf_ctrl, 0);
+ if (err)
+ XX_Print("FAILED!\n");
+ else
+ XX_Print("done.\n");
+ TgecResetCounters (p_Tgec);
+
+ return err;
+}
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+/* .............................................................................. */
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+static t_Error TgecDumpRegs(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ DECLARE_DUMP;
+
+ if (p_Tgec->p_MemMap)
+ {
+ DUMP_TITLE(p_Tgec->p_MemMap, ("10G MAC %d: ", p_Tgec->macId));
+ DUMP_VAR(p_Tgec->p_MemMap, tgec_id);
+ DUMP_VAR(p_Tgec->p_MemMap, scratch);
+ DUMP_VAR(p_Tgec->p_MemMap, cmd_conf_ctrl);
+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_0);
+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_1);
+ DUMP_VAR(p_Tgec->p_MemMap, maxfrm);
+ DUMP_VAR(p_Tgec->p_MemMap, pause_quant);
+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_sections);
+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_sections);
+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_almost_f_e);
+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_almost_f_e);
+ DUMP_VAR(p_Tgec->p_MemMap, hashtable_ctrl);
+ DUMP_VAR(p_Tgec->p_MemMap, mdio_cfg_status);
+ DUMP_VAR(p_Tgec->p_MemMap, mdio_command);
+ DUMP_VAR(p_Tgec->p_MemMap, mdio_data);
+ DUMP_VAR(p_Tgec->p_MemMap, mdio_regaddr);
+ DUMP_VAR(p_Tgec->p_MemMap, status);
+ DUMP_VAR(p_Tgec->p_MemMap, tx_ipg_len);
+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_2);
+ DUMP_VAR(p_Tgec->p_MemMap, mac_addr_3);
+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_rd);
+ DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_wr);
+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_rd);
+ DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_wr);
+ DUMP_VAR(p_Tgec->p_MemMap, imask);
+ DUMP_VAR(p_Tgec->p_MemMap, ievent);
+ DUMP_VAR(p_Tgec->p_MemMap, udp_port);
+ DUMP_VAR(p_Tgec->p_MemMap, type_1588v2);
+ }
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+
+/*****************************************************************************/
+/* FM Init & Free API */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+static t_Error TgecInit(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecDriverParam *p_TgecDriverParam;
+ t_TgecMemMap *p_MemMap;
+ uint64_t addr;
+ uint32_t tmpReg32;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+ if (!p_Tgec->p_TgecDriverParam->skipFman11Workaround &&
+ ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
+#ifdef NCSW_LINUX
+ {
+ /* the workaround fails in simics, just report and continue initialization */
+ REPORT_ERROR(MAJOR, err, ("TgecTxEccWorkaround FAILED, skipping workaround"));
+ }
+#else
+ {
+ FreeInitResources(p_Tgec);
+ RETURN_ERROR(MAJOR, err, ("TgecTxEccWorkaround FAILED"));
+ }
+#endif
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+ CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
+
+ p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
+ p_MemMap = p_Tgec->p_MemMap;
+
+ /* MAC Address */
+ addr = p_Tgec->addr;
+ tmpReg32 = (uint32_t)(addr>>16);
+ SwapUint32P(&tmpReg32);
+ WRITE_UINT32(p_MemMap->mac_addr_0, tmpReg32);
+
+ tmpReg32 = (uint32_t)(addr);
+ SwapUint32P(&tmpReg32);
+ tmpReg32 >>= 16;
+ WRITE_UINT32(p_MemMap->mac_addr_1, tmpReg32);
+
+ /* Config */
+ tmpReg32 = 0;
+ if (p_TgecDriverParam->wanModeEnable)
+ tmpReg32 |= CMD_CFG_WAN_MODE;
+ if (p_TgecDriverParam->promiscuousModeEnable)
+ tmpReg32 |= CMD_CFG_PROMIS_EN;
+ if (p_TgecDriverParam->pauseForwardEnable)
+ tmpReg32 |= CMD_CFG_PAUSE_FWD;
+ if (p_TgecDriverParam->pauseIgnore)
+ tmpReg32 |= CMD_CFG_PAUSE_IGNORE;
+ if (p_TgecDriverParam->txAddrInsEnable)
+ tmpReg32 |= CMD_CFG_TX_ADDR_INS;
+ if (p_TgecDriverParam->loopbackEnable)
+ tmpReg32 |= CMD_CFG_LOOPBACK_EN;
+ if (p_TgecDriverParam->cmdFrameEnable)
+ tmpReg32 |= CMD_CFG_CMD_FRM_EN;
+ if (p_TgecDriverParam->rxErrorDiscard)
+ tmpReg32 |= CMD_CFG_RX_ER_DISC;
+ if (p_TgecDriverParam->phyTxenaOn)
+ tmpReg32 |= CMD_CFG_PHY_TX_EN;
+ if (p_TgecDriverParam->sendIdleEnable)
+ tmpReg32 |= CMD_CFG_SEND_IDLE;
+ if (p_TgecDriverParam->noLengthCheckEnable)
+ tmpReg32 |= CMD_CFG_NO_LEN_CHK;
+ if (p_TgecDriverParam->lgthCheckNostdr)
+ tmpReg32 |= CMD_CFG_LEN_CHK_NOSTDR;
+ if (p_TgecDriverParam->timeStampEnable)
+ tmpReg32 |= CMD_CFG_EN_TIMESTAMP;
+ if (p_TgecDriverParam->rxSfdAny)
+ tmpReg32 |= RX_SFD_ANY;
+ if (p_TgecDriverParam->rxPblFwd)
+ tmpReg32 |= CMD_CFG_RX_PBL_FWD;
+ if (p_TgecDriverParam->txPblFwd)
+ tmpReg32 |= CMD_CFG_TX_PBL_FWD;
+ tmpReg32 |= 0x40;
+ WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
+
+ /* Max Frame Length */
+ WRITE_UINT32(p_MemMap->maxfrm, (uint32_t)p_TgecDriverParam->maxFrameLength);
+ err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MAC_10G, p_Tgec->fmMacControllerDriver.macId, p_TgecDriverParam->maxFrameLength);
+ if(err)
+ {
+ FreeInitResources(p_Tgec);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ /* Pause Time */
+ WRITE_UINT32(p_MemMap->pause_quant, p_TgecDriverParam->pauseTime);
+
+#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
+ WRITE_UINT32(p_Tgec->p_MemMap->tx_ipg_len,
+ (GET_UINT32(p_Tgec->p_MemMap->tx_ipg_len) & ~TX_IPG_LENGTH_MASK) | DEFAULT_txIpgLength);
+#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
+
+ /* Configure MII */
+ tmpReg32 = GET_UINT32(p_Tgec->p_MiiMemMap->mdio_cfg_status);
+#ifdef FM_10G_MDIO_HOLD_ERRATA_XAUI3
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ tmpReg32 |= (MIIMCOM_MDIO_HOLD_4_REG_CLK << 2);
+ }
+#endif /* FM_10G_MDIO_HOLD_ERRATA_XAUI3 */
+ tmpReg32 &= ~MIIMCOM_DIV_MASK;
+ /* (one half of fm clock => 2.5Mhz) */
+ tmpReg32 |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
+ WRITE_UINT32(p_Tgec->p_MiiMemMap->mdio_cfg_status, tmpReg32);
+
+ p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
+ if(!p_Tgec->p_MulticastAddrHash)
+ {
+ FreeInitResources(p_Tgec);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
+ }
+
+ p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
+ if(!p_Tgec->p_UnicastAddrHash)
+ {
+ FreeInitResources(p_Tgec);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
+ }
+
+ /* interrupts */
+#ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
+ if (revInfo.majorRev <=2)
+ p_Tgec->exceptions &= ~(IMASK_REM_FAULT | IMASK_LOC_FAULT);
+ }
+#endif /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */
+ WRITE_UINT32(p_MemMap->ievent, EVENTS_MASK);
+ WRITE_UINT32(p_MemMap->imask, p_Tgec->exceptions);
+
+ FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR, TgecErrException , p_Tgec);
+ if ((p_Tgec->mdioIrq != 0) && (p_Tgec->mdioIrq != NO_IRQ))
+ {
+ XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
+ XX_EnableIntr(p_Tgec->mdioIrq);
+ }
+ else if (p_Tgec->mdioIrq == 0)
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, (NO_MSG));
+
+ XX_Free(p_TgecDriverParam);
+ p_Tgec->p_TgecDriverParam = NULL;
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static t_Error TgecFree(t_Handle h_Tgec)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+
+ FreeInitResources(p_Tgec);
+
+ if (p_Tgec->p_TgecDriverParam)
+ {
+ XX_Free(p_Tgec->p_TgecDriverParam);
+ p_Tgec->p_TgecDriverParam = NULL;
+ }
+ XX_Free (p_Tgec);
+
+ return E_OK;
+}
+
+/* .............................................................................. */
+
+static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
+{
+ p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
+ p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
+
+ p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
+ p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
+
+ p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
+
+ p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
+ p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
+ p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
+ p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+ p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+ p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
+
+ p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
+ p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
+
+ p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
+ p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
+
+ p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
+ p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
+
+ p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
+ p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
+
+ p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
+ p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
+
+ p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
+ p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
+ p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
+ p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
+
+ p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
+ p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ p_FmMacControllerDriver->f_FM_MAC_DumpRegs = TgecDumpRegs;
+#endif /* (defined(DEBUG_ERRORS) && ... */
+}
+
+
+/*****************************************************************************/
+/* Tgec Config Main Entry */
+/*****************************************************************************/
+
+/* .............................................................................. */
+
+t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
+{
+ t_Tgec *p_Tgec;
+ t_TgecDriverParam *p_TgecDriverParam;
+ uintptr_t baseAddr;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
+
+ baseAddr = p_FmMacParam->baseAddr;
+ /* allocate memory for the UCC GETH data structure. */
+ p_Tgec = (t_Tgec *) XX_Malloc(sizeof(t_Tgec));
+ if (!p_Tgec)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
+ return NULL;
+ }
+ /* Zero out * p_Tgec */
+ memset(p_Tgec, 0, sizeof(t_Tgec));
+ InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
+
+ /* allocate memory for the 10G MAC driver parameters data structure. */
+ p_TgecDriverParam = (t_TgecDriverParam *) XX_Malloc(sizeof(t_TgecDriverParam));
+ if (!p_TgecDriverParam)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
+ TgecFree(p_Tgec);
+ return NULL;
+ }
+ /* Zero out */
+ memset(p_TgecDriverParam, 0, sizeof(t_TgecDriverParam));
+
+ /* Plant parameter structure pointer */
+ p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
+
+ SetDefaultParam(p_TgecDriverParam);
+
+ for (i=0; i < sizeof(p_FmMacParam->addr); i++)
+ p_Tgec->addr |= ((uint64_t)p_FmMacParam->addr[i] << ((5-i) * 8));
+
+ p_Tgec->p_MemMap = (t_TgecMemMap *)UINT_TO_PTR(baseAddr);
+ p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
+ p_Tgec->enetMode = p_FmMacParam->enetMode;
+ p_Tgec->macId = p_FmMacParam->macId;
+ p_Tgec->exceptions = DEFAULT_exceptions;
+ p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
+ p_Tgec->f_Exception = p_FmMacParam->f_Exception;
+ p_Tgec->f_Event = p_FmMacParam->f_Event;
+ p_Tgec->h_App = p_FmMacParam->h_App;
+
+ return p_Tgec;
+}
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h
new file mode 100644
index 0000000..db22ead
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.h
@@ -0,0 +1,482 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File tgec.h
+
+ @Description FM 10G MAC ...
+*//***************************************************************************/
+#ifndef __TGEC_H
+#define __TGEC_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "list_ext.h"
+#include "tgec_mii_acc.h"
+#include "fm_mac.h"
+
+
+/* Interrupt Mask Register (IMASK) */
+#define IMASK_MDIO_SCAN_EVENTMDIO 0x00010000 /* MDIO_SCAN_EVENTMDIO scan event interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_MDIO_CMD_CMPL 0x00008000 /* 16 MDIO_CMD_CMPL MDIO command completion interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_REM_FAULT 0x00004000 /* 17 REM_FAULT Remote fault interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_LOC_FAULT 0x00002000 /* 18 LOC_FAULT Local fault interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_1TX_ECC_ER 0x00001000 /* 19 TX_ECC_ER Transmit frame ECC error interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_TX_FIFO_UNFL 0x00000800 /* 20 TX_FIFO_UNFL Transmit FIFO underflow interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_TX_FIFO_OVFL 0x00000400 /* 21 TX_FIFO_OVFL Transmit FIFO overflow interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_TX_ER 0x00000200 /* 22 TX_ER Transmit frame error interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_FIFO_OVFL 0x00000100 /* 23 RX_FIFO_OVFL Receive FIFO overflow interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_ECC_ER 0x00000080 /* 24 RX_ECC_ER Receive frame ECC error interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_JAB_FRM 0x00000040 /* 25 RX_JAB_FRM Receive jabber frame interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_OVRSZ_FRM 0x00000020 /* 26 RX_OVRSZ_FRM Receive oversized frame interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_RUNT_FRM 0x00000010 /* 27 RX_RUNT_FRM Receive runt frame interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_FRAG_FRM 0x00000008 /* 28 RX_FRAG_FRM Receive fragment frame interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_LEN_ER 0x00000004 /* 29 RX_LEN_ER Receive payload length error interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_CRC_ER 0x00000002 /* 30 RX_CRC_ER Receive CRC error interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+#define IMASK_RX_ALIGN_ER 0x00000001 /* 31 RX_ALIGN_ER Receive alignment error interrupt mask.
+ * 0 masked
+ * 1 enabled
+ */
+
+#define EVENTS_MASK ((uint32_t)(IMASK_MDIO_SCAN_EVENTMDIO | \
+ IMASK_MDIO_CMD_CMPL | \
+ IMASK_REM_FAULT | \
+ IMASK_LOC_FAULT | \
+ IMASK_1TX_ECC_ER | \
+ IMASK_TX_FIFO_UNFL | \
+ IMASK_TX_FIFO_OVFL | \
+ IMASK_TX_ER | \
+ IMASK_RX_FIFO_OVFL | \
+ IMASK_RX_ECC_ER | \
+ IMASK_RX_JAB_FRM | \
+ IMASK_RX_OVRSZ_FRM | \
+ IMASK_RX_RUNT_FRM | \
+ IMASK_RX_FRAG_FRM | \
+ IMASK_RX_LEN_ER | \
+ IMASK_RX_CRC_ER | \
+ IMASK_RX_ALIGN_ER))
+
+#define GET_EXCEPTION_FLAG(bitMask, exception) switch(exception){ \
+ case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
+ bitMask = IMASK_MDIO_SCAN_EVENTMDIO; break; \
+ case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
+ bitMask = IMASK_MDIO_CMD_CMPL ; break; \
+ case e_FM_MAC_EX_10G_REM_FAULT: \
+ bitMask = IMASK_REM_FAULT ; break; \
+ case e_FM_MAC_EX_10G_LOC_FAULT: \
+ bitMask = IMASK_LOC_FAULT ; break; \
+ case e_FM_MAC_EX_10G_1TX_ECC_ER: \
+ bitMask = IMASK_1TX_ECC_ER ; break; \
+ case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
+ bitMask = IMASK_TX_FIFO_UNFL ; break; \
+ case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
+ bitMask = IMASK_TX_FIFO_OVFL ; break; \
+ case e_FM_MAC_EX_10G_TX_ER: \
+ bitMask = IMASK_TX_ER ; break; \
+ case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
+ bitMask = IMASK_RX_FIFO_OVFL ; break; \
+ case e_FM_MAC_EX_10G_RX_ECC_ER: \
+ bitMask = IMASK_RX_ECC_ER ; break; \
+ case e_FM_MAC_EX_10G_RX_JAB_FRM: \
+ bitMask = IMASK_RX_JAB_FRM ; break; \
+ case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
+ bitMask = IMASK_RX_OVRSZ_FRM ; break; \
+ case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
+ bitMask = IMASK_RX_RUNT_FRM ; break; \
+ case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
+ bitMask = IMASK_RX_FRAG_FRM ; break; \
+ case e_FM_MAC_EX_10G_RX_LEN_ER: \
+ bitMask = IMASK_RX_LEN_ER ; break; \
+ case e_FM_MAC_EX_10G_RX_CRC_ER: \
+ bitMask = IMASK_RX_CRC_ER ; break; \
+ case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
+ bitMask = IMASK_RX_ALIGN_ER ; break; \
+ default: bitMask = 0;break;}
+
+
+/* Default Config Params */
+#define DEFAULT_wanModeEnable FALSE
+#define DEFAULT_promiscuousModeEnable FALSE
+
+
+#define DEFAULT_pauseForwardEnable FALSE
+#define DEFAULT_pauseIgnore FALSE
+#define DEFAULT_txAddrInsEnable FALSE
+
+#define DEFAULT_loopbackEnable FALSE
+#define DEFAULT_cmdFrameEnable FALSE
+#define DEFAULT_rxErrorDiscard FALSE
+#define DEFAULT_phyTxenaOn FALSE
+#define DEFAULT_sendIdleEnable FALSE
+#define DEFAULT_noLengthCheckEnable TRUE
+#define DEFAULT_lgthCheckNostdr FALSE
+#define DEFAULT_timeStampEnable FALSE
+#define DEFAULT_rxSfdAny FALSE
+#define DEFAULT_rxPblFwd FALSE
+#define DEFAULT_txPblFwd FALSE
+#define DEFAULT_txIpgLength 12
+
+#define DEFAULT_maxFrameLength 0x600
+
+#define DEFAULT_debugMode FALSE
+#define DEFAULT_pauseTime 0xf000
+#define DEFAULT_imask 0xf000
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+#define DEFAULT_skipFman11Workaround FALSE
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+#define DEFAULT_exceptions ((uint32_t)(IMASK_MDIO_SCAN_EVENTMDIO | \
+ IMASK_REM_FAULT | \
+ IMASK_LOC_FAULT | \
+ IMASK_1TX_ECC_ER | \
+ IMASK_TX_FIFO_UNFL | \
+ IMASK_TX_FIFO_OVFL | \
+ IMASK_TX_ER | \
+ IMASK_RX_FIFO_OVFL | \
+ IMASK_RX_ECC_ER | \
+ IMASK_RX_JAB_FRM | \
+ IMASK_RX_OVRSZ_FRM | \
+ IMASK_RX_RUNT_FRM | \
+ IMASK_RX_FRAG_FRM | \
+ IMASK_RX_CRC_ER | \
+ IMASK_RX_ALIGN_ER))
+
+#define MAX_PACKET_ALIGNMENT 31
+#define MAX_INTER_PACKET_GAP 0x7f
+#define MAX_INTER_PALTERNATE_BEB 0x0f
+#define MAX_RETRANSMISSION 0x0f
+#define MAX_COLLISION_WINDOW 0x03ff
+
+
+#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
+
+#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
+
+#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
+
+#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
+
+/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
+#define TGEC_ID_ID 0xffff0000
+#define TGEC_ID_MAC_VERSION 0x0000FF00
+#define TGEC_ID_MAC_REV 0x000000ff
+
+/* Command and Configuration Register (COMMAND_CONFIG) */
+#define CMD_CFG_TX_PBL_FWD 0x00800000 /* 08 Transmit Preamble Forwarding (custom preamble).
+ */
+#define CMD_CFG_RX_PBL_FWD 0x00400000 /* 09 Receive Preamble Forwarding (custom preamble).
+ */
+#define RX_SFD_ANY 0x00200000 /* 10 Enables, when set, that any character is allowed at the SFD position of the preamble and the frame will be accepted.
+ */
+#define CMD_CFG_EN_TIMESTAMP 0x00100000 /* 11 EN_TIMESTAMP IEEE 1588 timeStamp functionality control.
+ * 0 disabled
+ * 1 enabled
+ */
+#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000 /* 12 TX_ADDR_INS_SEL Transmit MAC address select
+ * 0 insert using first MAC address
+ * 1 insert using second MAC address
+ */
+#define CMD_CFG_LEN_CHK_NOSTDR 0x00040000 /* 13 LEN_CHK_NOSTDR
+ */
+#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 NO_LEN_CHK Payload length check disable
+ * 0 MAC compares the frame payload length with the frame length/type field.
+ * 1 Payload length check is disabled.
+ */
+#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 SEND_IDLE Force idle generation
+ * 0 Normal operation.
+ * 1 MAC permanently sends XGMII idle sequences even when faults are received.
+ */
+#define CMD_CFG_PHY_TX_EN 0x00008000 /* 16 PHY_TX_EN PHY transmit enable
+ * 0 PHY transmit is disabled.
+ * 1 PHY transmit is enabled.
+ */
+#define CMD_CFG_RX_ER_DISC 0x00004000 /* 17 RX_ER_DISC Receive error frame discard enable
+ * 0 Received error frames are processed.
+ * 1 Any frame received with an error is discarded.
+ */
+#define CMD_CFG_CMD_FRM_EN 0x00002000 /* 18 CMD_FRM_EN Command frame reception enable
+ * 0 Only Pause frames are accepted (all other command frames are rejected).
+ * 1 All command frames are accepted.
+ */
+#define CMD_CFG_STAT_CLR 0x00001000 /* 19 STAT_CLR Clear statistics
+ * 0 Normal operations.
+ * 1 All statistics counters are cleared.
+ */
+#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 LOOPBAC_EN PHY interface loopback enable
+ * 0 Configure PHY for normal operation.
+ * 1 Configure PHY for loopback mode.
+ */
+#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 TX_ADDR_INS Transmit source MAC address insertion
+ * 0 MAC transmits the source MAC address unmodified.
+ * 1 MAC overwrites the source MAC address with address specified by COMMAND_CONFIG[TX_ADDR_INS_SEL].
+ */
+#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 PAUSE_IGNORE Ignore Pause frame quanta
+ * 0 MAC stops transmit process for the duration specified in the Pause frame quanta of a received Pause frame.
+ * 1 MAC ignores received Pause frames.
+ */
+#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 PAUSE_FWD Terminate/forward received Pause frames
+ * 0 MAC terminates and discards received Pause frames.
+ * 1 MAC forwards Pause frames to the user application.
+ */
+#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 PROMIS_EN Promiscuous operation enable
+ * 0 Unicast frames with a destination address not matching the core MAC address (defined by registers, MAC_ADDR_0 and MAC_ADDR_1) are rejected.
+ * 1 All frames are received without any MAC address filtering.
+ */
+#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN_MODE WAN mode enable
+ * 0 Configure MAC for LAN mode.
+ * 1 Configure MAC for WAN mode.
+ */
+#define CMD_CFG_RX_EN 0x00000002 /* 30 RX_EN MAC receive path enable
+ * 0 MAC receive path is disabled
+ * 1 MAC receive path is enabled.
+ */
+#define CMD_CFG_TX_EN 0x00000001 /* 31 TX_EN MAC transmit path enable
+ * 0 MAC transmit path is disabled
+ * 1 MAC transmit path is enabled.
+ */
+
+/* Hashtable Control Register (HASHTABLE_CTRL) */
+#define HASH_CTRL_MCAST_SHIFT 23
+
+#define HASH_CTRL_MCAST_RD 0x00000400 /* 22 MCAST_READ Entry Multicast frame reception for the hash entry.
+ * 0 disabled
+ * 1 enabled
+ */
+#define HASH_CTRL_MCAST_EN 0x00000200 /* 22 MCAST_EN Multicast frame reception for the hash entry.
+ * 0 disabled
+ * 1 enabled
+ */
+#define HASH_ADDR_MASK 0x000001ff /* 23-31 HASH_ADDR Hash table address code.
+ */
+
+/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
+#define TX_IPG_LENGTH_MASK 0x000003ff
+
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/*
+ * 10G memory map
+ */
+typedef _Packed struct {
+/* 10Ge General Control and Status */
+ volatile uint32_t tgec_id; /* 0x000 10GEC_ID - Controller ID register */
+ volatile uint32_t scratch; /* 0x004 */
+ volatile uint32_t cmd_conf_ctrl; /* 0x008 COMMAND_CONFIG - Control and configuration register */
+ volatile uint32_t mac_addr_0; /* 0x00C MAC_ADDR_0 - Lower 32 bits of the first 48-bit MAC address */
+ volatile uint32_t mac_addr_1; /* 0x010 MAC_ADDR_1 - Upper 16 bits of the first 48-bit MAC address */
+ volatile uint32_t maxfrm; /* 0x014 MAXFRM - Maximum frame length register */
+ volatile uint32_t pause_quant; /* 0x018 PAUSE_QUANT - Pause quanta register */
+ volatile uint32_t rx_fifo_sections; /* 0x01c */
+ volatile uint32_t tx_fifo_sections; /* 0x020 */
+ volatile uint32_t rx_fifo_almost_f_e; /* 0x024 */
+ volatile uint32_t tx_fifo_almost_f_e; /* 0x028 */
+ volatile uint32_t hashtable_ctrl; /* 0x02C HASHTABLE_CTRL - Hash table control register */
+ volatile uint32_t mdio_cfg_status; /* 0x030 */
+ volatile uint32_t mdio_command; /* 0x034 */
+ volatile uint32_t mdio_data; /* 0x038 */
+ volatile uint32_t mdio_regaddr; /* 0x03c */
+ volatile uint32_t status; /* 0x040 */
+ volatile uint32_t tx_ipg_len; /* 0x044 TX_IPG_LENGTH - Transmitter inter-packet-gap register */
+ volatile uint32_t mac_addr_2; /* 0x048 MAC_ADDR_2 - Lower 32 bits of the second 48-bit MAC address */
+ volatile uint32_t mac_addr_3; /* 0x04C MAC_ADDR_3 - Upper 16 bits of the second 48-bit MAC address */
+ volatile uint32_t rx_fifo_ptr_rd; /* 0x050 */
+ volatile uint32_t rx_fifo_ptr_wr; /* 0x054 */
+ volatile uint32_t tx_fifo_ptr_rd; /* 0x058 */
+ volatile uint32_t tx_fifo_ptr_wr; /* 0x05c */
+ volatile uint32_t imask; /* 0x060 IMASK - Interrupt mask register */
+ volatile uint32_t ievent; /* 0x064 IEVENT - Interrupt event register */
+ volatile uint32_t udp_port; /* 0x068 Defines a UDP Port number. When an UDP/IP frame is received with a matching UDP destination port, the receive status indication pin ff_rx_ts_frm will be asserted.*/
+ volatile uint32_t type_1588v2; /* 0x06c Type field for 1588v2 layer 2 frames. IEEE1588 defines the type 0x88f7 for 1588 frames. */
+ volatile uint32_t TENGEC_RESERVED4[4];
+/*10Ge Statistics Counter */
+ volatile uint64_t TFRM; /* 80 aFramesTransmittedOK */
+ volatile uint64_t RFRM; /* 88 aFramesReceivedOK */
+ volatile uint64_t RFCS; /* 90 aFrameCheckSequenceErrors */
+ volatile uint64_t RALN; /* 98 aAlignmentErrors */
+ volatile uint64_t TXPF; /* A0 aPAUSEMACCtrlFramesTransmitted */
+ volatile uint64_t RXPF; /* A8 aPAUSEMACCtrlFramesReceived */
+ volatile uint64_t RLONG; /* B0 aFrameTooLongErrors */
+ volatile uint64_t RFLR; /* B8 aInRangeLengthErrors */
+ volatile uint64_t TVLAN; /* C0 VLANTransmittedOK */
+ volatile uint64_t RVLAN; /* C8 VLANReceivedOK */
+ volatile uint64_t TOCT; /* D0 ifOutOctets */
+ volatile uint64_t ROCT; /* D8 ifInOctets */
+ volatile uint64_t RUCA; /* E0 ifInUcastPkts */
+ volatile uint64_t RMCA; /* E8 ifInMulticastPkts */
+ volatile uint64_t RBCA; /* F0 ifInBroadcastPkts */
+ volatile uint64_t TERR; /* F8 ifOutErrors */
+ volatile uint32_t TENGEC_RESERVED6[2];
+ volatile uint64_t TUCA; /* 108 ifOutUcastPkts */
+ volatile uint64_t TMCA; /* 110 ifOutMulticastPkts */
+ volatile uint64_t TBCA; /* 118 ifOutBroadcastPkts */
+ volatile uint64_t RDRP; /* 120 etherStatsDropEvents */
+ volatile uint64_t REOCT; /* 128 etherStatsOctets */
+ volatile uint64_t RPKT; /* 130 etherStatsPkts */
+ volatile uint64_t TRUND; /* 138 etherStatsUndersizePkts */
+ volatile uint64_t R64; /* 140 etherStatsPkts64Octets */
+ volatile uint64_t R127; /* 148 etherStatsPkts65to127Octets */
+ volatile uint64_t R255; /* 150 etherStatsPkts128to255Octets */
+ volatile uint64_t R511; /* 158 etherStatsPkts256to511Octets */
+ volatile uint64_t R1023; /* 160 etherStatsPkts512to1023Octets */
+ volatile uint64_t R1518; /* 168 etherStatsPkts1024to1518Octets */
+ volatile uint64_t R1519X; /* 170 etherStatsPkts1519toX */
+ volatile uint64_t TROVR; /* 178 etherStatsOversizePkts */
+ volatile uint64_t TRJBR; /* 180 etherStatsJabbers */
+ volatile uint64_t TRFRG; /* 188 etherStatsFragments */
+ volatile uint64_t RERR; /* 190 ifInErrors */
+} _PackedType t_TgecMemMap;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+typedef struct {
+ bool wanModeEnable; /* WAN Mode Enable. Sets WAN mode (1) or LAN mode (0, default) of operation. */
+ bool promiscuousModeEnable; /* Enables MAC promiscuous operation. When set to '1', all frames are received without any MAC address filtering, when set to '0' (Reset value) Unicast Frames with a destination address not matching the Core MAC Address (MAC Address programmed in Registers MAC_ADDR_0 and MAC_ADDR_1 or the MAC address programmed in Registers MAC_ADDR_2 and MAC_ADDR_3 ) are rejected. */
+ bool pauseForwardEnable; /* Terminate / Forward Pause Frames. If set to '1' pause frames are forwarded to the user application. When set to '0' (Reset value) pause frames are terminated and discarded within the MAC. */
+ bool pauseIgnore; /* Ignore Pause Frame Quanta. If set to '1' received pause frames are ignored by the MAC. When set to '0' (Reset value) the transmit process is stopped for the amount of time specified in the pause quanta received within a pause frame. */
+ bool txAddrInsEnable; /* Set Source MAC Address on Transmit.
+ If set to '1' the MAC overwrites the source MAC address received from the Client Interface with one of the MAC addresses (Refer to section 10.4)
+ If set to '0' (Reset value), the source MAC address from the Client Interface is transmitted unmodified to the line. */
+ bool loopbackEnable; /* PHY Interface Loopback. When set to '1', the signal loop_ena is set to '1', when set to '0' (Reset value) the signal loop_ena is set to '0'. */
+ bool cmdFrameEnable; /* Enables reception of all command frames. When set to '1' all Command Frames are accepted, when set to '0' (Reset Value) only Pause Frames are accepted and all other Command Frames are rejected. */
+ bool rxErrorDiscard; /* Receive Errored Frame Discard Enable. When set to ‘1’, any frame received with an error is discarded in the Core and not forwarded to the Client interface. When set to ‘0’ (Reset value), errored Frames are forwarded to the Client interface with ff_rx_err asserted. */
+ bool phyTxenaOn; /* PHY Transmit Enable. When set to '1', the signal phy_txena is set to '1', when set to '0' (Reset value) the signal phy_txena is set to '0' */
+ bool sendIdleEnable; /* Force Idle Generation. When set to '1', the MAC permanently sends XGMII Idle sequences even when faults are received. */
+ bool noLengthCheckEnable; /* Payload Length Check Disable. When set to ‘0’ (Reset value), the Core checks the frame's payload length with the Frame Length/Type field, when set to ‘1’, the payload length check is disabled. */
+ bool lgthCheckNostdr; /* The Core interprets the Length/Type field differently depending on the value of this Bit */
+ bool timeStampEnable; /* This bit selects between enabling and disabling the IEEE 1588 functionality.
+ 1: IEEE 1588 is enabled.
+ 0: IEEE 1588 is disabled. */
+ bool rxSfdAny; /* Enables, when set, that any character is allowed at the SFD position of the preamble and the frame will be accepted.
+ If cleared (default) the frame is accepted only if the 8th byte of the preamble contains the SFD value 0xd5. If another value is received, the frame is discarded and the alignment error counter increments. */
+ bool rxPblFwd; /* Receive Preamble Forwarding (custom preamble).
+ If set, the first word (ff_rx_sop) of every received frame contains the preamble of the frame. The frame data starts with the 2nd word from the FIFO.
+ If the bit is cleared (default) the preamble is removed from the frame before it is written into the receive FIFO. */
+ bool txPblFwd; /* Transmit Preamble Forwarding (custom preamble).
+ If set, the first word written into the TX FIFO is considered as frame preamble. The MAC will not add a preamble in front of the frame. Note that bits 7:0 of the preamble word will still be overwritten with the XGMII start character upon transmission.
+ If cleared (default) the MAC */
+ uint32_t txIpgLength; /*Transmit Inter-Packet-Gap (IPG) value.
+ A 6-bit value: Depending on LAN or WAN mode of operation (see COMMAND_CONFIG, 19.2.1 page 91) the value has the following meaning:
+ - LAN Mode: Number of octets in steps of 4. Valid values are 8, 12, 16, ... 100. DIC is fully supported (see 10.6.1 page 49) for any setting. A default of 12 (reset value) must be set to conform to IEEE802.3ae. Warning: When set to 8, PCS layers may not be able to perform clock rate compensation.
+ - WAN Mode: Stretch factor. Valid values are 4..15. The stretch factor is calculated as (value+1)*8. A default of 12 (reset value) must be set to conform to IEEE 802.3ae (i.e. 13*8=104). A larger value shrinks the IPG (increasing bandwidth). */
+/*.. */
+ uint16_t maxFrameLength;
+ bool debugMode;
+ uint16_t pauseTime;
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+ bool skipFman11Workaround;
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+} t_TgecDriverParam;
+
+typedef struct {
+ t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
+ t_Handle h_App; /**< Handle to the upper layer application */
+ t_TgecMemMap *p_MemMap; /**< pointer to 10G memory mapped registers. */
+ t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
+ uint64_t addr; /**< MAC address of device; */
+ e_EnetMode enetMode; /**< Ethernet physical interface */
+ t_FmMacExceptionCallback *f_Exception;
+ int mdioIrq;
+ t_FmMacExceptionCallback *f_Event;
+ bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
+ uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
+ uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
+ t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
+ t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
+ bool debugMode;
+ uint8_t macId;
+ uint32_t exceptions;
+ t_TgecDriverParam *p_TgecDriverParam;
+} t_Tgec;
+
+
+t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
+t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
+
+
+#endif /* __TGEC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c
new file mode 100644
index 0000000..c9753be
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c
@@ -0,0 +1,121 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "fm_mac.h"
+#include "tgec.h"
+#include "xx_ext.h"
+
+
+/*****************************************************************************/
+t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
+ uint8_t phyAddr,
+ uint8_t reg,
+ uint16_t data)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMiiAccessMemMap *p_MiiAccess;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
+
+ p_MiiAccess = p_Tgec->p_MiiMemMap;
+
+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
+ XX_UDelay (1);
+
+ WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
+
+ WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
+
+ CORE_MemoryBarrier();
+
+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
+ XX_UDelay (1);
+
+ WRITE_UINT32(p_MiiAccess->mdio_data, data);
+
+ CORE_MemoryBarrier();
+
+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
+ XX_UDelay (1);
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
+ uint8_t phyAddr,
+ uint8_t reg,
+ uint16_t *p_Data)
+{
+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
+ t_TgecMiiAccessMemMap *p_MiiAccess;
+ uint32_t cfg_status;
+
+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
+
+ p_MiiAccess = p_Tgec->p_MiiMemMap;
+
+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
+ XX_UDelay (1);
+
+ WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
+
+ WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
+
+ CORE_MemoryBarrier();
+
+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
+ XX_UDelay (1);
+
+ WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
+
+ CORE_MemoryBarrier();
+
+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
+ XX_UDelay (1);
+
+ *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
+
+ cfg_status = GET_UINT32(p_MiiAccess->mdio_cfg_status);
+
+ if (cfg_status & MIIMIND_READ_ERROR)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE,
+ ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfg_status 0x%x",
+ ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfg_status));
+
+ return E_OK;
+}
diff --git a/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h
new file mode 100644
index 0000000..81fd6ef
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.h
@@ -0,0 +1,81 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TGEC_MII_ACC_H
+#define __TGEC_MII_ACC_H
+
+#include "std_ext.h"
+
+
+/* MII Management Command Register */
+#define MIIMCOM_READ_POST_INCREMENT 0x00004000
+#define MIIMCOM_READ_CYCLE 0x00008000
+#define MIIMCOM_SCAN_CYCLE 0x00000800
+#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
+
+#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
+#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
+#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
+#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
+
+#define MIIMCOM_DIV_MASK 0x0000ff00
+#define MIIMCOM_DIV_SHIFT 8
+
+/* MII Management Indicator Register */
+#define MIIMIND_BUSY 0x00000001
+#define MIIMIND_READ_ERROR 0x00000002
+
+#define MIIDATA_BUSY 0x80000000
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/*----------------------------------------------------*/
+/* MII Configuration Control Memory Map Registers */
+/*----------------------------------------------------*/
+typedef _Packed struct t_TgecMiiAccessMemMap
+{
+ volatile uint32_t mdio_cfg_status; /* 0x030 */
+ volatile uint32_t mdio_command; /* 0x034 */
+ volatile uint32_t mdio_data; /* 0x038 */
+ volatile uint32_t mdio_regaddr; /* 0x03c */
+} _PackedType t_TgecMiiAccessMemMap ;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+#endif /* __TGEC_MII_ACC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c
new file mode 100644
index 0000000..fe765a4
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c
@@ -0,0 +1,3467 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_cc.c
+
+ @Description FM CC ...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "debug_ext.h"
+#include "fm_pcd_ext.h"
+#include "fm_muram_ext.h"
+
+#include "fm_common.h"
+#include "fm_hc.h"
+#include "fm_cc.h"
+
+
+#if defined(FM_CAPWAP_SUPPORT)
+#define FM_PCD_CC_MANIP
+#endif /* defined(FM_CAPWAP_SUPPORT) || ... */
+
+
+t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree, uint8_t manipIndx)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
+
+ ASSERT_COND(p_FmPcdCcTree);
+
+ return p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx];
+}
+
+void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams, uint8_t manipIndx)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
+
+ ASSERT_COND(p_FmPcdCcTree);
+
+ p_FmPcdCcTree->fmPcdCcSavedManipParams[manipIndx] = h_SavedManipParams;
+}
+
+uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+ return p_FmPcdCcNode->parseCode;
+}
+
+uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+ return p_FmPcdCcNode->offset;
+}
+
+uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+ return p_FmPcdCcNode->numOfKeys;
+}
+static void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo)
+{
+ t_CcNodeInformation *p_CcInformation;
+ uint32_t intFlags;
+
+ p_CcInformation = (t_CcNodeInformation *)XX_Malloc(sizeof(t_CcNodeInformation));
+ if (p_CcInformation)
+ {
+ memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
+ memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
+ INIT_LIST(&p_CcInformation->node);
+
+ intFlags = XX_DisableAllIntr();
+ LIST_AddToTail(&p_CcInformation->node, p_List);
+ XX_RestoreAllIntr(intFlags);
+ }
+ else
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
+}
+
+
+static t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info)
+{
+ t_CcNodeInformation *p_CcInformation;
+ t_List *p_Pos;
+ uint32_t intFlags;
+
+ intFlags = XX_DisableAllIntr();
+ for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos))
+ {
+ p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcInformation->h_CcNode);
+ if(p_CcInformation->h_CcNode == h_Info)
+ {
+ XX_RestoreAllIntr(intFlags);
+ return p_CcInformation;
+ }
+ }
+ XX_RestoreAllIntr(intFlags);
+ return NULL;
+}
+
+static void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info)
+{
+ t_CcNodeInformation *p_CcInformation = NULL;
+ uint32_t intFlags;
+ t_List *p_Pos;
+
+ intFlags = XX_DisableAllIntr();
+ if (LIST_IsEmpty(p_List))
+ {
+ XX_RestoreAllIntr(intFlags);
+ return;
+ }
+
+ for (p_Pos = NCSW_LIST_FIRST(p_List); p_Pos != (p_List); p_Pos = NCSW_LIST_NEXT(p_Pos))
+ {
+ p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcInformation->h_CcNode);
+ if (p_CcInformation->h_CcNode == h_Info)
+ break;
+ }
+ if (p_CcInformation)
+ LIST_DelAndInit(&p_CcInformation->node);
+ XX_RestoreAllIntr(intFlags);
+}
+
+static t_Error FmPcdCcSetRequiredAction(t_Handle h_FmPcd, uint32_t requiredAction, t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParamsTmp,
+ t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
+{
+
+ t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
+ uint32_t tmpReg32;
+ t_Error err;
+ t_FmPcdCcNode *p_FmPcdCcNode;
+ int i = 0;
+ uint16_t tmp = 0;
+ uint16_t profileId;
+ uint8_t relativeSchemeId, physicalSchemeId;
+ t_CcNodeInformation ccNodeInfo;
+
+ for(i = 0; i < numOfEntries; i++)
+ {
+ if(i == 0)
+ h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ else
+ h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ if(p_CcNextEngineParamsTmp[i].shadowAction & requiredAction)
+ continue;
+ switch(p_CcNextEngineParamsTmp[i].nextEngineParams.nextEngine)
+ {
+ case(e_FM_PCD_CC):
+ if(requiredAction)
+ {
+ p_FmPcdCcNode = p_CcNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
+ ASSERT_COND(p_FmPcdCcNode);
+ if(p_FmPcdCcNode->shadowAction == requiredAction)
+ break;
+ if((requiredAction & UPDATE_CC_WITH_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE))
+ {
+
+ ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 0);
+ if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE)
+ p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_DELETE_TREE;
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = h_Tree;
+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNode->ccTreesLst, &ccNodeInfo);
+ p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_TREE;
+ }
+ if((requiredAction & UPDATE_CC_WITH_DELETE_TREE) && !(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_DELETE_TREE))
+ {
+ ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) == 1);
+ if(p_FmPcdCcNode->shadowAction & UPDATE_CC_WITH_TREE)
+ p_FmPcdCcNode->shadowAction &= ~UPDATE_CC_WITH_TREE;
+ DequeueNodeInfoFromRelevantLst(&p_FmPcdCcNode->ccTreesLst, h_Tree);
+ p_CcNextEngineParamsTmp[i].shadowAction |= UPDATE_CC_WITH_DELETE_TREE;
+ }
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID)
+ tmp = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
+ else
+ tmp = p_FmPcdCcNode->numOfKeys;
+ err = FmPcdCcSetRequiredAction(h_FmPcd, requiredAction, p_FmPcdCcNode->nextEngineAndRequiredAction, p_FmPcdCcNode->h_AdTable, tmp, h_Tree);
+ if(err != E_OK)
+ return err;
+ p_FmPcdCcNode->shadowAction |= requiredAction;
+ }
+ break;
+
+ case(e_FM_PCD_KG):
+ if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
+ {
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme)-1);
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, physicalSchemeId);
+ if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+ if (!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
+ if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this action scheme has to be direct."));
+ err = FmPcdKgCcGetSetParams(h_FmPcd, p_CcNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme, requiredAction);
+ if(err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
+ }
+ break;
+
+ case(e_FM_PCD_PLCR):
+ if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
+ {
+ if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes"));
+ if(!p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this intialization only overrideFqid can be intiizliaes"));
+ err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd, e_FM_PCD_PLCR_SHARED, NULL, p_CcNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId, &profileId);
+ if(err!= E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId, requiredAction);
+ if(err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
+ }
+ break;
+
+ case(e_FM_PCD_DONE):
+ if((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && !(p_CcNextEngineParamsTmp[i].shadowAction & UPDATE_NIA_ENQ_WITHOUT_DMA))
+ {
+ tmpReg32 = GET_UINT32(p_AdTmp->nia);
+ if((tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine was previosely assigned not as PCD_DONE"));
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+ WRITE_UINT32(p_AdTmp->nia, tmpReg32);
+ p_CcNextEngineParamsTmp[i].shadowAction |= requiredAction;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return E_OK;
+}
+
+static t_Error CcUpdateParam(t_Handle h_FmPcd,
+ t_Handle h_FmPort,
+ t_FmPcdCcNextEngineAndRequiredActionParams *p_CcNextEngineParams,
+ uint16_t numOfEntries,
+ t_Handle h_Ad,
+ bool validate,
+ uint16_t level,
+ t_Handle h_FmTree,
+ bool modify)
+{
+ t_CcNodeInformation *p_CcNodeInfo;
+ t_FmPcdCcNode *p_FmPcdCcNode;
+ t_Error err;
+ uint16_t tmp = 0;
+ int i = 0;
+
+ level++;
+
+ if(numOfEntries)
+ {
+ for(i = 0; i < numOfEntries; i++)
+ {
+ if(i == 0)
+ h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ else
+ h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ if(p_CcNextEngineParams[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNode = p_CcNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
+ ASSERT_COND(p_FmPcdCcNode);
+ p_CcNodeInfo = FindNodeInfoInReleventLst(&p_FmPcdCcNode->ccTreesLst,h_FmTree);
+ ASSERT_COND(p_CcNodeInfo);
+ p_CcNodeInfo->index = level;
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNextEngineParams[i].nextEngineParams.h_Manip)
+ {
+ err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, p_CcNodeInfo->index, h_FmTree, modify);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams.nextEngine != e_FM_PCD_INVALID)
+ tmp = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
+ else
+ tmp = p_FmPcdCcNode->numOfKeys;
+
+ err = CcUpdateParam(h_FmPcd, h_FmPort, p_FmPcdCcNode->nextEngineAndRequiredAction, tmp, p_FmPcdCcNode->h_AdTable, validate,level, h_FmTree, modify);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+#ifdef FM_PCD_CC_MANIP
+ else
+ {
+ if(p_CcNextEngineParams[i].nextEngineParams.h_Manip)
+ {
+ err = FmPcdManipUpdate(h_FmPcd, h_FmPort, p_CcNextEngineParams[i].nextEngineParams.h_Manip, h_Ad, validate, level,h_FmTree, modify);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+#endif /* FM_PCD_CC_MANIP */
+ }
+ }
+
+ return E_OK;
+}
+static bool IsNodeInModifiedState(t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_CcNode);
+
+ return p_CcNode->modifiedState;
+}
+
+static void UpdateNodeWithModifiedState(t_Handle h_CcNode, bool modifiedState)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+
+ ASSERT_COND(p_FmPcdCcNode);
+
+ p_FmPcdCcNode->modifiedState = modifiedState;
+}
+
+static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
+{
+ switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
+ {
+ case(e_FM_PCD_ACTION_EXACT_MATCH):
+ switch(p_CcNodeParam->extractCcParams.extractNonHdr.src)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_KEY):
+ return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
+ case(e_FM_PCD_EXTRACT_FROM_HASH):
+ return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
+ default:
+ return CC_PRIVATE_INFO_NONE;
+ }
+ case(e_FM_PCD_ACTION_INDEXED_LOOKUP):
+ switch(p_CcNodeParam->extractCcParams.extractNonHdr.src)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_HASH):
+ return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
+ case(e_FM_PCD_EXTRACT_FROM_FLOW_ID):
+ return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
+ default:
+ return CC_PRIVATE_INFO_NONE;
+ }
+ default:
+ break;
+ }
+ return CC_PRIVATE_INFO_NONE;
+}
+
+static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(t_List *p_List)
+{
+ t_CcNodeInformation *p_CcNodeInfo = NULL;
+ uint32_t intFlags;
+
+ intFlags = XX_DisableAllIntr();
+ if (!LIST_IsEmpty(p_List))
+ {
+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
+ LIST_DelAndInit(&p_CcNodeInfo->node);
+ }
+ XX_RestoreAllIntr(intFlags);
+ return p_CcNodeInfo;
+}
+
+static void ReleaseLst(t_List *p_List)
+{
+ t_CcNodeInformation *p_CcNodeInfo = NULL;
+
+ if(!LIST_IsEmpty(p_List))
+ {
+ p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
+ while (p_CcNodeInfo)
+ {
+ XX_Free(p_CcNodeInfo);
+ p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
+ }
+ }
+ LIST_DelAndInit(p_List);
+}
+
+void FmPcdCcTreeReleaseLock(t_Handle h_FmPcdCcTree)
+{
+ RELEASE_LOCK(((t_FmPcdCcTree *)h_FmPcdCcTree)->lock);
+}
+
+void FmPcdCcNodeTreeReleaseLock(t_List *p_List)
+{
+ t_List *p_Pos;
+ t_CcNodeInformation *p_CcNodeInfo;
+ t_Handle h_FmPcdCcTree;
+
+ LIST_FOR_EACH(p_Pos, p_List)
+ {
+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
+ h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
+ FmPcdCcTreeReleaseLock(h_FmPcdCcTree);
+ }
+ ReleaseLst(p_List);
+}
+
+static void DeleteNode(t_FmPcdCcNode *p_FmPcdCcNode)
+{
+ if(p_FmPcdCcNode)
+ {
+ if(p_FmPcdCcNode->p_GlblMask)
+ {
+ XX_Free(p_FmPcdCcNode->p_GlblMask);
+ p_FmPcdCcNode->p_GlblMask = NULL;
+ }
+ if(p_FmPcdCcNode->h_KeysMatchTable)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_KeysMatchTable);
+ p_FmPcdCcNode->h_KeysMatchTable = NULL;
+ }
+ if(p_FmPcdCcNode->h_AdTable)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_FmPcdCcNode->h_AdTable);
+ p_FmPcdCcNode->h_AdTable = NULL;
+ }
+
+ ReleaseLst(&p_FmPcdCcNode->ccPrevNodesLst);
+ ReleaseLst(&p_FmPcdCcNode->ccTreeIdLst);
+ ReleaseLst(&p_FmPcdCcNode->ccTreesLst);
+
+ XX_Free(p_FmPcdCcNode);
+ }
+}
+
+static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
+{
+ if(p_FmPcdTree)
+ {
+ if(p_FmPcdTree->ccTreeBaseAddr)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
+ p_FmPcdTree->ccTreeBaseAddr = 0;
+ }
+
+ ReleaseLst(&p_FmPcdTree->fmPortsLst);
+
+ XX_Free(p_FmPcdTree);
+ }
+}
+
+static void UpdateNodeOwner(t_FmPcdCcNode *p_FmPcdCcNode, bool add)
+{
+ ASSERT_COND(p_FmPcdCcNode);
+
+ if(add)
+ p_FmPcdCcNode->owners++;
+ else
+ {
+ ASSERT_COND(p_FmPcdCcNode->owners);
+ p_FmPcdCcNode->owners--;
+ }
+}
+
+static void GetCcExtractKeySize(uint8_t parseCodeRealSize, uint8_t *parseCodeCcSize)
+{
+ if((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
+ *parseCodeCcSize = 1;
+ else if(parseCodeRealSize == 2)
+ *parseCodeCcSize = 2;
+ else if((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
+ *parseCodeCcSize = 4;
+ else if((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
+ *parseCodeCcSize = 8;
+ else if((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
+ *parseCodeCcSize = 16;
+ else if((parseCodeRealSize > 16) && (parseCodeRealSize <= 24))
+ *parseCodeCcSize = 24;
+ else if((parseCodeRealSize > 24) && (parseCodeRealSize <= 32))
+ *parseCodeCcSize = 32;
+ else if((parseCodeRealSize > 32) && (parseCodeRealSize <= 40))
+ *parseCodeCcSize = 40;
+ else if((parseCodeRealSize > 40) && (parseCodeRealSize <= 48))
+ *parseCodeCcSize = 48;
+ else if((parseCodeRealSize > 48) && (parseCodeRealSize <= 56))
+ *parseCodeCcSize = 56;
+ else
+ *parseCodeCcSize = 0;
+}
+
+static void GetSizeHeaderField(e_NetHeaderType hdr,t_FmPcdFields field,uint8_t *parseCodeRealSize)
+{
+ switch(hdr)
+ {
+ case (HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_DA):
+ *parseCodeRealSize = 6;
+ break;
+ case(NET_HEADER_FIELD_ETH_SA):
+ *parseCodeRealSize = 6;
+ break;
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case(HEADER_TYPE_PPPoE):
+ switch(field.pppoe)
+ {
+ case(NET_HEADER_FIELD_PPPoE_PID):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_MPLS):
+ switch(field.mpls)
+ {
+ case(NET_HEADER_FIELD_MPLS_LABEL_STACK):
+ *parseCodeRealSize = 4;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_IPv4):
+ switch(field.ipv4)
+ {
+ case(NET_HEADER_FIELD_IPv4_DST_IP):
+ case(NET_HEADER_FIELD_IPv4_SRC_IP):
+ *parseCodeRealSize = 4;
+ break;
+ case(NET_HEADER_FIELD_IPv4_TOS):
+ case(NET_HEADER_FIELD_IPv4_PROTO):
+ *parseCodeRealSize = 1;
+ break;
+ case(NET_HEADER_FIELD_IPv4_DST_IP | NET_HEADER_FIELD_IPv4_SRC_IP):
+ *parseCodeRealSize = 8;
+ break;
+ case(NET_HEADER_FIELD_IPv4_TTL):
+ *parseCodeRealSize = 1;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_IPv6):
+ switch(field.ipv6)
+ {
+ case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
+ *parseCodeRealSize = 4;
+ break;
+ case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
+ case(NET_HEADER_FIELD_IPv6_HOP_LIMIT):
+ *parseCodeRealSize = 1;
+ break;
+ case(NET_HEADER_FIELD_IPv6_DST_IP):
+ case(NET_HEADER_FIELD_IPv6_SRC_IP):
+ *parseCodeRealSize = 16;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_GRE):
+ switch(field.gre)
+ {
+ case(NET_HEADER_FIELD_GRE_TYPE):
+ *parseCodeRealSize = 2;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_MINENCAP):
+ switch(field.minencap)
+ {
+ case(NET_HEADER_FIELD_MINENCAP_TYPE):
+ *parseCodeRealSize = 1;
+ break;
+ case(NET_HEADER_FIELD_MINENCAP_DST_IP):
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP):
+ *parseCodeRealSize = 4;
+ break;
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP):
+ *parseCodeRealSize = 8;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_TCP):
+ switch(field.tcp)
+ {
+ case(NET_HEADER_FIELD_TCP_PORT_SRC):
+ case(NET_HEADER_FIELD_TCP_PORT_DST):
+ *parseCodeRealSize = 2;
+ break;
+ case(NET_HEADER_FIELD_TCP_PORT_SRC | NET_HEADER_FIELD_TCP_PORT_DST):
+ *parseCodeRealSize = 4;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ case (HEADER_TYPE_UDP):
+ switch(field.udp)
+ {
+ case(NET_HEADER_FIELD_UDP_PORT_SRC):
+ case(NET_HEADER_FIELD_UDP_PORT_DST):
+ *parseCodeRealSize = 2;
+ break;
+ case(NET_HEADER_FIELD_UDP_PORT_SRC | NET_HEADER_FIELD_UDP_PORT_DST):
+ *parseCodeRealSize = 4;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
+ *parseCodeRealSize = CC_SIZE_ILLEGAL;
+ break;
+ }
+}
+
+static t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ uint16_t absoluteProfileId;
+ t_Error err = E_OK;
+ uint8_t relativeSchemeId;
+
+ switch(p_FmPcdCcNextEngineParams->nextEngine)
+ {
+ case(e_FM_PCD_INVALID):
+ err = E_NOT_SUPPORTED;
+ break;
+ case(e_FM_PCD_DONE):
+ if(p_FmPcdCcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME)
+ {
+ if(p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid &&
+ !p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not defined fqid for control flow for BMI next engine "));
+ if(p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid & ~0x00FFFFFF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidForCtrlFlow must be between 1 and 2^24-1"));
+ }
+ break;
+ case(e_FM_PCD_KG):
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(h_FmPcd, (uint8_t)(PTR_TO_UINT(p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)-1));
+ if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ if(!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("not valid schemeIndex in KG next engine param"));
+ if(!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("CC Node may point only to a scheme that is always direct."));
+ break;
+ case(e_FM_PCD_PLCR):
+ if(p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
+ {
+ /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */
+ if(p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
+ {
+ err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId, &absoluteProfileId);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("Shared profile offset is out of range"));
+ if(!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile"));
+ }
+ else
+ {
+ }
+ /* TODO - add check according to the revision of the chip.
+ if(!p_FmPcdCcNextEngineParams->params.plcrParams.newFqid ||
+ (p_FmPcdCcNextEngineParams->params.plcrParams.newFqid & ~0x00FFFFFF))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("newFqid must be between 1 and 2^24-1"));
+ */
+ }
+ break;
+ case(e_FM_PCD_CC):
+ if(!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
+ RETURN_ERROR(MAJOR, E_NULL_POINTER, ("handler to next Node is NULL"));
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine is not correct"));
+ }
+ return err;
+}
+
+static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset, bool fromIc, ccPrivateInfo_t icCode)
+{
+ if(!fromIc)
+ {
+ switch(src)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_FRAME_START):
+ if(glblMask)
+ return CC_PC_GENERIC_WITH_MASK ;
+ else
+ return CC_PC_GENERIC_WITHOUT_MASK;
+ case(e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
+ *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
+ if(offset)
+ return CC_PR_OFFSET;
+ else
+ return CC_PR_WITHOUT_OFFSET;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
+ return CC_PC_ILLEGAL;
+ }
+ }
+ else
+ {
+ switch (icCode)
+ {
+ case(CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
+ *parseArrayOffset = 0x50;
+ return CC_PC_GENERIC_IC_GMASK;
+ case(CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
+ *parseArrayOffset = 0x48;
+ return CC_PC_GENERIC_IC_GMASK;
+ case(CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
+ *parseArrayOffset = 0x48;
+ return CC_PC_GENERIC_IC_HASH_INDEXED;
+ case(CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
+ *parseArrayOffset = 0x16;
+ return CC_PC_GENERIC_IC_HASH_INDEXED;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
+ break;
+ }
+ }
+ return CC_PC_ILLEGAL;
+}
+
+static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
+{
+
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ return CC_PC_ILLEGAL;
+
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_DA):
+ return CC_PC_FF_MACDST;
+ case(NET_HEADER_FIELD_ETH_SA):
+ return CC_PC_FF_MACSRC;
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ return CC_PC_FF_ETYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_TCI1;
+ if(index == e_FM_PCD_HDR_INDEX_LAST)
+ return CC_PC_FF_TCI2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_MPLS):
+ switch(field.mpls)
+ {
+ case(NET_HEADER_FIELD_MPLS_LABEL_STACK):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_MPLS1;
+ if(index == e_FM_PCD_HDR_INDEX_LAST)
+ return CC_PC_FF_MPLS_LAST;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
+ return CC_PC_ILLEGAL;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_IPv4):
+ switch(field.ipv4)
+ {
+ case(NET_HEADER_FIELD_IPv4_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4DST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4DST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_TOS):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4IPTOS_TC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4IPTOS_TC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_PROTO):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4PTYPE1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4PTYPE2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_SRC_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4SRC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4SRC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_SRC_IP | NET_HEADER_FIELD_IPv4_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV4SRC1_IPV4DST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV4SRC2_IPV4DST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv4_TTL):
+ return CC_PC_FF_IPV4TTL;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_IPv6):
+ switch(field.ipv6)
+ {
+ case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV6PTYPE1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV6PTYPE2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV6DST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV6DST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_SRC_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return CC_PC_FF_IPV6SRC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return CC_PC_FF_IPV6SRC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return CC_PC_ILLEGAL;
+ case(NET_HEADER_FIELD_IPv6_HOP_LIMIT):
+ return CC_PC_FF_IPV6HOP_LIMIT;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_GRE):
+ switch(field.gre)
+ {
+ case(NET_HEADER_FIELD_GRE_TYPE):
+ return CC_PC_FF_GREPTYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+ case(HEADER_TYPE_MINENCAP):
+ switch(field.minencap)
+ {
+ case(NET_HEADER_FIELD_MINENCAP_TYPE):
+ return CC_PC_FF_MINENCAP_PTYPE;
+ case(NET_HEADER_FIELD_MINENCAP_DST_IP):
+ return CC_PC_FF_MINENCAP_IPDST;
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP):
+ return CC_PC_FF_MINENCAP_IPSRC;
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP | NET_HEADER_FIELD_MINENCAP_DST_IP):
+ return CC_PC_FF_MINENCAP_IPSRC_IPDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_TCP):
+ switch(field.tcp)
+ {
+ case(NET_HEADER_FIELD_TCP_PORT_SRC):
+ return CC_PC_FF_L4PSRC;
+ case(NET_HEADER_FIELD_TCP_PORT_DST):
+ return CC_PC_FF_L4PDST;
+ case(NET_HEADER_FIELD_TCP_PORT_DST | NET_HEADER_FIELD_TCP_PORT_SRC):
+ return CC_PC_FF_L4PSRC_L4PDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_PPPoE):
+ switch(field.pppoe)
+ {
+ case(NET_HEADER_FIELD_PPPoE_PID):
+ return CC_PC_FF_PPPPID;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ case(HEADER_TYPE_UDP):
+ switch(field.udp)
+ {
+ case(NET_HEADER_FIELD_UDP_PORT_SRC):
+ return CC_PC_FF_L4PSRC;
+ case(NET_HEADER_FIELD_UDP_PORT_DST):
+ return CC_PC_FF_L4PDST;
+ case(NET_HEADER_FIELD_UDP_PORT_DST | NET_HEADER_FIELD_UDP_PORT_SRC):
+ return CC_PC_FF_L4PSRC_L4PDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+}
+
+static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, uint32_t offset, bool glblMask, uint8_t *parseArrayOffset)
+{
+ bool offsetRelevant = FALSE;
+
+ if(offset)
+ offsetRelevant = TRUE;
+
+ switch(hdr){
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ return CC_PC_ILLEGAL;
+ case(HEADER_TYPE_ETH):
+ *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
+ break;
+ case(HEADER_TYPE_USER_DEFINED_SHIM1):
+ if(offset || glblMask)
+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
+ else
+ return CC_PC_PR_SHIM1;
+ break;
+ case(HEADER_TYPE_USER_DEFINED_SHIM2):
+ if(offset || glblMask)
+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
+ else
+ return CC_PC_PR_SHIM2;
+ break;
+ case(HEADER_TYPE_LLC_SNAP):
+ *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
+ break;
+ case(HEADER_TYPE_PPPoE):
+ *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
+ break;
+ case(HEADER_TYPE_MPLS):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
+ else
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
+ return CC_PC_ILLEGAL;
+ }
+ break;
+ case(HEADER_TYPE_IPv4):
+ case(HEADER_TYPE_IPv6):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
+ *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
+ else
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
+ return CC_PC_ILLEGAL;
+
+ }
+ break;
+ case(HEADER_TYPE_MINENCAP):
+ *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
+ break;
+ case(HEADER_TYPE_GRE):
+ *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
+ break;
+ case(HEADER_TYPE_TCP):
+ case(HEADER_TYPE_UDP):
+ case(HEADER_TYPE_IPSEC_AH):
+ case(HEADER_TYPE_IPSEC_ESP):
+ case(HEADER_TYPE_DCCP):
+ case(HEADER_TYPE_SCTP):
+ *parseArrayOffset = CC_PC_PR_L4_OFFSET;
+ break;
+
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
+ return CC_PC_ILLEGAL;
+ }
+
+ if(offsetRelevant)
+ return CC_PR_OFFSET;
+ else
+ return CC_PR_WITHOUT_OFFSET;
+}
+
+static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field, uint32_t offset, uint8_t *parseArrayOffset, e_FmPcdHdrIndex hdrIndex)
+{
+ bool offsetRelevant = FALSE;
+
+ if(offset)
+ offsetRelevant = TRUE;
+
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+ break;
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return CC_PC_ILLEGAL;
+ }
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
+ return CC_PC_ILLEGAL;
+ }
+ if(offsetRelevant)
+ return CC_PR_OFFSET;
+ else
+ return CC_PR_WITHOUT_OFFSET;
+}
+
+static void FillAdOfTypeResult(t_Handle p_Ad, t_FmPcd *p_FmPcd, t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
+{
+ t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
+ uint32_t tmp = 0, tmpNia = 0;
+ uint16_t profileId;
+ t_Handle p_AdNewPtr = NULL;
+
+ p_AdNewPtr = p_AdResult;
+
+#ifdef FM_PCD_CC_MANIP
+ if (p_CcNextEngineParams->h_Manip)
+ FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip, p_Ad, &p_AdNewPtr);
+#endif /* FM_PCD_CC_MANIP */
+
+ if(p_AdNewPtr)
+ {
+ switch(p_CcNextEngineParams->nextEngine)
+ {
+ case(e_FM_PCD_DONE):
+ if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_ENQ_FRAME)
+ {
+ if(p_CcNextEngineParams->params.enqueueParams.overrideFqid)
+ {
+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
+ tmp |= p_CcNextEngineParams->params.enqueueParams.newFqid;
+ }
+ else
+ {
+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
+ tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
+ }
+ }
+ if(p_CcNextEngineParams->params.enqueueParams.action == e_FM_PCD_DROP_FRAME)
+ tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_DISCARD);
+ else
+ tmpNia |= (NIA_ENG_BMI |NIA_BMI_AC_ENQ_FRAME);
+ if(p_CcNextEngineParams->params.enqueueParams.statisticsEn)
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN;
+ break;
+ case(e_FM_PCD_KG):
+ if(p_CcNextEngineParams->params.kgParams.overrideFqid)
+ {
+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
+ tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
+ }
+ else
+ {
+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
+ tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
+ }
+ tmpNia = NIA_KG_DIRECT;
+ tmpNia |= NIA_ENG_KG;
+ tmpNia |= (uint8_t)(PTR_TO_UINT(p_CcNextEngineParams->params.kgParams.h_DirectScheme)-1);
+ if(p_CcNextEngineParams->params.kgParams.statisticsEn)
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN;
+ break;
+ case(e_FM_PCD_PLCR):
+ tmp = 0;
+ if(p_CcNextEngineParams->params.plcrParams.overrideParams)
+ {
+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
+
+ /* if private policer profile, it may be uninitialized yet, therefor no checks are done at this stage */
+ if(p_CcNextEngineParams->params.plcrParams.sharedProfile)
+ {
+ tmpNia |= NIA_PLCR_ABSOLUTE;
+ FmPcdPlcrGetAbsoluteProfileId((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL,p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, &profileId);
+ }
+ else
+ profileId = p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
+
+ tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
+ WRITE_UINT32(p_AdResult->plcrProfile,(uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
+ }
+ else
+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
+ tmpNia |= NIA_ENG_PLCR | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
+ if(p_CcNextEngineParams->params.kgParams.statisticsEn)
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE | FM_PCD_AD_RESULT_STATISTICS_EN;
+ break;
+ default:
+ return;
+ }
+ WRITE_UINT32(p_AdResult->fqid, tmp);
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNextEngineParams->h_Manip)
+ {
+ tmp = GET_UINT32(p_AdResult->plcrProfile);
+ tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr) - (p_FmPcd->physicalMuramBase)) >> 4;
+ WRITE_UINT32(p_AdResult->plcrProfile, tmp);
+
+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
+ tmpNia |= FM_PCD_AD_RESULT_NADEN;
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ WRITE_UINT32(p_AdResult->nia, tmpNia);
+ }
+}
+
+static void FillAdOfTypeContLookup(t_Handle p_Ad, t_Handle h_FmPcd, t_Handle p_FmPcdCcNode, t_Handle h_Manip)
+{
+ t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_FmPcdCcNode;
+ t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)p_Ad;
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t tmpReg32;
+ t_Handle p_AdNewPtr = NULL;
+
+ p_AdNewPtr = p_AdContLookup;
+
+#ifdef FM_PCD_CC_MANIP
+ if (h_Manip)
+ FmPcdManipUpdateAdContLookupForCc(h_Manip, p_Ad, &p_AdNewPtr, (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase)));
+#else
+ UNUSED(h_Manip);
+#endif /* FM_PCD_CC_MANIP */
+
+ if(p_AdNewPtr)
+ {
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ tmpReg32 |= p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) : 0;
+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase);
+ WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= p_Node->numOfKeys << 24;
+ tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
+ tmpReg32 |= p_Node->h_KeysMatchTable ?
+ (uint32_t)(XX_VirtToPhys(p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) : 0;
+ WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= p_Node->prsArrayOffset << 24;
+ tmpReg32 |= p_Node->offset << 16;
+ tmpReg32 |= p_Node->parseCode;
+ WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
+
+ Mem2IOCpy32((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, CC_GLBL_MASK_SIZE);
+ }
+}
+
+static void NextStepAd(t_Handle p_Ad, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_FmPcd *p_FmPcd)
+{
+ switch(p_FmPcdCcNextEngineParams->nextEngine)
+ {
+ case(e_FM_PCD_KG):
+ case(e_FM_PCD_PLCR):
+ case(e_FM_PCD_DONE):
+ FillAdOfTypeResult(p_Ad, p_FmPcd, p_FmPcdCcNextEngineParams);
+ break;
+ case(e_FM_PCD_CC):
+ FillAdOfTypeContLookup(p_Ad,
+ p_FmPcd,
+ p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
+#ifdef FM_PCD_CC_MANIP
+ p_FmPcdCcNextEngineParams->h_Manip
+#else
+ NULL
+#endif /* FM_PCD_CC_MANIP */
+ );
+ UpdateNodeOwner (p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
+ TRUE);
+ break;
+ default:
+ return;
+ }
+}
+
+
+static void ReleaseNewNodeCommonPart(t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+ if(p_AdditionalInfo->p_AdTableNew)
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_AdTableNew);
+ if(p_AdditionalInfo->p_KeysMatchTableNew)
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), p_AdditionalInfo->p_KeysMatchTableNew);
+}
+
+static t_Error UpdateGblMask(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keySize, uint8_t *p_Mask)
+{
+ if (p_Mask &&
+ !p_FmPcdCcNode->glblMaskUpdated &&
+ (keySize <= 4) &&
+ !p_FmPcdCcNode->lclMask )
+ {
+ memcpy(p_FmPcdCcNode->p_GlblMask, p_Mask, (sizeof(uint8_t))*keySize);
+ p_FmPcdCcNode->glblMaskUpdated = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 4;
+ }
+ else if (p_Mask &&
+ (keySize <= 4) &&
+ !p_FmPcdCcNode->lclMask)
+ {
+ if (memcmp(p_FmPcdCcNode->p_GlblMask, p_Mask, keySize) != 0)
+ {
+ p_FmPcdCcNode->lclMask = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 0;
+ }
+ }
+ else if (!p_Mask && (p_FmPcdCcNode->glblMaskUpdated) && (keySize <= 4))
+ {
+ uint32_t tmpMask = 0xffffffff;
+ if (memcmp(p_FmPcdCcNode->p_GlblMask, &tmpMask, 4) != 0)
+ {
+ p_FmPcdCcNode->lclMask = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 0;
+ }
+ }
+ else if (p_Mask)
+ {
+ p_FmPcdCcNode->lclMask = TRUE;
+ p_FmPcdCcNode->glblMaskSize = 0;
+ }
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeCommonPart(t_FmPcdCcNode *p_FmPcdCcNode,
+ int *size,
+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+
+ p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)( (p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE),
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_AdditionalInfo->p_AdTableNew)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table "));
+
+ IOMemSet32((uint8_t*)p_AdditionalInfo->p_AdTableNew, 0, (uint32_t)((p_AdditionalInfo->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE));
+
+ if(p_FmPcdCcNode->lclMask)
+ *size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction;
+ else
+ *size = p_FmPcdCcNode->ccKeySizeAccExtraction;
+
+ p_AdditionalInfo->p_KeysMatchTableNew =
+ (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)(*size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)),
+ FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
+ if(!p_AdditionalInfo->p_KeysMatchTableNew)
+ {
+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd), p_AdditionalInfo->p_AdTableNew);
+ p_AdditionalInfo->p_AdTableNew = NULL;
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table"));
+ }
+ IOMemSet32((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
+
+ p_AdditionalInfo->p_AdTableOld = p_FmPcdCcNode->h_AdTable;
+ p_AdditionalInfo->p_KeysMatchTableOld = p_FmPcdCcNode->h_KeysMatchTable;
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(t_Handle h_FmPcd ,t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdCcKeyParams *p_KeyParams,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
+{
+ t_Error err = E_OK;
+ t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
+ int size;
+ int i = 0, j = 0;
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t requiredAction = 0;
+ bool prvLclMask;
+ t_CcNodeInformation *p_CcNodeInformation;
+ t_List *p_Pos;
+
+ /*check that new NIA is legal*/
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ prvLclMask = p_FmPcdCcNode->lclMask;
+
+ /*check that new key is not require update of localMask*/
+ err = UpdateGblMask(p_FmPcdCcNode,
+ p_FmPcdCcNode->ccKeySizeAccExtraction,
+ p_KeyParams->p_Mask);
+ if (err != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*update internal data structure for next engine per index (index - key)*/
+ memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+
+ /*update numOfKeys*/
+ if(add)
+ p_AdditionalInfo->numOfKeys = (uint8_t)(p_FmPcdCcNode->numOfKeys + 1);
+ else
+ p_AdditionalInfo->numOfKeys = (uint8_t)p_FmPcdCcNode->numOfKeys;
+ /*function which build in the memory new KeyTbl, AdTbl*/
+ err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+#ifdef FM_PCD_CC_MANIP
+ /*check that manip is legal and what requiredAction is necessary for this manip*/
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams,&requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction;
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE;
+
+
+ /*update new Ad and new Key Table according to new requirement*/
+ i = 0;
+ for(j = 0; j < p_AdditionalInfo->numOfKeys; j++)
+ {
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ if(j == keyIndex)
+ {
+ NextStepAd(p_AdTableNewTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd);
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ Mem2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key, p_FmPcdCcNode->userSizeOfExtraction);
+ if(p_FmPcdCcNode->lclMask)
+ {
+ if(p_KeyParams->p_Mask)
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->userSizeOfExtraction);
+ else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ if(!add)
+ i++;
+ }
+ else
+ {
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i*size * sizeof(uint8_t));
+
+ if(p_FmPcdCcNode->lclMask)
+ {
+ if(prvLclMask)
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ p_FmPcdCcNode->ccKeySizeAccExtraction);
+ else
+ {
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction*sizeof(uint8_t));
+
+ if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ }
+ IO2IOCpy32(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction);
+ i++;
+ }
+ }
+
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+
+ if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst))
+ {
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ /*update the manipulation which has to be updated from parameters of the port*/
+ /*it's has to be updated with restrictions defined in the function*/
+ err = FmPcdCcSetRequiredAction(p_FmPcdCcNode->h_FmPcd,
+ p_FmPcdCcNode->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction,
+ &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ 1,
+ p_CcNodeInformation->h_CcNode);
+ if (err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ err = CcUpdateParam(p_FmPcdCcNode->h_FmPcd,
+ NULL,
+ &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ 1,
+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ TRUE,
+ p_CcNodeInformation->index,
+ p_CcNodeInformation->h_CcNode,
+ TRUE);
+ if (err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+ }
+
+ if(p_FmPcdCcNode->lclMask)
+ memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+
+
+ if(p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForAdd = p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
+
+ if(!add)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+ }
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeRemoveKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+ int i = 0, j = 0;
+ t_Handle p_AdTableNewTmp,p_KeysMatchTableNewTmp;
+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
+ int size;
+ t_Error err = E_OK;
+
+ /*save new numOfKeys*/
+ p_AdditionalInfo->numOfKeys = (uint16_t)(p_FmPcdCcNode->numOfKeys - 1);
+
+ /*function which allocates in the memory new KeyTbl, AdTbl*/
+ err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*update new Ad and new Key Table according to new requirement*/
+ for(i = 0, j = 0; j < p_FmPcdCcNode->numOfKeys; i++, j++)
+ {
+ if(j == keyIndex)
+ {
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ j++;
+ }
+ if(j == p_FmPcdCcNode->numOfKeys)
+ break;
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp,p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j*size * sizeof(uint8_t));
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i*size * sizeof(uint8_t));
+ IO2IOCpy32(p_KeysMatchTableNewTmp,p_KeysMatchTableOldTmp, size * sizeof(uint8_t));
+ }
+
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeModifyKey(t_FmPcdCcNode *p_FmPcdCcNode, uint8_t keyIndex, uint8_t *p_Key, uint8_t *p_Mask,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+ t_Error err = E_OK;
+ t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
+ int size;
+ int i = 0, j = 0;
+ bool prvLclMask;
+
+ p_AdditionalInfo->numOfKeys = p_FmPcdCcNode->numOfKeys;
+
+ prvLclMask = p_FmPcdCcNode->lclMask;
+
+ /*check that new key is not require update of localMask*/
+ err = UpdateGblMask(p_FmPcdCcNode,
+ p_FmPcdCcNode->sizeOfExtraction,
+ p_Mask);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*function which build in the memory new KeyTbl, AdTbl*/
+ err = BuildNewNodeCommonPart(p_FmPcdCcNode, &size, p_AdditionalInfo);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*fill the New AdTable and New KeyTable*/
+ for(j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
+ {
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ if(j == keyIndex)
+ {
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ Mem2IOCpy32(p_KeysMatchTableNewTmp, p_Key, p_FmPcdCcNode->userSizeOfExtraction);
+ if(p_FmPcdCcNode->lclMask)
+ {
+ if(p_Mask)
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_Mask, p_FmPcdCcNode->userSizeOfExtraction);
+ else if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ }
+ else
+ {
+ p_KeysMatchTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size * sizeof(uint8_t));
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*size * sizeof(uint8_t));
+ if (p_FmPcdCcNode->lclMask)
+ {
+ if(prvLclMask)
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ PTR_MOVE(p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction),
+ p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ {
+ p_KeysMatchTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_KeysMatchTable, i*p_FmPcdCcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
+
+ if (p_FmPcdCcNode->ccKeySizeAccExtraction > 4)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->userSizeOfExtraction);
+ else
+ IO2IOCpy32(PTR_MOVE(p_KeysMatchTableNewTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_FmPcdCcNode->p_GlblMask, p_FmPcdCcNode->userSizeOfExtraction);
+ }
+ }
+ IO2IOCpy32((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, p_FmPcdCcNode->ccKeySizeAccExtraction);
+ }
+ }
+
+ p_AdTableNewTmp = PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
+ p_AdTableOldTmp = PTR_MOVE(p_FmPcdCcNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ IO2IOCpy32(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ return E_OK;
+}
+
+static t_Error BuildNewNodeModifyNextEngine(t_Handle h_FmPcd ,t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst,t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
+{
+
+ t_Error err = E_OK;
+ uint32_t requiredAction = 0;
+ t_List *p_Pos;
+ t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
+ t_Handle p_Ad;
+ t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
+ t_FmPcdCcTree *p_FmPcdCcTree = NULL;
+
+ ASSERT_COND(p_CcNextEngineParams);
+ /*check that new NIA is legal*/
+ err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /*update internal data structure for next engine per index (index - key)*/
+ memcpy(&p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].nextEngineParams,p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+
+#ifdef FM_PCD_CC_MANIP
+ /*check that manip is legal and what requiredAction is necessary for this manip*/
+ if(p_CcNextEngineParams->h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(p_CcNextEngineParams,&requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ if(!p_AdditionalInfo->tree)
+ {
+ p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
+ p_Ad = p_FmPcdCcNode1->h_AdTable;
+ if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcNode1->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+ }
+ else
+ {
+ p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
+ p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip)
+ p_AdditionalInfo->h_ManipForRmv = p_FmPcdCcTree->nextEngineAndRequiredAction[keyIndex].nextEngineParams.h_Manip;
+#endif /* FM_PCD_CC_MANIP */
+ }
+ ASSERT_COND(p_Ad);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
+
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ p_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+
+ if(!p_Ad)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+ if(p_CcNextEngineParams)
+ NextStepAd(p_Ad,p_CcNextEngineParams, h_FmPcd);
+ ccNodeInfo.h_CcNode = p_Ad;
+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction = requiredAction;
+
+ p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction |= UPDATE_CC_WITH_TREE;
+
+ if(!p_AdditionalInfo->tree)
+ {
+ ASSERT_COND(p_FmPcdCcNode1);
+ if(!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
+ {
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ /*update the manipulation which has to be updated from parameters of the port*/
+ /*it's has to be updated with restrictions defined in the function*/
+ err = FmPcdCcSetRequiredAction(p_FmPcdCcNode1->h_FmPcd, p_FmPcdCcNode1->shadowAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ p_Ad, 1, p_CcNodeInformation->h_CcNode);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ err = CcUpdateParam(p_FmPcdCcNode1->h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, p_CcNodeInformation->index, p_CcNodeInformation->h_CcNode, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+ }
+ }
+ else
+ {
+ ASSERT_COND(p_FmPcdCcTree);
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->requiredAction | p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex].requiredAction, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],
+ p_Ad, 1, (t_Handle)p_FmPcdCcTree);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ err = CcUpdateParam(h_FmPcd, NULL, &p_AdditionalInfo->nextEngineAndRequiredAction[keyIndex],1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+
+ if(p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
+ p_AdditionalInfo->h_NodeForAdd = p_CcNextEngineParams->params.ccParams.h_CcNode;
+ return E_OK;
+}
+
+static t_Handle BuildNewAd(t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
+ t_FmPcdCcNode *p_FmPcdCcNode,
+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+
+ t_Handle p_Ad;
+ t_FmPcdCcNode *p_FmPcdCcNodeTmp;
+
+ p_Ad = (t_Handle)FM_MURAM_AllocMem(((t_FmPcd *)(p_FmPcdCcNode->h_FmPcd))->h_FmMuram,
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_Ad)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM for AD"));
+ return NULL;
+ }
+ IOMemSet32(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
+ if(!p_FmPcdCcNodeTmp)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
+ return NULL;
+ }
+ memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
+
+ p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
+ p_FmPcdCcNodeTmp->h_KeysMatchTable = p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
+ p_FmPcdCcNodeTmp->h_AdTable = p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
+
+ p_FmPcdCcNodeTmp->lclMask = p_FmPcdCcNode->lclMask;
+ p_FmPcdCcNodeTmp->parseCode = p_FmPcdCcNode->parseCode;
+ p_FmPcdCcNodeTmp->offset = p_FmPcdCcNode->offset;
+ p_FmPcdCcNodeTmp->prsArrayOffset = p_FmPcdCcNode->prsArrayOffset;
+ p_FmPcdCcNodeTmp->ctrlFlow = p_FmPcdCcNode->ctrlFlow;
+ p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_FmPcdCcNode->ccKeySizeAccExtraction;
+ p_FmPcdCcNodeTmp->sizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction;
+ p_FmPcdCcNodeTmp->glblMaskSize = p_FmPcdCcNode->glblMaskSize;
+ p_FmPcdCcNodeTmp->p_GlblMask = p_FmPcdCcNode->p_GlblMask;
+
+ if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
+ FillAdOfTypeContLookup(p_Ad,
+ p_FmPcdCcNode->h_FmPcd,
+ p_FmPcdCcNodeTmp,
+#ifdef FM_PCD_CC_MANIP
+ p_FmPcdCcNextEngineParams->h_Manip
+#else
+ NULL
+#endif /* FM_PCD_CC_MANIP */
+ );
+
+ XX_Free(p_FmPcdCcNodeTmp);
+
+ return p_Ad;
+}
+
+static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List *h_OldLst, t_List *h_NewLst)
+{
+ t_CcNodeInformation *p_CcNodeInformation;
+ t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
+ t_List *p_Pos;
+ int i = 0;
+ t_Handle p_AdTablePtOnCrntCurrentMdfNode, p_AdTableNewModified;
+ t_CcNodeInformation ccNodeInfo;
+
+ LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ p_NodePtrOnCurrentMdfNode = (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
+ ASSERT_COND(p_NodePtrOnCurrentMdfNode);
+ /*search in the prev node which exact index points on this current modified node for getting AD */
+ for(i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
+ {
+ if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ if(p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode)
+ {
+ p_AdTablePtOnCrntCurrentMdfNode = PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
+
+ p_AdTableNewModified = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_NodePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTableNewModified;
+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
+ }
+ }
+ }
+ ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
+ }
+}
+
+static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(t_FmPcdCcNode *p_CrntMdfNode ,t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, t_List *h_OldLst, t_List *h_NewLst)
+{
+ t_CcNodeInformation *p_CcNodeInformation;
+ t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
+ t_List *p_Pos;
+ int i = 0;
+ t_Handle p_AdTableTmp, p_AdTableTmp1;
+ t_CcNodeInformation ccNodeInfo;
+
+ LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ p_TreePtrOnCurrentMdfNode = (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
+
+ ASSERT_COND(p_TreePtrOnCurrentMdfNode);
+ /*search in the trees which exact index points on this current modified node for getting AD
+ */
+ for(i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
+ {
+ if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ if(p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode == (t_Handle)p_CrntMdfNode)
+ {
+ p_AdTableTmp = UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTableTmp;
+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo);
+
+ p_AdTableTmp1 = BuildNewAd(p_FmPcdModifyCcKeyAdditionalParams, p_CrntMdfNode, &p_TreePtrOnCurrentMdfNode->nextEngineAndRequiredAction[i].nextEngineParams);
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = p_AdTableTmp1;
+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo);
+ }
+ }
+ }
+ ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
+ }
+}
+
+static t_Error ModifyKeyCommonPart1(t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, t_Handle *h_Params, e_ModifyState modifyState, bool check, bool tree)
+{
+ t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
+ int i = 0, j = 0;
+ bool wasUpdate = FALSE;
+ t_FmPcdCcNode *p_FmPcdCcNode = NULL;
+ t_FmPcdCcTree *p_FmPcdCcTree;
+ uint16_t numOfKeys;
+ t_FmPcdCcNextEngineAndRequiredActionParams *p_nextEngineAndRequiredAction = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNodeOrTree,E_INVALID_HANDLE);
+
+ p_nextEngineAndRequiredAction = XX_Malloc(FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction));
+ if(!p_nextEngineAndRequiredAction)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate memory for p_nextEngineAndRequiredAction"));
+
+ memset(p_nextEngineAndRequiredAction, 0, FM_PCD_MAX_NUM_OF_KEYS * sizeof(*p_nextEngineAndRequiredAction));
+
+ if(!tree)
+ {
+ p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
+ numOfKeys = p_FmPcdCcNode->numOfKeys;
+
+ /*node has to be pointed by another node or tree*/
+ if (!LIST_NumOfObjs(&p_FmPcdCcNode->ccPrevNodesLst) &&
+ !LIST_NumOfObjs(&p_FmPcdCcNode->ccTreeIdLst))
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be pointed by node or tree"));
+ }
+
+ if(!LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) ||
+ (LIST_NumOfObjs(&p_FmPcdCcNode->ccTreesLst) != 1))
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("node has to be belonging to some tree and only to one tree"));
+ }
+
+ memcpy(p_nextEngineAndRequiredAction,
+ p_FmPcdCcNode->nextEngineAndRequiredAction,
+ FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+
+ if(check)
+ {
+ if((p_FmPcdCcNode->parseCode == CC_PC_FF_IPV4TTL) ||
+ (p_FmPcdCcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT) ||
+ (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_FF_IPV4TTL or CC_PC_FF_IPV6HOP_LIMIT can not be used for addKey, removeKey, modifyKey"));
+ }
+ }
+ }
+ else
+ {
+ p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
+ numOfKeys = p_FmPcdCcTree->numOfEntries;
+ memcpy(p_nextEngineAndRequiredAction,
+ p_FmPcdCcTree->nextEngineAndRequiredAction,
+ FM_PCD_MAX_NUM_OF_KEYS * sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+ }
+
+ p_FmPcdModifyCcKeyAdditionalParams =
+ (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(sizeof(t_FmPcdModifyCcKeyAdditionalParams));
+ if(!p_FmPcdModifyCcKeyAdditionalParams)
+ {
+ XX_Free(p_nextEngineAndRequiredAction);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
+ }
+ memset(p_FmPcdModifyCcKeyAdditionalParams, 0, sizeof(t_FmPcdModifyCcKeyAdditionalParams));
+
+ p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
+ p_FmPcdModifyCcKeyAdditionalParams->keyIndex = keyIndex;
+
+ while(i < numOfKeys)
+ {
+ if((j == keyIndex) && !wasUpdate)
+ {
+ if(modifyState == e_MODIFY_STATE_ADD)
+ j++;
+ else if(modifyState == e_MODIFY_STATE_REMOVE)
+ i++;
+ wasUpdate = TRUE;
+ }
+ else
+ {
+ memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+ i++;
+ j++;
+ }
+ }
+
+ if (keyIndex == numOfKeys)
+ {
+ if (modifyState == e_MODIFY_STATE_ADD)
+ j++;
+ else if(modifyState == e_MODIFY_STATE_REMOVE)
+ i++;
+ }
+
+ memcpy(&p_FmPcdModifyCcKeyAdditionalParams->nextEngineAndRequiredAction[j], &p_nextEngineAndRequiredAction[numOfKeys], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+
+ XX_Free(p_nextEngineAndRequiredAction);
+ *h_Params = p_FmPcdModifyCcKeyAdditionalParams;
+
+ return E_OK;
+}
+
+static t_Error UpdatePtrWhichPointOnCrntMdfNode(t_FmPcdCcNode *p_FmPcdCcNode, t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams ,t_List *h_OldLst, t_List *h_NewLst)
+{
+ if(!LIST_IsEmpty(&p_FmPcdCcNode->ccPrevNodesLst))
+ UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst);
+
+ if(!LIST_IsEmpty(&p_FmPcdCcNode->ccTreeIdLst))
+ UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_FmPcdCcNode, p_FmPcdModifyCcKeyAdditionalParams, h_OldLst, h_NewLst);
+
+ return E_OK;
+}
+
+static void FmPcdCcUpdateTreeOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
+{
+ ASSERT_COND(p_FmPcdCcTree);
+
+ if(add)
+ p_FmPcdCcTree->owners++;
+ else
+ {
+ ASSERT_COND(p_FmPcdCcTree->owners);
+ p_FmPcdCcTree->owners--;
+ }
+}
+
+#ifdef FM_PCD_CC_MANIP
+static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_FmPcdCcNode)
+{
+ t_Error err = E_OK;
+ int i = 0;
+
+ for(i = 0; i < p_FmPcdCcNode->numOfKeys; i++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsWithCcNodeParams(p_FmPcdCcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, (t_Handle)p_FmPcdCcNode);
+ if(err)
+ return err;
+ }
+ }
+
+ return err;
+}
+#endif /* FM_PCD_CC_MANIP */
+
+static t_Error CcUpdateParams(t_Handle h_FmPcd,
+ t_Handle h_FmPort,
+ t_Handle h_FmTree,
+ bool validate)
+{
+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *) h_FmTree;
+
+ return CcUpdateParam(h_FmPcd,
+ h_FmPort,
+ p_CcTree->nextEngineAndRequiredAction,
+ p_CcTree->numOfEntries,
+ UINT_TO_PTR(p_CcTree->ccTreeBaseAddr),
+ validate,
+ 0,
+ h_FmTree,
+ FALSE);
+}
+
+static t_Error CheckParams(t_Handle h_FmPcd,
+ t_FmPcdCcNodeParams *p_CcNodeParam,
+ t_FmPcdCcNode *p_FmPcdCcNode,
+ bool *isKeyTblAlloc)
+{
+ int tmp = 0;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Error err;
+ uint32_t requiredAction = 0;
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid"));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction;
+
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+
+ if(!p_KeyParams->p_Key)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
+
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+ err = UpdateGblMask(p_FmPcdCcNode,
+ p_CcNodeParam->keysParams.keySize,
+ p_KeyParams->p_Mask);
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp],&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
+ }
+
+ *isKeyTblAlloc = TRUE;
+ return E_OK;
+}
+
+static t_Error Ipv4TtlOrIpv6HopLimiCheckParams( t_Handle h_FmPcd,
+ t_FmPcdCcNodeParams *p_CcNodeParam, t_FmPcdCcNode *p_FmPcdCcNode,
+ bool *isKeyTblAlloc)
+{
+ int tmp = 0;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Error err;
+ uint8_t key = 0x01;
+ uint32_t requiredAction = 0;
+
+ if(p_FmPcdCcNode->numOfKeys != 1 )
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for IPV4TTL and IPV6_HOP_LIMIT has to be only 1 key - TTL = 1, otherwise it's Miss"));
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("For this node MissNextEngineParams are not valid"));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].nextEngineParams, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[p_FmPcdCcNode->numOfKeys].requiredAction = requiredAction;
+
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+ if(p_KeyParams->p_Mask)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
+ if(memcmp(p_KeyParams->p_Key, &key, 1) != 0)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("If node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams, &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+ p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
+ }
+
+ *isKeyTblAlloc = FALSE;
+ return E_OK;
+}
+
+static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
+ t_FmPcdCcNodeParams *p_CcNodeParam,
+ t_FmPcdCcNode *p_FmPcdCcNode,
+ /*uint16_t *ccInfo,*/
+ /*t_List *ccNextDifferentNodesLst,*/
+ bool *isKeyTblAlloc)
+{
+ int tmp = 0, countOnes = 0;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Error err;
+ uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
+ uint16_t countMask = (uint16_t)(glblMask >> 4);
+#ifdef FM_PCD_CC_MANIP
+ uint32_t requiredAction;
+#endif /* FM_PCD_CC_MANIP */
+
+ if (glblMask & 0x000f)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("icIndxMask has to be with last nibble 0"));
+
+ while (countMask)
+ {
+ countOnes++;
+ countMask=(uint16_t)(countMask>>1);
+ }
+
+ if (!POWER_OF_2(p_FmPcdCcNode->numOfKeys))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
+ if (p_FmPcdCcNode->numOfKeys != ((uint32_t)1<<countOnes ))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
+
+ err = ValidateNextEngineParams(h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss);
+ if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED)
+ RETURN_ERROR(MAJOR, err, ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
+
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+ if(p_KeyParams->p_Mask || p_KeyParams->p_Key)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
+
+ if((glblMask & (tmp * 16)) == (tmp * 16))
+ {
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_KeyParams->ccNextEngineParams.h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_KeyParams->ccNextEngineParams, &requiredAction);
+ if(err)
+ RETURN_ERROR(MAJOR, err, (NO_MSG));
+ }
+ p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction = requiredAction;
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams,&p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
+ }
+ else
+ {
+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams);
+ if(GET_ERROR_TYPE(err)!= E_NOT_SUPPORTED)
+ RETURN_ERROR(MAJOR, err, ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
+ }
+ }
+ *isKeyTblAlloc = FALSE;
+ memcpy(PTR_MOVE(p_FmPcdCcNode->p_GlblMask, 2), &glblMask, 2);
+
+ return E_OK;
+}
+
+t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
+ t_Error err = E_OK;
+ uint16_t keyIndex;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ SANITY_CHECK_RETURN_ERROR((grpId <= 7),E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree,E_INVALID_VALUE);
+
+ if(grpId >= p_FmPcdCcTree->numOfGrps)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree"));
+
+ if(index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
+
+ keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry + index);
+
+ err = ModifyKeyCommonPart1(h_FmPcdCcTree, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+ p_ModifyKeyParams->tree = TRUE;
+
+ err = BuildNewNodeModifyNextEngine (h_FmPcd, h_FmPcdCcTree, keyIndex,p_FmPcdCcNextEngineParams, h_OldLst, h_NewLst, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ return E_OK;
+
+}
+
+t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *) h_FmPcdCcNode;
+ t_Error err = E_OK;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ if(keyIndex >= p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("impossible to remove key when numOfKeys <= keyIndex"));
+
+ if(!p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("keyIndex you asked > numOfKeys of relevant node that was initialized"));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_REMOVE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+ err = BuildNewNodeRemoveKey (p_FmPcdCcNode, keyIndex, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+
+}
+
+t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, t_List *h_OldLst, t_List *h_NewLst,t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_Error err = E_OK;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ if(keyIndex >= p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size for ModifyKey has to be the same as defined in SetNode"));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeModifyKey (p_FmPcdCcNode, keyIndex, p_Key, p_Mask, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ return E_OK;
+}
+
+
+t_Error FmPcdCcModiyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, uint8_t keyIndex,t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_Error err = E_OK;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_HANDLE);
+
+ if(keyIndex >= p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, FALSE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ return E_OK;
+}
+
+t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_Error err = E_OK;
+ uint16_t keyIndex;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNode,E_INVALID_VALUE);
+
+ keyIndex = p_FmPcdCcNode->numOfKeys;
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeModifyNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex,p_FmPcdCcNextEngineParams, h_OldPointer, h_NewPointer, p_ModifyKeyParams);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+ t_Error err = E_OK;
+
+ if(keyIndex > p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step."));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_ADD, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+ err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, TRUE);
+ if(err)
+ {
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
+ t_Error err = E_OK;
+
+ if(keyIndex > p_FmPcdCcNode->numOfKeys)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("keyIndex > previousely cleared last index + 1"));
+
+ if((p_FmPcdCcNode->numOfKeys + 1) > FM_PCD_MAX_NUM_OF_CC_NODES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfKeys with new key can not be larger than 255"));
+
+ if(keySize != p_FmPcdCcNode->userSizeOfExtraction)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be defined as it was defined in initialization step"));
+
+ if(p_FmPcdCcNode->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("handler to FmPcd is diferent from one which was assigned to the node in the Init time"));
+
+ err = ModifyKeyCommonPart1(p_FmPcdCcNode, keyIndex, h_AdditionalParams, e_MODIFY_STATE_CHANGE, TRUE, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ p_ModifyKeyParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_AdditionalParams;
+
+ err = BuildNewNodeAddOrMdfyKeyAndNextEngine (h_FmPcd, p_FmPcdCcNode, keyIndex, p_FmPcdCcKeyParams, p_ModifyKeyParams, FALSE);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = UpdatePtrWhichPointOnCrntMdfNode(p_FmPcdCcNode, p_ModifyKeyParams, h_OldLst, h_NewLst);
+ if(err)
+ {
+ ReleaseNewNodeCommonPart(p_ModifyKeyParams);
+ XX_Free(p_ModifyKeyParams);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+t_Error FmPcdCcReleaseModifiedDataStructure(t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, t_List *h_FmPcdNewPointersLst, uint16_t numOfGoodChanges, t_Handle *h_Params)
+{
+ t_FmPcdModifyCcKeyAdditionalParams *p_CcNewModifyAdditionalParams = (t_FmPcdModifyCcKeyAdditionalParams *)*h_Params;
+ t_List *p_Pos;
+ t_Error err = E_OK;
+ t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
+ t_Handle h_Muram;
+ t_FmPcdCcNode *p_FmPcdCcNextNode;
+ t_List *p_UpdateLst;
+
+ UNUSED(numOfGoodChanges);
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_CcNewModifyAdditionalParams->h_CurrentNode,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdOldPointersLst)),E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR((numOfGoodChanges == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR((LIST_NumOfObjs(h_FmPcdOldPointersLst) == LIST_NumOfObjs(h_FmPcdNewPointersLst)),E_INVALID_STATE);
+
+ /*we don't update subtree of the new node with new tree because it was done in the previose stage*/
+ if(p_CcNewModifyAdditionalParams->h_NodeForAdd)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForAdd;
+ if(!p_CcNewModifyAdditionalParams->tree)
+ p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
+ else
+ p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
+ p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode);
+ if(p_CcNodeInformation)
+ p_CcNodeInformation->index++;
+ else
+ {
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = (t_Handle)p_CcNewModifyAdditionalParams->h_CurrentNode;
+ ccNodeInfo.index = 1;
+ EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo);
+ }
+ }
+
+ if(p_CcNewModifyAdditionalParams->h_NodeForRmv)
+ {
+
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_CcNewModifyAdditionalParams->h_NodeForRmv;
+ if(!p_CcNewModifyAdditionalParams->tree)
+ {
+ p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNextNode->ccTreesLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ err = FmPcdCcSetRequiredAction(h_FmPcd,
+ UPDATE_CC_WITH_DELETE_TREE,
+ &((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex],
+ PTR_MOVE(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable, p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ 1,
+ p_CcNodeInformation->h_CcNode);
+ }
+ }
+ else
+ {
+ p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
+ err = FmPcdCcSetRequiredAction(h_FmPcd,
+ UPDATE_CC_WITH_DELETE_TREE,
+ &((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction[p_CcNewModifyAdditionalParams->keyIndex],
+ UINT_TO_PTR(((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_CcNewModifyAdditionalParams->keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
+ 1,
+ p_CcNewModifyAdditionalParams->h_CurrentNode);
+ }
+ if(err)
+ return err;
+
+ /*we remove from the subtree of the removed node tree because it wasn't done in the previose stage*/
+ /*update ccPrevNodesLst or ccTreeIdLst of the removed node*/
+ /*update of the nodeOwner*/
+ p_CcNodeInformation = FindNodeInfoInReleventLst(p_UpdateLst, p_CcNewModifyAdditionalParams->h_CurrentNode);
+ ASSERT_COND(p_CcNodeInformation);
+ ASSERT_COND(p_CcNodeInformation->index);
+ p_CcNodeInformation->index--;
+ if(p_CcNodeInformation->index == 0)
+ DequeueNodeInfoFromRelevantLst(p_UpdateLst,p_CcNewModifyAdditionalParams->h_CurrentNode);
+ ASSERT_COND(LIST_NumOfObjs(&p_FmPcdCcNextNode->ccTreesLst) == 1);
+ UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
+ }
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_CcNewModifyAdditionalParams->h_ManipForRmv)
+ FmPcdManipUpdateOwner(p_CcNewModifyAdditionalParams->h_ManipForRmv, FALSE);
+#endif /* FM_PCD_CC_MANIP */
+
+ h_Muram = FmPcdGetMuramHandle(h_FmPcd);
+ ASSERT_COND(h_Muram);
+
+ /*we release new AD which was allocated and updated for copy from to actual AD*/
+ LIST_FOR_EACH(p_Pos, h_FmPcdNewPointersLst)
+ {
+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInformation->h_CcNode);
+ FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
+
+ }
+
+ /*free Old data structure if it has to be freed - new data structure was allocated*/
+ if(p_CcNewModifyAdditionalParams->p_AdTableOld)
+ FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_AdTableOld);
+ if(p_CcNewModifyAdditionalParams->p_KeysMatchTableOld)
+ FM_MURAM_FreeMem(h_Muram,p_CcNewModifyAdditionalParams->p_KeysMatchTableOld);
+
+ /*update current modified node with changed fields if it's required*/
+ if(!p_CcNewModifyAdditionalParams->tree)
+ {
+ if(p_CcNewModifyAdditionalParams->p_AdTableNew)
+ ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_AdTable = p_CcNewModifyAdditionalParams->p_AdTableNew;
+ if(p_CcNewModifyAdditionalParams->numOfKeys)
+ ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfKeys = p_CcNewModifyAdditionalParams->numOfKeys;
+ if(p_CcNewModifyAdditionalParams->p_KeysMatchTableNew)
+ ((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->h_KeysMatchTable = p_CcNewModifyAdditionalParams->p_KeysMatchTableNew;
+ memcpy(((t_FmPcdCcNode *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (FM_PCD_MAX_NUM_OF_KEYS));
+ }
+ else
+ memcpy(&((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->nextEngineAndRequiredAction, &p_CcNewModifyAdditionalParams->nextEngineAndRequiredAction, sizeof(t_FmPcdCcNextEngineAndRequiredActionParams) * (((t_FmPcdCcTree *)(p_CcNewModifyAdditionalParams->h_CurrentNode))->numOfEntries));
+
+ ReleaseLst(h_FmPcdOldPointersLst);
+ ReleaseLst(h_FmPcdNewPointersLst);
+ XX_Free(p_CcNewModifyAdditionalParams);
+
+ return E_OK;
+}
+
+uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_CcNodeInformation *p_CcNodeInfo;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, (uint32_t)ILLEGAL_BASE);
+
+ p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
+ return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode) - p_FmPcd->physicalMuramBase);
+}
+
+t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *) h_FmPcdCcTree;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
+
+ if(grpId >= p_FmPcdCcTree->numOfGrps)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("grpId you asked > numOfGroup of relevant tree"));
+ *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
+ *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
+ return E_OK;
+}
+
+t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint32_t *p_Offset, t_Handle h_FmPort)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_STATE);
+
+ FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, TRUE);
+
+ *p_Offset = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr)) -
+ p_FmPcd->physicalMuramBase);
+
+ err = CcUpdateParams(h_FmPcd, h_FmPort, h_FmPcdCcTree, TRUE);
+
+ return err;
+}
+
+t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
+{
+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
+
+ UNUSED(h_FmPcd);
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcTree,E_INVALID_HANDLE);
+
+ FmPcdCcUpdateTreeOwner(p_FmPcdCcTree, FALSE);
+
+ return E_OK;
+}
+
+t_Error FmPcdCcTreeTryLock(t_Handle h_FmPcdCcTree)
+{
+ if (TRY_LOCK(NULL, &((t_FmPcdCcTree *)h_FmPcdCcTree)->lock))
+ return E_OK;
+ return ERROR_CODE(E_BUSY);
+}
+
+t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
+ t_List *p_Pos;
+ t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
+ t_Error err = E_OK;
+
+ UNUSED(h_FmPcd);
+
+ if(LIST_IsEmpty(&p_FmPcdCcNode->ccTreesLst))
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("asked for more nodes in CC than MAX")) ;
+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode->ccTreesLst)
+ {
+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
+ ASSERT_COND(p_CcNodeInfo->h_CcNode);
+ err = FmPcdCcTreeTryLock(p_CcNodeInfo->h_CcNode);
+ if(err == E_OK)
+ {
+ memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
+ nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
+ EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo);
+ }
+ else
+ FmPcdCcNodeTreeReleaseLock(p_List);
+ }
+
+ return err;
+}
+
+t_Handle FM_PCD_CcBuildTree(t_Handle h_FmPcd, t_FmPcdCcTreeParams *p_PcdGroupsParam)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_Error err = E_OK;
+ int i = 0, j = 0, k = 0;
+ t_FmPcdCcTree *p_FmPcdCcTree;
+ uint8_t numOfEntries;
+ t_Handle p_CcTreeTmp;
+ t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
+ t_FmPcdCcNextEngineAndRequiredActionParams params[16];
+ t_NetEnvParams netEnvParams;
+ uint8_t lastOne = 0;
+ uint32_t requiredAction = 0;
+ t_FmPcdCcNode *p_FmPcdCcNextNode;
+ t_CcNodeInformation ccNodeInfo, *p_CcInformation;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam,E_INVALID_HANDLE, NULL);
+
+ if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
+ return NULL;
+ }
+
+ p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
+ if(!p_FmPcdCcTree)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
+ return NULL;
+ }
+ memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree)) ;
+ memset(params, 0, 16 * sizeof(t_FmPcdCcNextEngineParams));
+
+ INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
+
+ numOfEntries = 0;
+ p_FmPcdCcTree->netEnvId = (uint8_t)(PTR_TO_UINT(p_PcdGroupsParam->h_NetEnv)-1);
+ for(i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
+ {
+ p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
+
+ if (p_FmPcdCcGroupParams->numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_CC_UNITS)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
+ return NULL;
+ }
+
+ p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
+ p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup =(uint8_t)( 0x01 << p_FmPcdCcGroupParams->numOfDistinctionUnits);
+ numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
+ if(numOfEntries > 16)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than 16"));
+ return NULL;
+ }
+ if(lastOne)
+ {
+ if(p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
+ return NULL;
+ }
+ }
+
+ lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
+
+ netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
+ netEnvParams.numOfDistinctionUnits = p_FmPcdCcGroupParams->numOfDistinctionUnits;
+ memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds, (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
+ err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+
+ p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
+ for(j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; j++)
+ {
+ err = ValidateNextEngineParams(h_FmPcd,&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j]);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, err, (NO_MSG));
+ return NULL;
+ }
+
+#ifdef FM_PCD_CC_MANIP
+ if(p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
+ {
+ err = FmPcdManipCheckParamsForCcNextEgine(&p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], &requiredAction);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ return NULL;
+ }
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ memcpy(&params[k].nextEngineParams, &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], sizeof(t_FmPcdCcNextEngineParams));
+ requiredAction |= UPDATE_CC_WITH_TREE;
+ params[k].requiredAction = requiredAction;
+ k++;
+ }
+ }
+
+ p_FmPcdCcTree->numOfEntries = (uint8_t)k;
+ p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
+ p_FmPcdCcTree->ccTreeBaseAddr =
+ PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
+ (uint32_t)( k * FM_PCD_CC_AD_ENTRY_SIZE),
+ FM_PCD_CC_AD_TABLE_ALIGN));
+
+ if(!p_FmPcdCcTree->ccTreeBaseAddr)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+ return NULL;
+ }
+ IOMemSet32(UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, (uint32_t)(k * FM_PCD_CC_AD_ENTRY_SIZE));
+
+ p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
+
+ j = 0;
+ for(i = 0; i < numOfEntries; i++)
+ {
+ NextStepAd(p_CcTreeTmp,&params[i].nextEngineParams,p_FmPcd);
+ p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ memcpy(&p_FmPcdCcTree->nextEngineAndRequiredAction[i], &params[i], sizeof(t_FmPcdCcNextEngineAndRequiredActionParams));
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine== e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode;
+ if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ {
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
+ ccNodeInfo.index = 1;
+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, &ccNodeInfo);
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE);
+ }
+ else
+ {
+ p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccTreeIdLst,(t_Handle)p_FmPcdCcTree);
+ ASSERT_COND(p_CcInformation);
+ p_CcInformation->index++;
+ }
+ }
+ }
+
+ FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
+ p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
+
+ for(i = 0; i < p_FmPcdCcTree->numOfEntries ; i++)
+ {
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode;
+
+ if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE);
+ }
+ }
+
+ for(i = 0; i < numOfEntries; i++)
+ {
+ if(p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction)
+ {
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcTree->nextEngineAndRequiredAction[i].requiredAction, &p_FmPcdCcTree->nextEngineAndRequiredAction[i], p_CcTreeTmp,1, p_FmPcdCcTree);
+ if(err)
+ {
+ DeleteTree(p_FmPcdCcTree,p_FmPcd);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+ return NULL;
+ }
+ p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ }
+ }
+
+ return p_FmPcdCcTree;
+}
+
+t_Error FM_PCD_CcDeleteTree(t_Handle h_FmPcd, t_Handle h_CcTree)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
+ int i= 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_CcTree,E_INVALID_STATE);
+
+ FmPcdDecNetEnvOwners(h_FmPcd, p_CcTree->netEnvId);
+
+ if(p_CcTree->owners)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
+
+ for(i = 0; i <p_CcTree->numOfEntries; i++)
+ {
+ if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ UpdateNodeOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
+ }
+
+#ifdef FM_PCD_CC_MANIP
+ for(i = 0; i < p_CcTree->numOfEntries; i++)
+ {
+ if(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ FmPcdManipUpdateOwner(p_CcTree->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ DeleteTree(p_CcTree, p_FmPcd);
+ return E_OK;
+}
+
+t_Handle FM_PCD_CcSetNode(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *) h_FmPcd;
+ t_FmPcdCcNode *p_FmPcdCcNode, *p_FmPcdCcNextNode;
+ t_Error err = E_OK;
+ int tmp, size;
+ bool glblMask = FALSE;
+ t_FmPcdCcKeyParams *p_KeyParams;
+ t_Handle p_KeysMatchTblTmp;
+ t_Handle p_AdTableTmp;
+ bool fullField = FALSE;
+ ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
+ bool isKeyTblAlloc, fromIc = FALSE;
+ t_CcNodeInformation ccNodeInfo, *p_CcInformation;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
+
+ /*
+ if (!p_CcNodeParam->keysParams.keySize ||
+ !p_CcNodeParam->keysParams.numOfKeys)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("At least one key of keySize > 0 must be defined."));
+ return NULL;
+ }
+ */
+ p_FmPcdCcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
+ if(!p_FmPcdCcNode)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+ return NULL;
+ }
+ memset(p_FmPcdCcNode, 0, sizeof(t_FmPcdCcNode));
+
+ p_FmPcdCcNode->p_GlblMask = (t_Handle)XX_Malloc(CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+ memset(p_FmPcdCcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+
+ p_FmPcdCcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
+
+ p_FmPcdCcNode->h_FmPcd = h_FmPcd;
+
+ INIT_LIST(&p_FmPcdCcNode->ccPrevNodesLst);
+ INIT_LIST(&p_FmPcdCcNode->ccTreeIdLst);
+ INIT_LIST(&p_FmPcdCcNode->ccTreesLst);
+
+ if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) &&
+ ((p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv4) ||
+ (p_CcNodeParam->extractCcParams.extractByHdr.hdr == HEADER_TYPE_IPv6)) &&
+ (p_CcNodeParam->extractCcParams.extractByHdr.type == e_FM_PCD_EXTRACT_FULL_FIELD) &&
+ ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6 == NET_HEADER_FIELD_IPv6_HOP_LIMIT) ||
+ (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4 == NET_HEADER_FIELD_IPv4_TTL)))
+ {
+ err = Ipv4TtlOrIpv6HopLimiCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc);
+ glblMask = FALSE;
+
+ }
+ else if((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR) &&
+ ((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_KEY) ||
+ (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_HASH) ||
+ (p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
+ {
+ if((p_CcNodeParam->extractCcParams.extractNonHdr.src == e_FM_PCD_EXTRACT_FROM_FLOW_ID) &&
+ (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
+ return NULL;
+ }
+
+ icCode = IcDefineCode(p_CcNodeParam);
+ fromIc = TRUE;
+ if(icCode == CC_PRIVATE_INFO_NONE)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
+ return NULL;
+ }
+
+ if((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP) || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
+ {
+ err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_FmPcdCcNode, &isKeyTblAlloc);
+
+ glblMask = TRUE;
+ }
+ else
+ {
+ err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc);
+ if(p_FmPcdCcNode->glblMaskSize)
+ glblMask = TRUE;
+ }
+ }
+ else
+ {
+ err = CheckParams(h_FmPcd, p_CcNodeParam,p_FmPcdCcNode, &isKeyTblAlloc);
+ if(p_FmPcdCcNode->glblMaskSize)
+ glblMask = TRUE;
+ }
+
+ if(err)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+
+ switch(p_CcNodeParam->extractCcParams.type)
+ {
+ case(e_FM_PCD_EXTRACT_BY_HDR):
+ switch(p_CcNodeParam->extractCcParams.extractByHdr.type)
+ {
+ case(e_FM_PCD_EXTRACT_FULL_FIELD):
+ p_FmPcdCcNode->parseCode = GetFullFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
+ GetSizeHeaderField(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField, &p_FmPcdCcNode->sizeOfExtraction);
+ fullField = TRUE;
+ if((p_FmPcdCcNode->parseCode != CC_PC_FF_TCI1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_TCI2) &&
+ (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_MPLS1) &&
+ (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) &&
+ (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) && (p_FmPcdCcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2) &&
+ glblMask)
+ {
+ glblMask = FALSE;
+ p_FmPcdCcNode->glblMaskSize = 4;
+ p_FmPcdCcNode->lclMask = TRUE;
+ }
+ break;
+ case(e_FM_PCD_EXTRACT_FROM_HDR):
+ p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
+ p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
+ p_FmPcdCcNode->parseCode = GetPrParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
+ p_FmPcdCcNode->offset,glblMask, &p_FmPcdCcNode->prsArrayOffset);
+ break;
+ case(e_FM_PCD_EXTRACT_FROM_FIELD):
+ p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
+ p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
+ p_FmPcdCcNode->parseCode = GetFieldParseCode(p_CcNodeParam->extractCcParams.extractByHdr.hdr, p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
+ p_FmPcdCcNode->offset,&p_FmPcdCcNode->prsArrayOffset,
+ p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
+ break;
+ default:
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ return NULL;
+ }
+ break;
+ case(e_FM_PCD_EXTRACT_NON_HDR):
+ /* get the field code for the generic extract */
+ p_FmPcdCcNode->sizeOfExtraction = p_CcNodeParam->extractCcParams.extractNonHdr.size;
+ p_FmPcdCcNode->offset = p_CcNodeParam->extractCcParams.extractNonHdr.offset;
+ p_FmPcdCcNode->parseCode = GetGenParseCode(p_CcNodeParam->extractCcParams.extractNonHdr.src, p_FmPcdCcNode->offset, glblMask, &p_FmPcdCcNode->prsArrayOffset, fromIc,icCode);
+
+ if(p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
+ {
+ if((p_FmPcdCcNode->offset + p_FmPcdCcNode->sizeOfExtraction) > 64)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION,("when node of the type CC_PC_GENERIC_IC_HASH_INDEXED offset + size can not be bigger then size of HASH 64 bits (8 bytes)"));
+ return NULL;
+ }
+ }
+ if((p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_GMASK) || (p_FmPcdCcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
+ {
+ p_FmPcdCcNode->offset += p_FmPcdCcNode->prsArrayOffset;
+ p_FmPcdCcNode->prsArrayOffset = 0;
+ }
+ break;
+
+ default:
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ return NULL;
+ }
+
+ if(p_FmPcdCcNode->parseCode == CC_PC_ILLEGAL)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("illeagl extraction type"));
+ return NULL;
+ }
+
+ if((p_FmPcdCcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) || !p_FmPcdCcNode->sizeOfExtraction)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("sizeOfExatrction can not be greater than 56 and not 0"));
+ return NULL;
+ }
+
+ if(p_CcNodeParam->keysParams.keySize != p_FmPcdCcNode->sizeOfExtraction)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction"));
+ return NULL;
+ }
+
+
+ p_FmPcdCcNode->userSizeOfExtraction = p_FmPcdCcNode->sizeOfExtraction;
+
+ if(!glblMask)
+ memset(p_FmPcdCcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
+
+#ifdef FM_PCD_CC_MANIP
+ err = CheckAndSetManipParamsWithCcNodeParams(p_FmPcdCcNode);
+ if(err != E_OK)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("keySize has to be equal to sizeOfExtraction"));
+ return NULL;
+ }
+#endif /* FM_PCD_CC_MANIP */
+
+ GetCcExtractKeySize(p_FmPcdCcNode->sizeOfExtraction, &p_FmPcdCcNode->ccKeySizeAccExtraction);
+
+ if(p_FmPcdCcNode->lclMask)
+ size = 2 * p_FmPcdCcNode->ccKeySizeAccExtraction;
+ else
+ size = p_FmPcdCcNode->ccKeySizeAccExtraction;
+
+ if(isKeyTblAlloc)
+ {
+ p_FmPcdCcNode->h_KeysMatchTable =(t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)(size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1)),
+ FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
+ if(!p_FmPcdCcNode->h_KeysMatchTable)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for KEY MATCH table"));
+ return NULL;
+ }
+ IOMemSet32((uint8_t *)p_FmPcdCcNode->h_KeysMatchTable, 0, size * sizeof(uint8_t) * (p_FmPcdCcNode->numOfKeys + 1));
+ }
+
+ p_FmPcdCcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcdCcNode->h_FmPcd),
+ (uint32_t)( (p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE),
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_FmPcdCcNode->h_AdTable)
+ {
+ DeleteNode(p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory in MURAM for AD table "));
+ return NULL;
+ }
+ IOMemSet32((uint8_t *)p_FmPcdCcNode->h_AdTable, 0, (uint32_t)((p_FmPcdCcNode->numOfKeys+1) * FM_PCD_CC_AD_ENTRY_SIZE));
+
+ p_KeysMatchTblTmp = p_FmPcdCcNode->h_KeysMatchTable;
+ p_AdTableTmp = p_FmPcdCcNode->h_AdTable;
+ for(tmp = 0 ; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
+
+ if(p_KeysMatchTblTmp)
+ {
+ Mem2IOCpy32((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key, p_FmPcdCcNode->sizeOfExtraction);
+
+ if(p_FmPcdCcNode->lclMask && p_KeyParams->p_Mask)
+ Mem2IOCpy32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), p_KeyParams->p_Mask, p_FmPcdCcNode->sizeOfExtraction);
+ else if(p_FmPcdCcNode->lclMask)
+ IOMemSet32(PTR_MOVE(p_KeysMatchTblTmp, p_FmPcdCcNode->ccKeySizeAccExtraction), 0xff, p_FmPcdCcNode->sizeOfExtraction);
+ p_KeysMatchTblTmp = PTR_MOVE(p_KeysMatchTblTmp, size * sizeof(uint8_t));
+ }
+ NextStepAd(p_AdTableTmp,&p_KeyParams->ccNextEngineParams, p_FmPcd);
+
+ p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ }
+ NextStepAd(p_AdTableTmp,&p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, p_FmPcd);
+
+ if(fullField == TRUE)
+ p_FmPcdCcNode->sizeOfExtraction = 0;
+
+
+ for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode;
+
+ if(!IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ {
+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
+ ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcNode;
+ ccNodeInfo.index = 1;
+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst, &ccNodeInfo);
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, TRUE);
+ }
+ else
+ {
+ p_CcInformation = FindNodeInfoInReleventLst(&p_FmPcdCcNextNode->ccPrevNodesLst,(t_Handle)p_FmPcdCcNode);
+ ASSERT_COND(p_CcInformation);
+ p_CcInformation->index++;
+ }
+ }
+
+ }
+
+ for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys + 1; tmp++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].nextEngineParams.params.ccParams.h_CcNode;
+
+ if(IsNodeInModifiedState((t_Handle)p_FmPcdCcNextNode))
+ UpdateNodeWithModifiedState((t_Handle)p_FmPcdCcNextNode, FALSE);
+ }
+ }
+
+ p_AdTableTmp = p_FmPcdCcNode->h_AdTable;
+ for(tmp = 0; tmp < p_FmPcdCcNode->numOfKeys; tmp++)
+ {
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction)
+ {
+
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL);
+ if(err)
+ {
+ FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+ p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
+ }
+ }
+ if(p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction)
+ {
+ err = FmPcdCcSetRequiredAction(h_FmPcd, p_FmPcdCcNode->nextEngineAndRequiredAction[tmp].requiredAction, &p_FmPcdCcNode->nextEngineAndRequiredAction[tmp], p_AdTableTmp,1, NULL);
+ if(err)
+ {
+ FM_PCD_CcDeleteNode(h_FmPcd, (t_Handle)p_FmPcdCcNode);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+
+ }
+
+
+ return p_FmPcdCcNode;
+}
+
+t_Error FM_PCD_CcDeleteNode(t_Handle h_FmPcd, t_Handle h_CcNode)
+{
+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
+ int i = 0;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+
+ UNUSED(h_FmPcd);
+ if(!p_CcNode)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID is not initialized"));
+
+ if(p_CcNode->owners)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("the node with this ID can not be removed because this node is occupied, first - unbind this node"));
+
+ for(i = 0; i < p_CcNode->numOfKeys; i++)
+ {
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
+
+ }
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ UpdateNodeOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.params.ccParams.h_CcNode, FALSE);
+
+#ifdef FM_PCD_CC_MANIP
+ for(i = 0; i < p_CcNode->numOfKeys; i++)
+ {
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
+ }
+ if(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip)
+ FmPcdManipUpdateOwner(p_CcNode->nextEngineAndRequiredAction[i].nextEngineParams.h_Manip, FALSE);
+#endif /* FM_PCD_CC_MANIP */
+
+ DeleteNode(p_CcNode);
+
+ return E_OK;
+}
+
+t_Error FM_PCD_CcNodeAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcAddKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams);
+}
+
+t_Error FM_PCD_CcNodeRemoveKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcRemoveKey(p_FmPcd->h_Hc, h_CcNode, keyIndex);
+}
+
+t_Error FM_PCD_CcNodeModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyKey(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_Key, p_Mask);
+}
+
+t_Error FM_PCD_CcNodeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyNodeNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, p_FmPcdCcNextEngineParams);
+}
+
+t_Error FM_PCD_CcNodeModifyMissNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyNodeMissNextEngine(p_FmPcd->h_Hc, h_CcNode, p_FmPcdCcNextEngineParams);
+}
+
+t_Error FM_PCD_CcTreeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyTreeNextEngine(p_FmPcd->h_Hc, h_CcTree, grpId, index, p_FmPcdCcNextEngineParams);
+}
+
+t_Error FM_PCD_CcNodeModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
+
+ return FmHcPcdCcModifyKeyAndNextEngine(p_FmPcd->h_Hc, h_CcNode, keyIndex, keySize, p_KeyParams);
+}
+
+uint32_t FM_PCD_CcNodeGetKeyCounter(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex)
+{
+ t_FmPcdCcNode *p_FmPcdCcNode = (t_FmPcdCcNode *)h_CcNode;
+ t_AdOfTypeResult *p_AdResult = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_VALUE(h_CcNode, E_INVALID_HANDLE, 0);
+#ifdef DISABLE_SANITY_CHECKS
+UNUSED(h_FmPcd);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ if (keyIndex >= p_FmPcdCcNode->numOfKeys)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE,
+ ("keyIndex > numOfKeys defined for this node"));
+ return 0;
+ }
+
+ p_AdResult = PTR_MOVE(p_FmPcdCcNode->h_AdTable, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE);
+ ASSERT_COND(p_AdResult);
+
+ if (p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_CC)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE,
+ ("statistics updated only for entries where next engine not CC"));
+ return 0;
+ }
+
+ if(((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_DONE) &&
+ !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.enqueueParams.statisticsEn) ||
+ ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_KG) &&
+ !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.kgParams.statisticsEn) ||
+ ((p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.nextEngine == e_FM_PCD_PLCR) &&
+ !p_FmPcdCcNode->nextEngineAndRequiredAction[keyIndex].nextEngineParams.params.plcrParams.statisticsEn))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE,
+ ("statistics wasn't enable"));
+ return 0;
+ }
+
+ return GET_UINT32(p_AdResult->res);
+}
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h
new file mode 100644
index 0000000..a96142b
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_cc.h
@@ -0,0 +1,312 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_cc.h
+
+ @Description FM PCD CC ...
+*//***************************************************************************/
+#ifndef __FM_CC_H
+#define __FM_CC_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "list_ext.h"
+
+#include "fm_pcd.h"
+
+
+/***********************************************************************/
+/* Coarse classification defines */
+/***********************************************************************/
+
+#define CC_PC_FF_MACDST 0x00
+#define CC_PC_FF_MACSRC 0x01
+#define CC_PC_FF_ETYPE 0x02
+
+#define CC_PC_FF_TCI1 0x03
+#define CC_PC_FF_TCI2 0x04
+
+#define CC_PC_FF_MPLS1 0x06
+#define CC_PC_FF_MPLS_LAST 0x07
+
+#define CC_PC_FF_IPV4DST1 0x08
+#define CC_PC_FF_IPV4DST2 0x16
+#define CC_PC_FF_IPV4IPTOS_TC1 0x09
+#define CC_PC_FF_IPV4IPTOS_TC2 0x17
+#define CC_PC_FF_IPV4PTYPE1 0x0A
+#define CC_PC_FF_IPV4PTYPE2 0x18
+#define CC_PC_FF_IPV4SRC1 0x0b
+#define CC_PC_FF_IPV4SRC2 0x19
+#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
+#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
+#define CC_PC_FF_IPV4TTL 0x29
+
+
+#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
+#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
+#define CC_PC_FF_IPV6PTYPE1 0x0e
+#define CC_PC_FF_IPV6PTYPE2 0x1c
+#define CC_PC_FF_IPV6DST1 0x0f
+#define CC_PC_FF_IPV6DST2 0x1d
+#define CC_PC_FF_IPV6SRC1 0x10
+#define CC_PC_FF_IPV6SRC2 0x1e
+#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
+#define CC_PC_FF_GREPTYPE 0x11
+
+#define CC_PC_FF_MINENCAP_PTYPE 0x12
+#define CC_PC_FF_MINENCAP_IPDST 0x13
+#define CC_PC_FF_MINENCAP_IPSRC 0x14
+#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
+
+#define CC_PC_FF_L4PSRC 0x1f
+#define CC_PC_FF_L4PDST 0x20
+#define CC_PC_FF_L4PSRC_L4PDST 0x21
+
+#define CC_PC_FF_PPPPID 0x05
+
+#define CC_PC_PR_SHIM1 0x22
+#define CC_PC_PR_SHIM2 0x23
+
+#define CC_PC_GENERIC_WITHOUT_MASK 0x27
+#define CC_PC_GENERIC_WITH_MASK 0x28
+#define CC_PC_GENERIC_IC_GMASK 0x2B
+#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
+
+#define CC_PR_OFFSET 0x25
+#define CC_PR_WITHOUT_OFFSET 0x26
+
+#define CC_PC_PR_ETH_OFFSET 19
+#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
+#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
+#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
+#define CC_PC_PR_VLAN1_OFFSET 21
+#define CC_PC_PR_VLAN2_OFFSET 22
+#define CC_PC_PR_PPPOE_OFFSET 24
+#define CC_PC_PR_MPLS1_OFFSET 25
+#define CC_PC_PR_MPLS_LAST_OFFSET 26
+#define CC_PC_PR_IP1_OFFSET 27
+#define CC_PC_PR_IP_LAST_OFFSET 28
+#define CC_PC_PR_MINENC_OFFSET 28
+#define CC_PC_PR_L4_OFFSET 30
+#define CC_PC_PR_GRE_OFFSET 29
+#define CC_PC_PR_ETYPE_LAST_OFFSET 23
+#define CC_PC_PR_NEXT_HEADER_OFFSET 31
+
+#define CC_PC_ILLEGAL 0xff
+#define CC_SIZE_ILLEGAL 0
+
+#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
+#define FM_PCD_CC_AD_TABLE_ALIGN 256
+#define FM_PCD_CC_AD_ENTRY_SIZE 16
+#define FM_PCD_CC_NUM_OF_KEYS 255
+
+#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
+#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
+#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
+#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
+#define FM_PCD_AD_RESULT_NADEN 0x20000000
+#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
+
+
+#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
+#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
+
+#define FM_PCD_AD_TYPE_MASK 0xc0000000
+#define FM_PCD_AD_OPCODE_MASK 0x0000000f
+
+#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
+
+#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
+#define CC_GLBL_MASK_SIZE 4
+
+typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
+
+#define CC_PRIVATE_INFO_NONE 0
+#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
+#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
+#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
+#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
+
+/***********************************************************************/
+/* Memory map */
+/***********************************************************************/
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct {
+ volatile uint32_t fqid;
+ volatile uint32_t plcrProfile;
+ volatile uint32_t nia;
+ volatile uint32_t res;
+} _PackedType t_AdOfTypeResult;
+
+typedef _Packed struct {
+ volatile uint32_t ccAdBase;
+ volatile uint32_t matchTblPtr;
+ volatile uint32_t pcAndOffsets;
+ volatile uint32_t gmask;
+} _PackedType t_AdOfTypeContLookup;
+
+typedef _Packed union {
+ volatile t_AdOfTypeResult adResult;
+ volatile t_AdOfTypeContLookup adContLookup;
+} _PackedType t_Ad;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/***********************************************************************/
+/* Driver's internal structures */
+/***********************************************************************/
+
+typedef enum e_ModifyState {
+ e_MODIFY_STATE_ADD = 0,
+ e_MODIFY_STATE_REMOVE,
+ e_MODIFY_STATE_CHANGE
+} e_ModifyState;
+
+typedef struct {
+ t_FmPcdCcNextEngineParams nextEngineParams;
+ uint32_t requiredAction;
+ uint32_t shadowAction;
+} t_FmPcdCcNextEngineAndRequiredActionParams;
+
+typedef struct {
+ t_Handle p_Ad;
+ e_FmPcdEngine fmPcdEngine;
+ bool adAllocated;
+ bool isTree;
+
+ uint32_t myInfo;
+ t_List *h_CcNextNodesLst;
+ t_Handle h_AdditionalInfo;
+ t_Handle h_Node;
+} t_FmPcdModifyCcAdditionalParams;
+
+typedef struct {
+ t_Handle p_AdTableNew;
+ t_Handle p_KeysMatchTableNew;
+ t_Handle p_AdTableOld;
+ t_Handle p_KeysMatchTableOld;
+ uint16_t numOfKeys;
+ t_Handle h_CurrentNode;
+ uint16_t keyIndex;
+ t_Handle h_NodeForAdd;
+ t_Handle h_NodeForRmv;
+ t_Handle h_ManipForRmv;
+ bool tree;
+
+ t_FmPcdCcNextEngineAndRequiredActionParams nextEngineAndRequiredAction[256];
+} t_FmPcdModifyCcKeyAdditionalParams;
+
+typedef struct {
+ t_Handle h_Manip;
+ t_Handle h_CcNode;
+} t_CcNextEngineInfo;
+
+typedef struct {
+ uint16_t numOfKeys;
+ bool glblMaskUpdated;
+ t_Handle p_GlblMask;
+ bool lclMask;
+ uint8_t parseCode;
+ uint8_t offset;
+ uint8_t prsArrayOffset;
+ bool ctrlFlow;
+ uint8_t owners;
+
+ uint8_t ccKeySizeAccExtraction;
+ uint8_t sizeOfExtraction;
+ uint8_t glblMaskSize;
+
+ t_Handle h_KeysMatchTable;
+ t_Handle h_AdTable;
+
+ t_List ccPrevNodesLst;
+
+ t_List ccTreeIdLst;
+ t_List ccTreesLst;
+
+ t_Handle h_FmPcd;
+ uint32_t shadowAction;
+ bool modifiedState;
+ uint8_t userSizeOfExtraction;
+
+ t_FmPcdCcNextEngineAndRequiredActionParams nextEngineAndRequiredAction[256];
+} t_FmPcdCcNode;
+
+typedef struct {
+ t_FmPcdCcNode *p_FmPcdCcNode;
+ bool occupied;
+ uint8_t owners;
+ volatile bool lock;
+} t_FmPcdCcNodeArray;
+
+typedef struct {
+ uint8_t numOfEntriesInGroup;
+ uint32_t totalBitsMask;
+ uint8_t baseGroupEntry;
+} t_FmPcdCcGroupParam;
+
+typedef struct {
+ uint8_t netEnvId;
+ uintptr_t ccTreeBaseAddr;
+ uint8_t numOfGrps;
+ t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
+ t_List fmPortsLst;
+ volatile bool lock;
+ uint8_t numOfEntries;
+ uint8_t owners;
+ t_Handle *fmPcdCcSavedManipParams[256];
+ bool modifiedState;
+ uint32_t requiredAction;
+ t_FmPcdCcNextEngineAndRequiredActionParams nextEngineAndRequiredAction[FM_PCD_MAX_NUM_OF_KEYS];
+} t_FmPcdCcTree;
+
+typedef struct {
+ t_FmPcdCcTree *p_FmPcdCcTree;
+ bool occupied;
+ uint8_t owners;
+ volatile bool lock;
+} t_FmPcdCcTreeArray;
+
+
+bool FmPcdManipIsManipNode(t_Handle h_Ad);
+
+
+#endif /* __FM_CC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c
new file mode 100644
index 0000000..ca93ec5
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c
@@ -0,0 +1,3189 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_kg.c
+
+ @Description FM PCD ...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "debug_ext.h"
+#include "net_ext.h"
+#include "fm_port_ext.h"
+
+#include "fm_common.h"
+#include "fm_pcd.h"
+#include "fm_hc.h"
+
+#include "fm_pcd_ipc.h"
+
+
+static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t kgar)
+{
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgar, kgar);
+ /* Wait for GO to be idle and read error */
+ while ((kgar = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgar)) & FM_PCD_KG_KGAR_GO) ;
+ if (kgar & FM_PCD_KG_KGAR_ERR)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
+ return E_OK;
+}
+
+static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
+{
+ int i;
+
+ switch(code)
+ {
+ case( KG_SCH_GEN_PARSE_RESULT_N_FQID):
+ case( KG_SCH_GEN_DEFAULT):
+ case( KG_SCH_GEN_NEXTHDR):
+ for(i=0 ; i<numOfSwDefaults ; i++)
+ if(swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
+ return swDefaults[i].dfltSelect;
+ ASSERT_COND(FALSE);
+ case( KG_SCH_GEN_SHIM1):
+ case( KG_SCH_GEN_SHIM2):
+ case( KG_SCH_GEN_IP_PID_NO_V):
+ case( KG_SCH_GEN_ETH_NO_V):
+ case( KG_SCH_GEN_SNAP_NO_V):
+ case( KG_SCH_GEN_VLAN1_NO_V):
+ case( KG_SCH_GEN_VLAN2_NO_V):
+ case( KG_SCH_GEN_ETH_TYPE_NO_V):
+ case( KG_SCH_GEN_PPP_NO_V):
+ case( KG_SCH_GEN_MPLS1_NO_V):
+ case( KG_SCH_GEN_MPLS_LAST_NO_V):
+ case( KG_SCH_GEN_L3_NO_V):
+ case( KG_SCH_GEN_IP2_NO_V):
+ case( KG_SCH_GEN_GRE_NO_V):
+ case( KG_SCH_GEN_L4_NO_V):
+ for(i=0 ; i<numOfSwDefaults ; i++)
+ if(swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
+ return swDefaults[i].dfltSelect;
+
+ case( KG_SCH_GEN_START_OF_FRM):
+ case( KG_SCH_GEN_ETH):
+ case( KG_SCH_GEN_SNAP):
+ case( KG_SCH_GEN_VLAN1):
+ case( KG_SCH_GEN_VLAN2):
+ case( KG_SCH_GEN_ETH_TYPE):
+ case( KG_SCH_GEN_PPP):
+ case( KG_SCH_GEN_MPLS1):
+ case( KG_SCH_GEN_MPLS2):
+ case( KG_SCH_GEN_MPLS3):
+ case( KG_SCH_GEN_MPLS_LAST):
+ case( KG_SCH_GEN_IPV4):
+ case( KG_SCH_GEN_IPV6):
+ case( KG_SCH_GEN_IPV4_TUNNELED):
+ case( KG_SCH_GEN_IPV6_TUNNELED):
+ case( KG_SCH_GEN_MIN_ENCAP):
+ case( KG_SCH_GEN_GRE):
+ case( KG_SCH_GEN_TCP):
+ case( KG_SCH_GEN_UDP):
+ case( KG_SCH_GEN_IPSEC_AH):
+ case( KG_SCH_GEN_SCTP):
+ case( KG_SCH_GEN_DCCP):
+ case( KG_SCH_GEN_IPSEC_ESP):
+ for(i=0 ; i<numOfSwDefaults ; i++)
+ if(swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
+ return swDefaults[i].dfltSelect;
+ default:
+ return e_FM_PCD_KG_DFLT_ILLEGAL;
+ }
+}
+
+static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
+{
+ *p_Offset = 0;
+
+ switch(src)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_FRAME_START):
+ return KG_SCH_GEN_START_OF_FRM;
+ case(e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
+ return KG_SCH_GEN_DEFAULT;
+ case(e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
+ return KG_SCH_GEN_PARSE_RESULT_N_FQID;
+ case(e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
+ *p_Offset = 32;
+ return KG_SCH_GEN_PARSE_RESULT_N_FQID;
+ case(e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
+ return KG_SCH_GEN_NEXTHDR;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
+ return 0;
+ }
+}
+
+static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
+{
+ if(!ignoreProtocolValidation)
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ case(HEADER_TYPE_ETH):
+ return KG_SCH_GEN_ETH;
+ case(HEADER_TYPE_LLC_SNAP):
+ return KG_SCH_GEN_SNAP;
+ case(HEADER_TYPE_PPPoE):
+ return KG_SCH_GEN_PPP;
+ case(HEADER_TYPE_MPLS):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_GEN_MPLS1;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_GEN_MPLS2;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_3)
+ return KG_SCH_GEN_MPLS3;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ return KG_SCH_GEN_MPLS_LAST;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
+ return 0;
+ case(HEADER_TYPE_IPv4):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_GEN_IPV4;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_GEN_IPV4_TUNNELED;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
+ return 0;
+ case(HEADER_TYPE_IPv6):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_GEN_IPV6;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_GEN_IPV6_TUNNELED;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
+ return 0;
+ case(HEADER_TYPE_GRE):
+ return KG_SCH_GEN_GRE;
+ case(HEADER_TYPE_TCP):
+ return KG_SCH_GEN_TCP;
+ case(HEADER_TYPE_UDP):
+ return KG_SCH_GEN_UDP;
+ case(HEADER_TYPE_IPSEC_AH):
+ return KG_SCH_GEN_IPSEC_AH;
+ case(HEADER_TYPE_IPSEC_ESP):
+ return KG_SCH_GEN_IPSEC_ESP;
+ case(HEADER_TYPE_SCTP):
+ return KG_SCH_GEN_SCTP;
+ case(HEADER_TYPE_DCCP):
+ return KG_SCH_GEN_DCCP;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ else
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ case(HEADER_TYPE_ETH):
+ return KG_SCH_GEN_ETH_NO_V;
+ case(HEADER_TYPE_LLC_SNAP):
+ return KG_SCH_GEN_SNAP_NO_V;
+ case(HEADER_TYPE_PPPoE):
+ return KG_SCH_GEN_PPP_NO_V;
+ case(HEADER_TYPE_MPLS):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_GEN_MPLS1_NO_V;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ return KG_SCH_GEN_MPLS_LAST_NO_V;
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
+ else
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
+ return 0;
+ case(HEADER_TYPE_IPv4):
+ case(HEADER_TYPE_IPv6):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_GEN_L3_NO_V;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_GEN_IP2_NO_V;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
+ case(HEADER_TYPE_MINENCAP):
+ return KG_SCH_GEN_IP2_NO_V;
+ case(HEADER_TYPE_USER_DEFINED_L3):
+ return KG_SCH_GEN_L3_NO_V;
+ case(HEADER_TYPE_GRE):
+ return KG_SCH_GEN_GRE_NO_V;
+ case(HEADER_TYPE_TCP):
+ case(HEADER_TYPE_UDP):
+ case(HEADER_TYPE_IPSEC_AH):
+ case(HEADER_TYPE_IPSEC_ESP):
+ case(HEADER_TYPE_SCTP):
+ case(HEADER_TYPE_DCCP):
+ return KG_SCH_GEN_L4_NO_V;
+ case(HEADER_TYPE_USER_DEFINED_SHIM1):
+ return KG_SCH_GEN_SHIM1;
+ case(HEADER_TYPE_USER_DEFINED_SHIM2):
+ return KG_SCH_GEN_SHIM2;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+}
+static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
+{
+ if (!ignoreProtocolValidation)
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ return KG_SCH_GEN_ETH_TYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_GEN_VLAN1;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ return KG_SCH_GEN_VLAN2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
+ return 0;
+ }
+ case(HEADER_TYPE_MPLS):
+ case(HEADER_TYPE_IPSEC_AH):
+ case(HEADER_TYPE_IPSEC_ESP):
+ case(HEADER_TYPE_LLC_SNAP):
+ case(HEADER_TYPE_PPPoE):
+ case(HEADER_TYPE_IPv4):
+ case(HEADER_TYPE_IPv6):
+ case(HEADER_TYPE_GRE):
+ case(HEADER_TYPE_MINENCAP):
+ case(HEADER_TYPE_USER_DEFINED_L3):
+ case(HEADER_TYPE_TCP):
+ case(HEADER_TYPE_UDP):
+ case(HEADER_TYPE_SCTP):
+ case(HEADER_TYPE_DCCP):
+ case(HEADER_TYPE_USER_DEFINED_L4):
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
+ return 0;
+ }
+ else
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ return KG_SCH_GEN_ETH_TYPE_NO_V;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI) :
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_GEN_VLAN1_NO_V;
+ if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ return KG_SCH_GEN_VLAN2_NO_V;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
+ return 0;
+ }
+ case(HEADER_TYPE_IPv4):
+ switch(field.ipv4)
+ {
+ case(NET_HEADER_FIELD_IPv4_PROTO):
+ return KG_SCH_GEN_IP_PID_NO_V;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_IPv6):
+ switch(field.ipv6)
+ {
+ case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
+ return KG_SCH_GEN_IP_PID_NO_V;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_MPLS):
+ case(HEADER_TYPE_LLC_SNAP):
+ case(HEADER_TYPE_PPPoE):
+ case(HEADER_TYPE_GRE):
+ case(HEADER_TYPE_MINENCAP):
+ case(HEADER_TYPE_USER_DEFINED_L3):
+ case(HEADER_TYPE_TCP):
+ case(HEADER_TYPE_UDP):
+ case(HEADER_TYPE_IPSEC_AH):
+ case(HEADER_TYPE_IPSEC_ESP):
+ case(HEADER_TYPE_SCTP):
+ case(HEADER_TYPE_DCCP):
+ case(HEADER_TYPE_USER_DEFINED_L4):
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
+ return 0;
+ }
+}
+
+static t_KnownFieldsMasks GetKnownProtMask(e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
+{
+ switch(hdr)
+ {
+ case(HEADER_TYPE_NONE):
+ ASSERT_COND(FALSE);
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_DA):
+ return KG_SCH_KN_MACDST;
+ case(NET_HEADER_FIELD_ETH_SA):
+ return KG_SCH_KN_MACSRC;
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ return KG_SCH_KN_ETYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_LLC_SNAP):
+ switch(field.llcSnap)
+ {
+ case(NET_HEADER_FIELD_LLC_SNAP_TYPE):
+ return KG_SCH_KN_ETYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_TCI1;
+ if(index == e_FM_PCD_HDR_INDEX_LAST)
+ return KG_SCH_KN_TCI2;
+ else
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_MPLS):
+ switch(field.mpls)
+ {
+ case(NET_HEADER_FIELD_MPLS_LABEL_STACK):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_MPLS1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_MPLS2;
+ if(index == e_FM_PCD_HDR_INDEX_LAST)
+ return KG_SCH_KN_MPLS_LAST;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
+ return 0;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_IPv4):
+ switch(field.ipv4)
+ {
+ case(NET_HEADER_FIELD_IPv4_SRC_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_IPSRC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_IPSRC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return 0;
+ case(NET_HEADER_FIELD_IPv4_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_IPDST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_IPDST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return 0;
+ case(NET_HEADER_FIELD_IPv4_PROTO):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_PTYPE1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_PTYPE2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return 0;
+ case(NET_HEADER_FIELD_IPv4_TOS):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_IPTOS_TC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_IPTOS_TC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
+ return 0;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_IPv6):
+ switch(field.ipv6)
+ {
+ case(NET_HEADER_FIELD_IPv6_SRC_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_IPSRC1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_IPSRC2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return 0;
+ case(NET_HEADER_FIELD_IPv6_DST_IP):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_IPDST1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_IPDST2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return 0;
+ case(NET_HEADER_FIELD_IPv6_NEXT_HDR):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return KG_SCH_KN_PTYPE1;
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return KG_SCH_KN_PTYPE2;
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return 0;
+ case(NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
+ if((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
+ return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
+ if(index == e_FM_PCD_HDR_INDEX_2)
+ return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
+ return 0;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_GRE):
+ switch(field.gre)
+ {
+ case(NET_HEADER_FIELD_GRE_TYPE):
+ return KG_SCH_KN_GREPTYPE;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_MINENCAP):
+ switch(field.minencap)
+ {
+ case(NET_HEADER_FIELD_MINENCAP_SRC_IP):
+ return KG_SCH_KN_IPSRC2;
+ case(NET_HEADER_FIELD_MINENCAP_DST_IP):
+ return KG_SCH_KN_IPDST2;
+ case(NET_HEADER_FIELD_MINENCAP_TYPE):
+ return KG_SCH_KN_PTYPE2;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_TCP):
+ switch(field.tcp)
+ {
+ case(NET_HEADER_FIELD_TCP_PORT_SRC):
+ return KG_SCH_KN_L4PSRC;
+ case(NET_HEADER_FIELD_TCP_PORT_DST):
+ return KG_SCH_KN_L4PDST;
+ case(NET_HEADER_FIELD_TCP_FLAGS):
+ return KG_SCH_KN_TFLG;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_UDP):
+ switch(field.udp)
+ {
+ case(NET_HEADER_FIELD_UDP_PORT_SRC):
+ return KG_SCH_KN_L4PSRC;
+ case(NET_HEADER_FIELD_UDP_PORT_DST):
+ return KG_SCH_KN_L4PDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_IPSEC_AH):
+ switch(field.ipsecAh)
+ {
+ case(NET_HEADER_FIELD_IPSEC_AH_SPI):
+ return KG_SCH_KN_IPSEC_SPI;
+ case(NET_HEADER_FIELD_IPSEC_AH_NH):
+ return KG_SCH_KN_IPSEC_NH;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_IPSEC_ESP):
+ switch(field.ipsecEsp)
+ {
+ case(NET_HEADER_FIELD_IPSEC_ESP_SPI):
+ return KG_SCH_KN_IPSEC_SPI;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_SCTP):
+ switch(field.sctp)
+ {
+ case(NET_HEADER_FIELD_SCTP_PORT_SRC):
+ return KG_SCH_KN_L4PSRC;
+ case(NET_HEADER_FIELD_SCTP_PORT_DST):
+ return KG_SCH_KN_L4PDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_DCCP):
+ switch(field.dccp)
+ {
+ case(NET_HEADER_FIELD_DCCP_PORT_SRC):
+ return KG_SCH_KN_L4PSRC;
+ case(NET_HEADER_FIELD_DCCP_PORT_DST):
+ return KG_SCH_KN_L4PDST;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ case(HEADER_TYPE_PPPoE):
+ switch(field.pppoe)
+ {
+ case(NET_HEADER_FIELD_PPPoE_PID):
+ return KG_SCH_KN_PPPID;
+ case(NET_HEADER_FIELD_PPPoE_SID):
+ return KG_SCH_KN_PPPSID;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
+ return 0;
+ }
+}
+
+
+static uint8_t GetKnownFieldId(uint32_t bitMask)
+{
+ uint8_t cnt = 0;
+
+ while (bitMask)
+ if(bitMask & 0x80000000)
+ break;
+ else
+ {
+ cnt++;
+ bitMask <<= 1;
+ }
+ return cnt;
+
+}
+
+static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
+{
+ uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
+
+ /* bitOffset 1-7 --> mask 0x1-0x7F */
+ if(bitOffset<8)
+ {
+ mask = 0;
+ for(i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
+ mask |= walking1Mask;
+ }
+ else
+ {
+ mask = 0xFF;
+ numOfOnesToClear = 0;
+ if(fqid && bitOffset>24)
+ /* bitOffset 25-31 --> mask 0xFE-0x80 */
+ numOfOnesToClear = (uint8_t)(bitOffset-24);
+ else
+ /* bitOffset 9-15 --> mask 0xFE-0x80 */
+ if(!fqid && bitOffset>8)
+ numOfOnesToClear = (uint8_t)(bitOffset-8);
+ for(i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
+ mask &= ~walking1Mask;
+ /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
+ }
+ return mask;
+}
+
+
+t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
+ t_FmPcdIpcKgClsPlanParams kgAlloc;
+ t_Error err = E_OK;
+ uint32_t oredVectors = 0;
+ uint32_t intFlags;
+ int i, j;
+
+ if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
+
+ intFlags = FmPcdLock(p_FmPcd);
+
+ /* find a new clsPlan group */
+ for(i = 0;i<FM_MAX_NUM_OF_PORTS;i++)
+ if(!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
+ break;
+ if(i== FM_MAX_NUM_OF_PORTS)
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
+ }
+ p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
+ p_Grp->clsPlanGrpId = (uint8_t)i;
+
+ if(p_Grp->numOfOptions == 0)
+ p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
+
+ if (!TRY_LOCK(NULL, &p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return ERROR_CODE(E_BUSY);
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
+ p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
+ p_ClsPlanGrp->owners = 0;
+ FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
+ FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
+
+ p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1<<p_Grp->numOfOptions);
+ /* a minimal group of 8 is required */
+ if(p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
+ p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
+
+ if(err)
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+ }
+
+ }
+ else
+ {
+ t_FmPcdIpcMsg msg;
+ uint32_t replyLength;
+ t_FmPcdIpcReply reply;
+
+ /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ memset(&kgAlloc, 0, sizeof(kgAlloc));
+ kgAlloc.guestId = p_FmPcd->guestId;
+ kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
+ msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
+ replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(kgAlloc),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ }
+ if ((t_Error)reply.error != E_OK)
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock);
+ RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
+ }
+
+ p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
+ }
+
+ /* build classification plan entries parameters */
+ p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
+ p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
+
+ oredVectors = 0;
+ for(i = 0; i<p_Grp->numOfOptions; i++)
+ {
+ oredVectors |= p_Grp->optVectors[i];
+ /* save an array of used options - the indexes represent the power of 2 index */
+ p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
+ }
+ /* set the classification plan relevant entries so that all bits
+ * relevant to the list of options is cleared
+ */
+ for(j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
+ p_ClsPlanSet->vectors[j] = ~oredVectors;
+
+ for(i = 0; i<p_Grp->numOfOptions; i++)
+ {
+ /* option i got the place 2^i in the clsPlan array. all entries that
+ * have bit i set, should have the vector bit cleared. So each option
+ * has one location that it is exclusive (1,2,4,8...) and represent the
+ * presence of that option only, and other locations that represent a
+ * combination of options.
+ * e.g:
+ * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
+ * now represents a frame with ethernet-BC header - so the bit
+ * representing ethernet-BC should be set and all other option bits
+ * should be cleared.
+ * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
+ * vector[1] set, but they also have other bits set:
+ * 3=1+2, options 0 and 1
+ * 6=2+4, options 1 and 2
+ * 7=1+2+4, options 0,1,and 2
+ * 10=2+8, options 1 and 3
+ * etc.
+ * */
+
+ /* now for each option (i), we set their bits in all entries (j)
+ * that contain bit 2^i.
+ */
+ for(j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
+ {
+ if(j & (1<<i))
+ p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
+ }
+ }
+
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->clsPlanGrps[p_Grp->clsPlanGrpId].lock);
+
+ return E_OK;
+}
+
+void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdIpcKgClsPlanParams kgAlloc;
+ t_Error err;
+ t_FmPcdIpcMsg msg;
+ uint32_t replyLength;
+ t_FmPcdIpcReply reply;
+
+ /* check that no port is bound to this clsPlan */
+ if(p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
+ return;
+ }
+
+ FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
+
+ /* free blocks */
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ KgFreeClsPlanEntries(h_FmPcd,
+ p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
+ p_FmPcd->guestId,
+ p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
+ }
+ else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
+ {
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ kgAlloc.guestId = p_FmPcd->guestId;
+ kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
+ kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
+ msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(kgAlloc),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ {
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return;
+ }
+ if (replyLength != sizeof(uint32_t))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return;
+ }
+ if((t_Error)reply.error != E_OK)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
+ return;
+ }
+ }
+
+ if(grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
+ p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
+ /* clear clsPlan driver structure */
+ memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
+}
+
+t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t j, schemesPerPortVector = 0;
+ t_FmPcdKgScheme *p_Scheme;
+ uint8_t i, relativeSchemeId;
+ uint32_t tmp, walking1Mask;
+ uint8_t swPortIndex = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ /* for each scheme */
+ for(i = 0; i<p_BindPort->numOfSchemes; i++)
+ {
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
+ if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ if(add)
+ {
+ if (!FmPcdKgIsSchemeValidSw(h_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
+
+ p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
+ /* check netEnvId of the port against the scheme netEnvId */
+ if((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
+
+ /* if next engine is private port policer profile, we need to check that it is valid */
+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
+ if(p_Scheme->nextRelativePlcrProfile)
+ {
+ for(j = 0;j<p_Scheme->numOfProfiles;j++)
+ {
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
+ if(p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
+ if(!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
+ }
+ }
+ if(!p_BindPort->useClsPlan)
+ {
+ /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
+ cls plan options. Schemes that are used only directly, should not be checked.
+ it also may not be bound to schemes that go to CC with units that are options - so we OR
+ the match vector and the grpBits (= ccUnits) */
+ if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
+ {
+ walking1Mask = 0x80000000;
+ tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
+ tmp |= p_Scheme->ccUnits;
+ while (tmp)
+ {
+ if(tmp & walking1Mask)
+ {
+ tmp &= ~walking1Mask;
+ if(!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, p_Scheme->netEnvId, walking1Mask))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
+ }
+ walking1Mask >>= 1;
+ }
+ }
+ }
+ }
+ /* build vector */
+ schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
+ }
+
+ *p_SpReg = schemesPerPortVector;
+
+ return E_OK;
+}
+
+void FmPcdKgIncSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ int i;
+ t_FmPcdKgScheme *p_Scheme;
+
+ /* for each scheme - update owners counters */
+ for(i = 0; i<p_BindPort->numOfSchemes; i++)
+ {
+ p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[p_BindPort->schemesIds[i]];
+
+ /* increment owners number */
+ p_Scheme->owners++;
+ }
+}
+
+void FmPcdKgDecSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ int i;
+ t_FmPcdKgScheme *p_Scheme;
+
+ /* for each scheme - update owners counters */
+ for(i = 0; i<p_BindPort->numOfSchemes; i++)
+ {
+ p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[p_BindPort->schemesIds[i]];
+
+ /* increment owners number */
+ ASSERT_COND(p_Scheme->owners);
+ p_Scheme->owners--;
+ }
+}
+
+static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
+{
+ t_FmPcdKgPortConfigRegs *p_FmPcdKgPortRegs;
+ uint32_t tmpKgarReg = 0, tmpKgpeSp, intFlags;
+ t_Error err = E_OK;
+
+ if (p_FmPcd->h_Hc)
+ return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
+
+ p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs;
+
+ tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
+ intFlags = FmPcdLock(p_FmPcd);
+ err = WriteKgarWait(p_FmPcd, tmpKgarReg);
+ if(err)
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ tmpKgpeSp = GET_UINT32(p_FmPcdKgPortRegs->kgoe_sp);
+
+ if(add)
+ tmpKgpeSp |= spReg;
+ else /* clear */
+ tmpKgpeSp &= ~spReg;
+
+ WRITE_UINT32(p_FmPcdKgPortRegs->kgoe_sp, tmpKgpeSp);
+
+ tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
+
+ err = WriteKgarWait(p_FmPcd, tmpKgarReg);
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return err;
+}
+
+static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
+{
+ t_FmPcdKgPortConfigRegs *p_FmPcdKgPortRegs;
+ uint32_t tmpKgarReg, intFlags;
+ t_Error err;
+
+ if (p_FmPcd->h_Hc)
+ return FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
+
+ p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs;
+ intFlags = FmPcdLock(p_FmPcd);
+ WRITE_UINT32(p_FmPcdKgPortRegs->kgoe_cpp, cppReg);
+
+ tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
+ err = WriteKgarWait(p_FmPcd, tmpKgarReg);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return err;
+}
+
+static void FmPcdKgUnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
+{
+ KgWriteCpp(p_FmPcd, hardwarePortId, 0);
+}
+
+static t_Error KgBindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
+{
+ uint32_t tmpKgpeCpp = 0;
+
+ tmpKgpeCpp = FmPcdKgBuildCppReg(p_FmPcd, clsPlanGrpId);
+ return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
+}
+
+t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t spReg;
+ t_Error err = E_OK;
+
+ err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ FmPcdKgIncSchemeOwners(h_FmPcd, p_SchemeBind);
+
+ return E_OK;
+}
+
+t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t spReg;
+ t_Error err = E_OK;
+
+ err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ FmPcdKgDecSchemeOwners(h_FmPcd, p_SchemeBind);
+
+ return E_OK;
+}
+
+bool FmPcdKgIsSchemeValidSw(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].valid;
+}
+
+bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ if(p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t intFlags;
+ uint8_t i,j;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
+
+ intFlags = FmPcdLock(p_FmPcd);
+ for(j=0,i=0;i<FM_PCD_KG_NUM_OF_SCHEMES && j<numOfSchemes;i++)
+ {
+ if(!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
+ {
+ p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
+ p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
+ p_SchemesIds[j] = i;
+ j++;
+ }
+ }
+
+ if (j != numOfSchemes)
+ {
+ /* roll back */
+ for(j--; j; j--)
+ {
+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
+ p_SchemesIds[j] = 0;
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+}
+
+t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t intFlags;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
+
+ intFlags = FmPcdLock(p_FmPcd);
+
+ for(i=0;i<numOfSchemes;i++)
+ {
+ if(!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
+ }
+ if(p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
+ }
+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
+ }
+
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return E_OK;
+}
+
+t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t intFlags;
+ uint8_t numOfBlocks, blocksFound=0, first=0;
+ uint8_t i, j;
+
+ intFlags = FmPcdLock(p_FmPcd);
+
+ if(!numOfClsPlanEntries)
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return E_OK;
+ }
+
+ if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
+ }
+
+ numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
+
+ /* try to find consequent blocks */
+ first = 0;
+ for(i=0;i<FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
+ {
+ if(!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
+ {
+ blocksFound++;
+ i++;
+ if(blocksFound == numOfBlocks)
+ break;
+ }
+ else
+ {
+ blocksFound = 0;
+ /* advance i to the next aligned address */
+ first = i = (uint8_t)(first + numOfBlocks);
+ }
+ }
+
+ if(blocksFound == numOfBlocks)
+ {
+ *p_First = (uint8_t)(first*CLS_PLAN_NUM_PER_GRP);
+ for(j = first; j<first + numOfBlocks; j++)
+ {
+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+ }
+ else
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MINOR, E_FULL, ("No recources for clsPlan"));
+ }
+}
+
+void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t intFlags;
+ uint8_t numOfBlocks;
+ uint8_t i, baseBlock;
+
+ UNUSED( guestId);
+
+ intFlags = FmPcdLock(p_FmPcd);
+
+ numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
+ ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
+
+ baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
+ for(i=baseBlock;i<baseBlock+numOfBlocks;i++)
+ {
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
+ ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+}
+
+void KgEnable(t_FmPcd *p_FmPcd)
+{
+ t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ WRITE_UINT32(p_Regs->kggcr,GET_UINT32(p_Regs->kggcr) | FM_PCD_KG_KGGCR_EN);
+}
+
+void KgDisable(t_FmPcd *p_FmPcd)
+{
+ t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ WRITE_UINT32(p_Regs->kggcr,GET_UINT32(p_Regs->kggcr) & ~FM_PCD_KG_KGGCR_EN);
+}
+
+void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdKgClsPlanRegs *p_FmPcdKgPortRegs;
+ uint32_t tmpKgarReg=0, intFlags;
+ uint16_t i, j;
+
+ SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs;
+
+ intFlags = FmPcdLock(p_FmPcd);
+ for(i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
+ {
+ tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
+
+ for (j = i; j < i+8; j++)
+ {
+ ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
+ WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
+ }
+
+ if(WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
+ return;
+ }
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+}
+
+static void PcdKgErrorException(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint32_t event, force, schemeIndexes = 0,index = 0, mask = 0;
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ event = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeer);
+ mask = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer);
+
+ schemeIndexes = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseer);
+ schemeIndexes &= GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseeer);
+
+ event &= mask;
+
+ /* clear the forced events */
+ force = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer);
+ if(force & event)
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, force & ~event);
+
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeer, event);
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgseer, schemeIndexes);
+
+ if(event & FM_PCD_KG_DOUBLE_ECC)
+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
+ if(event & FM_PCD_KG_KEYSIZE_OVERFLOW)
+ {
+ if(schemeIndexes)
+ {
+ while(schemeIndexes)
+ {
+ if(schemeIndexes & 0x1)
+ p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
+ schemeIndexes >>= 1;
+ index+=1;
+ }
+ }
+ else /* this should happen only when interrupt is forced. */
+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
+ }
+}
+
+static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
+{
+ t_Error err = E_OK;
+ t_FmPcdIpcKgSchemesParams kgAlloc;
+ uint32_t replyLength;
+ t_FmPcdIpcReply reply;
+ t_FmPcdIpcMsg msg;
+
+ ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
+
+ /* in GUEST_PARTITION, we use the IPC */
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
+ kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
+ kgAlloc.guestId = p_FmPcd->guestId;
+ msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
+ replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(kgAlloc),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
+
+ return (t_Error)reply.error;
+}
+
+static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
+{
+ t_Error err = E_OK;
+ t_FmPcdKgRegs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
+ int i;
+ uint8_t hardwarePortId = 0;
+ uint32_t tmpReg;
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+
+ /**********************KGEER******************/
+ WRITE_UINT32(p_Regs->kgeer, (FM_PCD_KG_DOUBLE_ECC | FM_PCD_KG_KEYSIZE_OVERFLOW));
+ /**********************KGEER******************/
+
+ /**********************KGEEER******************/
+ tmpReg = 0;
+ if(p_FmPcd->exceptions & FM_PCD_EX_KG_DOUBLE_ECC)
+ {
+ FmEnableRamsEcc(p_FmPcd->h_Fm);
+ tmpReg |= FM_PCD_KG_DOUBLE_ECC;
+ }
+ if(p_FmPcd->exceptions & FM_PCD_EX_KG_KEYSIZE_OVERFLOW)
+ tmpReg |= FM_PCD_KG_KEYSIZE_OVERFLOW;
+ WRITE_UINT32(p_Regs->kgeeer,tmpReg);
+ /**********************KGEEER******************/
+
+ /**********************KGFDOR******************/
+ WRITE_UINT32(p_Regs->kgfdor,0);
+ /**********************KGFDOR******************/
+
+ /**********************KGGDV0R******************/
+ WRITE_UINT32(p_Regs->kggdv0r,0);
+ /**********************KGGDV0R******************/
+
+ /**********************KGGDV1R******************/
+ WRITE_UINT32(p_Regs->kggdv1r,0);
+ /**********************KGGDV1R******************/
+
+ /**********************KGGCR******************/
+ WRITE_UINT32(p_Regs->kggcr, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME);
+ /**********************KGGCR******************/
+
+ /* register even if no interrupts enabled, to allow future enablement */
+ FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR, PcdKgErrorException, p_FmPcd);
+
+ /* clear binding between ports to schemes so that all ports are not bound to any schemes */
+ for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
+ {
+ SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, i);
+
+ err = KgWriteSp(p_FmPcd, hardwarePortId, 0xffffffff, FALSE);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ err = KgWriteCpp(p_FmPcd, hardwarePortId, 0);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ /* enable and enable all scheme interrupts */
+ WRITE_UINT32(p_Regs->kgseer, 0xFFFFFFFF);
+ WRITE_UINT32(p_Regs->kgseeer, 0xFFFFFFFF);
+
+ if(p_FmPcd->p_FmPcdKg->numOfSchemes)
+ {
+ err = FmPcdKgAllocSchemes(p_FmPcd,
+ p_FmPcd->p_FmPcdKg->numOfSchemes,
+ p_FmPcd->guestId,
+ p_FmPcd->p_FmPcdKg->schemesIds);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ return E_OK;
+}
+
+
+/****************************************/
+/* API routines */
+/****************************************/
+t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdKgRegs *p_Regs;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
+
+ p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
+ if(!FmIsMaster(p_FmPcd->h_Fm))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
+
+/* not needed
+ if(payloadOffset > 256)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("data exatraction offset from parseing end can not be more than 256"));
+*/
+
+ WRITE_UINT32(p_Regs->kgfdor,payloadOffset);
+
+ return E_OK;
+}
+
+t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdKgRegs *p_Regs;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
+
+ p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
+
+ if(!FmIsMaster(p_FmPcd->h_Fm))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
+
+ if(valueId == 0)
+ WRITE_UINT32(p_Regs->kggdv0r,value);
+ else
+ WRITE_UINT32(p_Regs->kggdv1r,value);
+ return E_OK;
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ int i = 0, j = 0;
+ uint8_t hardwarePortId = 0;
+ uint32_t tmpKgarReg, intFlags;
+ t_Error err = E_OK;
+ t_FmPcdIpcMsg msg;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_KG_DUMP_REGS;
+ return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ }
+ DUMP_SUBTITLE(("\n"));
+ DUMP_TITLE(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, ("FmPcdKgRegs Regs"));
+
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggcr);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgeer);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgeeer);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgseer);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgseeer);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggsr);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgtpc);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgserc);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfdor);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggdv0r);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kggdv1r);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfer);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgfeer);
+ DUMP_VAR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs,kgar);
+
+ DUMP_SUBTITLE(("\n"));
+ intFlags = FmPcdLock(p_FmPcd);
+ for(j = 0;j<FM_PCD_KG_NUM_OF_SCHEMES;j++)
+ {
+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg((uint8_t)j);
+ if(WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs, ("FmPcdKgIndirectAccessSchemeRegs Scheme %d Regs", j));
+
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_mode);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ekfc);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ekdv);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_bmch);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_bmcl);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_fqb);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_hc);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ppc);
+
+ DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_gec, ("kgse_gec"));
+ DUMP_SUBSTRUCT_ARRAY(i, FM_PCD_KG_NUM_OF_GENERIC_REGS)
+ {
+ DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_gec[i], sizeof(uint32_t));
+ }
+
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_spc);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_dv0);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_dv1);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_ccbs);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs,kgse_mv);
+ }
+ DUMP_SUBTITLE(("\n"));
+
+ for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
+ {
+ SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, i);
+
+ tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
+
+ err = WriteKgarWait(p_FmPcd, tmpKgarReg);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, ("FmPcdKgIndirectAccessPortRegs PCD Port %d regs", hardwarePortId));
+
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, kgoe_sp);
+ DUMP_VAR(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.portRegs, kgoe_cpp);
+ }
+
+ DUMP_SUBTITLE(("\n"));
+ for(j=0;j<FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;j++)
+ {
+ DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs, ("FmPcdKgIndirectAccessClsPlanRegs Regs group %d", j));
+ DUMP_TITLE(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs.kgcpe, ("kgcpe"));
+
+ tmpKgarReg = FmPcdKgBuildReadClsPlanBlockActionReg((uint8_t)j);
+ err = WriteKgarWait(p_FmPcd, tmpKgarReg);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ DUMP_SUBSTRUCT_ARRAY(i, 8)
+ DUMP_MEMORY(&p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.clsPlanRegs.kgcpe[i], sizeof(uint32_t));
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
+{
+ t_FmPcdKg *p_FmPcdKg;
+
+ UNUSED(p_FmPcd);
+
+ if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,
+ ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
+ return NULL;
+ }
+
+ p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
+ if (!p_FmPcdKg)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
+ return NULL;
+ }
+ memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
+
+ if(FmIsMaster(p_FmPcd->h_Fm))
+ {
+ p_FmPcdKg->p_FmPcdKgRegs = (t_FmPcdKgRegs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
+ p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
+ }
+
+ p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
+ if((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
+ {
+ p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
+ DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
+ }
+
+ p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
+
+ return p_FmPcdKg;
+}
+
+t_Error KgInit(t_FmPcd *p_FmPcd)
+{
+ if (p_FmPcd->guestId == NCSW_MASTER_ID)
+ return KgInitMaster(p_FmPcd);
+ else
+ return KgInitGuest(p_FmPcd);
+}
+
+t_Error KgFree(t_FmPcd *p_FmPcd)
+{
+ t_FmPcdIpcKgSchemesParams kgAlloc;
+ t_Error err = E_OK;
+ t_FmPcdIpcMsg msg;
+ uint32_t replyLength;
+ t_FmPcdIpcReply reply;
+
+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
+
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ return FmPcdKgFreeSchemes(p_FmPcd,
+ p_FmPcd->p_FmPcdKg->numOfSchemes,
+ p_FmPcd->guestId,
+ p_FmPcd->p_FmPcdKg->schemesIds);
+
+ /* guest */
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
+ kgAlloc.guestId = p_FmPcd->guestId;
+ ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
+ memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds , (sizeof(uint8_t))*kgAlloc.numOfSchemes);
+ msg.msgId = FM_PCD_FREE_KG_SCHEMES;
+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(kgAlloc),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ return (t_Error)reply.error;
+}
+
+t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
+ t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
+ t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
+ t_Error err;
+
+ memset(&grpParams, 0, sizeof(grpParams));
+ grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
+ p_GrpParams = &grpParams;
+
+ p_GrpParams->netEnvId = netEnvId;
+ err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
+ if(err)
+ RETURN_ERROR(MINOR,err,NO_MSG);
+ if(p_GrpParams->grpExists)
+ *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
+ else
+ {
+ p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
+ if (!p_ClsPlanSet)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSet"));
+ memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
+ err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
+ if (err)
+ {
+ XX_Free(p_ClsPlanSet);
+ RETURN_ERROR(MINOR,err,NO_MSG);
+ }
+ *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
+
+ if (p_FmPcd->h_Hc)
+ {
+ /* write clsPlan entries to memory */
+ err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
+ if (err)
+ {
+ XX_Free(p_ClsPlanSet);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+ else
+ /* write clsPlan entries to memory */
+ KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
+
+ XX_Free(p_ClsPlanSet);
+ }
+
+ /* mark if this is an empty classification group */
+ if(*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
+ *p_IsEmptyClsPlanGrp = TRUE;
+ else
+ *p_IsEmptyClsPlanGrp = FALSE;
+
+ p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
+
+ /* increment owners number */
+ p_ClsPlanGrp->owners++;
+
+ /* copy options array for port */
+ memcpy(p_OptArray, &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId].optArray, FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)*sizeof(protocolOpt_t));
+
+ /* bind port to the new or existing group */
+ err = KgBindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ return E_OK;
+}
+
+t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
+ t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
+
+ FmPcdKgUnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
+
+ /* decrement owners number */
+ ASSERT_COND(p_ClsPlanGrp->owners);
+ p_ClsPlanGrp->owners--;
+
+ if(!p_ClsPlanGrp->owners)
+ {
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
+ else
+ {
+ /* clear clsPlan entries in memory */
+ p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
+ if (!p_ClsPlanSet)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("memory allocation failed for p_ClsPlanSet"));
+ memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
+ p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
+ p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
+ KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
+ XX_Free(p_ClsPlanSet);
+ FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
+ }
+ }
+ return E_OK;
+}
+
+t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t_FmPcdKgInterModuleSchemeRegs *p_SchemeRegs)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint32_t grpBits = 0;
+ uint8_t grpBase;
+ bool direct=TRUE, absolute=FALSE;
+ uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
+ t_Error err = E_OK;
+ int i = 0;
+ t_NetEnvParams netEnvParams;
+ uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
+ t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
+ uint8_t j, curr, idx;
+ uint8_t id, shift=0, code=0, offset=0, size=0;
+ t_FmPcdExtractEntry *p_Extract = NULL;
+ t_FmPcdKgExtractedOrParams *p_ExtractOr;
+ bool generic = FALSE;
+ t_KnownFieldsMasks bitMask;
+ e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
+ t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
+ uint8_t numOfSwDefaults = 0;
+ t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
+ uint8_t currGenId = 0, relativeSchemeId;
+
+ if(!p_Scheme->modify)
+ relativeSchemeId = p_Scheme->id.relativeSchemeId;
+ else
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1));
+
+ memset(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId], 0, sizeof(t_FmPcdKgScheme));
+ memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
+ memset(p_SchemeRegs, 0, sizeof(t_FmPcdKgInterModuleSchemeRegs));
+
+ if (p_Scheme->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
+
+ /* by netEnv parameters, get match vector */
+ if(!p_Scheme->alwaysDirect)
+ {
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId =
+ (uint8_t)(PTR_TO_UINT(p_Scheme->netEnvParams.h_NetEnv)-1);
+ netEnvParams.netEnvId = p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId;
+ netEnvParams.numOfDistinctionUnits = p_Scheme->netEnvParams.numOfDistinctionUnits;
+ memcpy(netEnvParams.unitIds, p_Scheme->netEnvParams.unitIds, (sizeof(uint8_t))*p_Scheme->netEnvParams.numOfDistinctionUnits);
+ err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector = netEnvParams.vector;
+ }
+ else
+ {
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector = SCHEME_ALWAYS_DIRECT;
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId = ILLEGAL_NETENV;
+ }
+
+ if(p_Scheme->nextEngine == e_FM_PCD_INVALID)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
+
+ if(p_Scheme->bypassFqidGeneration)
+ {
+#ifdef FM_KG_NO_BYPASS_FQID_GEN
+ {
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
+ }
+#endif /* FM_KG_NO_BYPASS_FQID_GEN */
+ if(p_Scheme->baseFqid)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
+ }
+ else
+ if(!p_Scheme->baseFqid)
+ DBG(WARNING, ("baseFqid is 0."));
+
+ if(p_Scheme->nextEngine == e_FM_PCD_PLCR)
+ {
+ direct = p_Scheme->kgNextEngineParams.plcrProfile.direct;
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr = direct;
+ absolute = (bool)(p_Scheme->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
+ if(!direct && absolute)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
+
+ if(direct)
+ {
+ profileId = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
+ numOfProfiles = 1;
+ }
+ else
+ {
+ profileId = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
+ shift = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
+ numOfProfiles = p_Scheme->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
+ }
+ }
+
+ if(p_Scheme->nextEngine == e_FM_PCD_CC)
+ {
+#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
+ if((p_Scheme->kgNextEngineParams.cc.plcrNext) && (p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
+ {
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
+ }
+#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
+
+ err = FmPcdCcGetGrpParams(p_Scheme->kgNextEngineParams.cc.h_CcTree,
+ p_Scheme->kgNextEngineParams.cc.grpId,
+ &grpBits,
+ &grpBase);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].ccUnits = grpBits;
+
+ if((p_Scheme->kgNextEngineParams.cc.plcrNext) &&
+ (!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
+ {
+ if(p_Scheme->kgNextEngineParams.cc.plcrProfile.sharedProfile)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
+ absolute = FALSE;
+ direct = p_Scheme->kgNextEngineParams.cc.plcrProfile.direct;
+ if(direct)
+ {
+ profileId = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
+ numOfProfiles = 1;
+ }
+ else
+ {
+ profileId = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
+ shift = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
+ numOfProfiles = p_Scheme->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
+ }
+ }
+ }
+
+ /* if policer is used directly after KG, or after CC */
+ if((p_Scheme->nextEngine == e_FM_PCD_PLCR) ||
+ ((p_Scheme->nextEngine == e_FM_PCD_CC) &&
+ (p_Scheme->kgNextEngineParams.cc.plcrNext) &&
+ (!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
+ {
+ /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
+ if(absolute)
+ {
+ /* for absolute direct policy only, */
+ relativeProfileId = profileId;
+ err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
+ if(err)
+ RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
+ if(!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId = profileId;
+ }
+ else
+ {
+ /* save relative profile id's for later check */
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile = TRUE;
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId = profileId;
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].numOfProfiles = numOfProfiles;
+ }
+ }
+ else
+ {
+ /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
+ is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
+ if(p_Scheme->bypassFqidGeneration && p_Scheme->numOfUsedExtractedOrs)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,
+ ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
+ if(p_Scheme->bypassFqidGeneration &&
+ p_Scheme->useHash &&
+ p_Scheme->keyExtractAndHashParams.hashDistributionNumOfFqids)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,
+ ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
+ }
+
+ /* configure all 21 scheme registers */
+ tmpReg = KG_SCH_MODE_EN;
+ switch(p_Scheme->nextEngine)
+ {
+ case(e_FM_PCD_PLCR):
+ /* add to mode register - NIA */
+ tmpReg |= KG_SCH_MODE_NIA_PLCR;
+ tmpReg |= NIA_ENG_PLCR;
+ tmpReg |= (uint32_t)(p_Scheme->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
+ /* initialize policer profile command - */
+ /* configure kgse_ppc */
+ if(direct)
+ /* use profileId as base, other fields are 0 */
+ p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
+ else
+ {
+ if(shift > MAX_PP_SHIFT)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
+
+ if(!numOfProfiles || !POWER_OF_2(numOfProfiles))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
+
+ ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
+ ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
+ ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
+ ppcTmp |= (uint32_t)profileId;
+
+ p_SchemeRegs->kgse_ppc = ppcTmp;
+ }
+ break;
+ case(e_FM_PCD_CC):
+ /* mode reg - define NIA */
+ tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
+
+ p_SchemeRegs->kgse_ccbs = grpBits;
+ tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
+
+ if(p_Scheme->kgNextEngineParams.cc.plcrNext)
+ {
+ if(!p_Scheme->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
+ {
+ /* find out if absolute or relative */
+ if(absolute)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("It is illegal to request a shared profile in a scheme that is in a KG->CC->PLCR flow"));
+ if(direct)
+ {
+ /* mask = 0, base = directProfileId */
+ p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
+ }
+ else
+ {
+ if(shift > MAX_PP_SHIFT)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
+ if(!numOfProfiles || !POWER_OF_2(numOfProfiles))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
+
+ ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
+ ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
+ ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
+ ppcTmp |= (uint32_t)profileId;
+
+ p_SchemeRegs->kgse_ppc = ppcTmp;
+ }
+ }
+ else
+ ppcTmp = KG_SCH_PP_NO_GEN;
+ }
+ break;
+ case(e_FM_PCD_DONE):
+ if(p_Scheme->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
+ tmpReg |= (NIA_ENG_BMI | NIA_BMI_AC_DISCARD);
+ else
+ tmpReg |= (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
+ }
+ p_SchemeRegs->kgse_mode = tmpReg;
+
+ p_SchemeRegs->kgse_mv = p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].matchVector;
+
+ if(p_Scheme->useHash)
+ {
+ p_KeyAndHash = &p_Scheme->keyExtractAndHashParams;
+
+ if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
+
+ /* configure kgse_dv0 */
+ p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
+
+ /* configure kgse_dv1 */
+ p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
+
+ if(!p_Scheme->bypassFqidGeneration)
+ {
+ if(!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
+ if((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_Scheme->baseFqid)
+ DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
+ }
+
+ /* configure kgse_ekdv */
+ tmpReg = 0;
+ for( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
+ {
+ switch(p_KeyAndHash->dflts[i].type)
+ {
+ case(e_FM_PCD_KG_MAC_ADDR):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
+ break;
+ case(e_FM_PCD_KG_TCI):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
+ break;
+ case(e_FM_PCD_KG_ENET_TYPE):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
+ break;
+ case(e_FM_PCD_KG_PPP_SESSION_ID):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
+ break;
+ case(e_FM_PCD_KG_PPP_PROTOCOL_ID):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
+ break;
+ case(e_FM_PCD_KG_MPLS_LABEL):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
+ break;
+ case(e_FM_PCD_KG_IP_ADDR):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
+ break;
+ case(e_FM_PCD_KG_PROTOCOL_TYPE):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
+ break;
+ case(e_FM_PCD_KG_IP_TOS_TC):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
+ break;
+ case(e_FM_PCD_KG_IPV6_FLOW_LABEL):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
+ break;
+ case(e_FM_PCD_KG_IPSEC_SPI):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
+ break;
+ case(e_FM_PCD_KG_L4_PORT):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
+ break;
+ case(e_FM_PCD_KG_TCP_FLAG):
+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
+ break;
+ case(e_FM_PCD_KG_GENERIC_FROM_DATA):
+ swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
+ swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
+ numOfSwDefaults ++;
+ break;
+ case(e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
+ swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
+ swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
+ numOfSwDefaults ++;
+ break;
+ case(e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
+ swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
+ swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
+ numOfSwDefaults ++;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ }
+ p_SchemeRegs->kgse_ekdv = tmpReg;
+
+ p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
+ if(!p_LocalExtractsArray)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+
+ /* configure kgse_ekfc and kgse_gec */
+ knownTmp = 0;
+ for( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
+ {
+ p_Extract = &p_KeyAndHash->extractArray[i];
+ switch(p_Extract->type)
+ {
+ case(e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
+ knownTmp |= KG_SCH_KN_PORT_ID;
+ /* save in driver structure */
+ p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
+ p_LocalExtractsArray->extractsArray[i].known = TRUE;
+ break;
+ case(e_FM_PCD_EXTRACT_BY_HDR):
+ switch(p_Extract->extractByHdr.hdr)
+ {
+ case(HEADER_TYPE_UDP_ENCAP_ESP):
+ switch(p_Extract->extractByHdr.type)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_HDR):
+ /* case where extraction from ESP only */
+ if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
+ {
+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
+ p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
+ }
+ else
+ {
+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
+ p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
+ }
+ break;
+ case(e_FM_PCD_EXTRACT_FROM_FIELD):
+ switch(p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
+ {
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
+ break;
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
+ p_Extract->extractByHdr.extractByHdrType.fromField.size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
+ /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
+ break;
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
+ p_Extract->extractByHdr.extractByHdrType.fromField.size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
+ p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
+ break;
+ }
+ break;
+ case(e_FM_PCD_EXTRACT_FULL_FIELD):
+ switch(p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
+ {
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
+ break;
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
+ p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
+ p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
+ break;
+ case(NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
+ p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
+ p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
+ break;
+ }
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ switch(p_Extract->extractByHdr.type)
+ {
+ case(e_FM_PCD_EXTRACT_FROM_HDR):
+ generic = TRUE;
+ /* get the header code for the generic extract */
+ code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
+ /* set generic register fields */
+ offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
+ size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
+ break;
+ case(e_FM_PCD_EXTRACT_FROM_FIELD):
+ generic = TRUE;
+ /* get the field code for the generic extract */
+ code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
+ p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
+ offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
+ size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
+ break;
+ case(e_FM_PCD_EXTRACT_FULL_FIELD):
+ if(!p_Extract->extractByHdr.ignoreProtocolValidation)
+ {
+ /* if we have a known field for it - use it, otherwise use generic */
+ bitMask = GetKnownProtMask(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
+ p_Extract->extractByHdr.extractByHdrType.fullField);
+ if(bitMask)
+ {
+ knownTmp |= bitMask;
+ /* save in driver structure */
+ p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
+ p_LocalExtractsArray->extractsArray[i].known = TRUE;
+ }
+ else
+ generic = TRUE;
+
+ }
+ else
+ generic = TRUE;
+ if(generic)
+ {
+ /* tmp - till we cover more headers under generic */
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
+ }
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ break;
+ case(e_FM_PCD_EXTRACT_NON_HDR):
+ /* use generic */
+ generic = TRUE;
+ offset = 0;
+ /* get the field code for the generic extract */
+ code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
+ offset += p_Extract->extractNonHdr.offset;
+ size = p_Extract->extractNonHdr.size;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ if(generic)
+ {
+ /* set generic register fields */
+ if(currGenId >= FM_PCD_KG_NUM_OF_GENERIC_REGS)
+ RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
+ if(!code)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
+
+ genTmp = KG_SCH_GEN_VALID;
+ genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
+ genTmp |= offset;
+ if((size > MAX_KG_SCH_SIZE) || (size < 1))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
+ genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
+ swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
+ if(swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
+ DBG(WARNING, ("No sw default configured"));
+
+ genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
+ genTmp |= KG_SCH_GEN_MASK;
+ p_SchemeRegs->kgse_gec[currGenId] = genTmp;
+ /* save in driver structure */
+ p_LocalExtractsArray->extractsArray[i].id = currGenId++;
+ p_LocalExtractsArray->extractsArray[i].known = FALSE;
+ generic = FALSE;
+ }
+ }
+ p_SchemeRegs->kgse_ekfc = knownTmp;
+
+ selectTmp = 0;
+ maskTmp = 0xFFFFFFFF;
+ /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
+
+ if(p_KeyAndHash->numOfUsedMasks >= FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
+ for( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
+ {
+ /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
+ id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
+ /* Get the shift of the select field (depending on i) */
+ GET_MASK_SEL_SHIFT(shift,i);
+ if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
+ selectTmp |= id << shift;
+ else
+ selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
+
+ /* Get the shift of the offset field (depending on i) - may
+ be in kgse_bmch or in kgse_fqb (depending on i) */
+ GET_MASK_OFFSET_SHIFT(shift,i);
+ if (i<=1)
+ selectTmp |= p_KeyAndHash->masks[i].offset << shift;
+ else
+ fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
+
+ /* Get the shift of the mask field (depending on i) */
+ GET_MASK_SHIFT(shift,i);
+ /* pass all bits */
+ maskTmp |= KG_SCH_BITMASK_MASK << shift;
+ /* clear bits that need masking */
+ maskTmp &= ~(0xFF << shift) ;
+ /* set mask bits */
+ maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
+ }
+ p_SchemeRegs->kgse_bmch = selectTmp;
+ p_SchemeRegs->kgse_bmcl = maskTmp;
+ /* kgse_fqb will be written t the end of the routine */
+
+ /* configure kgse_hc */
+ if(p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
+ if(p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
+
+ tmpReg = 0;
+
+ tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
+ tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
+
+ if(p_KeyAndHash->symmetricHash)
+ {
+ if((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
+ (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
+ (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
+ (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
+ tmpReg |= KG_SCH_HASH_CONFIG_SYM;
+ }
+ p_SchemeRegs->kgse_hc = tmpReg;
+
+ /* build the return array describing the order of the extractions */
+
+ /* the last currGenId places of the array
+ are for generic extracts that are always last.
+ We now sort for the calculation of the order of the known
+ extractions we sort the known extracts between orderedArray[0] and
+ orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
+ for the calculation of the order of the generic extractions we use:
+ num_of_generic - currGenId
+ num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
+ first_generic_index = num_of_known */
+ curr = 0;
+ for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
+ {
+ if(p_LocalExtractsArray->extractsArray[i].known)
+ {
+ ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
+ j = curr;
+ /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
+ index in the user's extractions array */
+ /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
+ location */
+ while((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
+ p_LocalExtractsArray->extractsArray[p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j-1]].id))
+ {
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j] =
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j-1];
+ j--;
+ }
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[j] = (uint8_t)i;
+ curr++;
+ }
+ else
+ {
+ /* index is first_generic_index + generic index (id) */
+ idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
+ ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].orderedArray[idx]= (uint8_t)i;
+ }
+ }
+ XX_Free(p_LocalExtractsArray);
+ p_LocalExtractsArray = NULL;
+
+ }
+ else
+ {
+ /* clear all unused registers: */
+ p_SchemeRegs->kgse_ekfc = 0;
+ p_SchemeRegs->kgse_ekdv = 0;
+ p_SchemeRegs->kgse_bmch = 0;
+ p_SchemeRegs->kgse_bmcl = 0;
+ p_SchemeRegs->kgse_hc = 0;
+ p_SchemeRegs->kgse_dv0 = 0;
+ p_SchemeRegs->kgse_dv1 = 0;
+ }
+
+ if(p_Scheme->bypassFqidGeneration)
+ p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
+
+ /* configure kgse_spc */
+ if( p_Scheme->schemeCounter.update)
+ p_SchemeRegs->kgse_spc = p_Scheme->schemeCounter.value;
+
+
+ /* check that are enough generic registers */
+ if(p_Scheme->numOfUsedExtractedOrs + currGenId > FM_PCD_KG_NUM_OF_GENERIC_REGS)
+ RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
+
+ /* extracted OR mask on Qid */
+ for( i=0 ;i<p_Scheme->numOfUsedExtractedOrs ; i++)
+ {
+
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs = TRUE;
+ /* configure kgse_gec[i] */
+ p_ExtractOr = &p_Scheme->extractedOrs[i];
+ switch(p_ExtractOr->type)
+ {
+ case(e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
+ code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
+ offset = 0;
+ break;
+ case(e_FM_PCD_EXTRACT_BY_HDR):
+ /* get the header code for the generic extract */
+ code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
+ /* set generic register fields */
+ offset = p_ExtractOr->extractionOffset;
+ break;
+ case(e_FM_PCD_EXTRACT_NON_HDR):
+ /* get the field code for the generic extract */
+ offset = 0;
+ code = GetGenCode(p_ExtractOr->src, &offset);
+ offset += p_ExtractOr->extractionOffset;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ /* set generic register fields */
+ if(!code)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
+ genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
+ genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
+ genTmp |= offset;
+ if(!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
+
+ /************************************************************************************
+ bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
+ in the following way:
+
+ Driver API and implementation:
+ ==============================
+ FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
+ if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
+ are not overlapping FQID.
+ ------------------------
+ | FQID (24) |
+ ------------------------
+ --------
+ | | extracted OR byte
+ --------
+
+ Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
+ PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
+ are not overlapping PP id.
+
+ --------
+ | PP (8) |
+ --------
+ --------
+ | | extracted OR byte
+ --------
+
+ HW implementation
+ =================
+ FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
+ as the highest byte of that word and may be rotated to effect any part os the FQID or
+ the PP.
+ ------------------------ --------
+ | FQID (24) || PP (8) |
+ ------------------------ --------
+ --------
+ | | extracted OR byte
+ --------
+
+ ************************************************************************************/
+
+ if(p_ExtractOr->bitOffsetInFqid)
+ {
+ if(p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
+ if(p_ExtractOr->bitOffsetInFqid<8)
+ genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
+ else
+ genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
+ p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
+ }
+ else /* effect policer profile */
+ {
+ if(p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
+ genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
+ p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
+ }
+
+ genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
+ /* clear bits that need masking */
+ genTmp &= ~KG_SCH_GEN_MASK ;
+ /* set mask bits */
+ genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
+ p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
+
+ }
+ /* clear all unused GEC registers */
+ for( i=currGenId ;i<FM_PCD_KG_NUM_OF_GENERIC_REGS ; i++)
+ p_SchemeRegs->kgse_gec[i] = 0;
+
+ /* add base Qid for this scheme */
+ /* add configuration for kgse_fqb */
+ if(p_Scheme->baseFqid & ~0x00FFFFFF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
+
+ fqbTmp |= p_Scheme->baseFqid;
+ p_SchemeRegs->kgse_fqb = fqbTmp;
+
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine = p_Scheme->nextEngine;
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction = p_Scheme->kgNextEngineParams.doneAction;
+ return E_OK;
+}
+
+void FmPcdKgValidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(!p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ if(p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId != ILLEGAL_NETENV)
+ FmPcdIncNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId);
+ p_FmPcd->p_FmPcdKg->schemes[schemeId].valid = TRUE;
+}
+
+void FmPcdKgInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId)
+{
+
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ if(p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId != ILLEGAL_NETENV)
+ FmPcdDecNetEnvOwners(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[schemeId].netEnvId);
+ p_FmPcd->p_FmPcdKg->schemes[schemeId].valid = FALSE;
+}
+
+uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
+}
+
+uint32_t FmPcdKgGetPointedOwners(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners;
+}
+
+bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
+}
+
+
+uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
+}
+
+
+bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ if((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
+ p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
+ p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
+ return TRUE;
+ else
+ return FALSE;
+
+}
+void FmPcdKgUpatePointedOwner(t_Handle h_FmPcd, uint8_t schemeId, bool add)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ if(add)
+ p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners++;
+ else
+ p_FmPcd->p_FmPcdKg->schemes[schemeId].pointedOwners--;
+}
+
+e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].nextEngine;
+}
+
+e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
+}
+
+void FmPcdKgUpdateRequiredAction(t_Handle h_FmPcd, uint8_t schemeId, uint32_t requiredAction)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
+
+ p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction = requiredAction;
+}
+
+t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ if(schemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ /* check that no port is bound to this scheme */
+ if(p_FmPcd->p_FmPcdKg->schemes[schemeId].owners)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
+ if(!p_FmPcd->p_FmPcdKg->schemes[schemeId].valid)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete an invalid scheme"));
+ return E_OK;
+}
+
+uint32_t FmPcdKgBuildCppReg(t_Handle h_FmPcd, uint8_t clsPlanGrpId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t tmpKgpeCpp;
+
+ tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
+ tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_PCD_KG_PE_CPP_MASK_SHIFT);
+ return tmpKgpeCpp;
+}
+
+bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
+{
+
+ if(schemeModeReg & KG_SCH_MODE_EN)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
+{
+ return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT)|
+ FM_PCD_KG_KGAR_GO |
+ FM_PCD_KG_KGAR_WRITE |
+ FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY |
+ DUMMY_PORT_ID |
+ (updateCounter ? FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT:0));
+
+}
+
+uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
+{
+ return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT)|
+ FM_PCD_KG_KGAR_GO |
+ FM_PCD_KG_KGAR_READ |
+ FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY |
+ DUMMY_PORT_ID |
+ FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT);
+
+}
+
+
+uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
+{
+ return (uint32_t)(FM_PCD_KG_KGAR_GO |
+ FM_PCD_KG_KGAR_WRITE |
+ FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
+ DUMMY_PORT_ID |
+ ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
+ FM_PCD_KG_KGAR_WSEL_MASK);
+
+
+ /* if we ever want to write 1 by 1, use:
+ sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));*/
+}
+
+uint32_t FmPcdKgBuildReadClsPlanBlockActionReg(uint8_t grpId)
+{
+ return (uint32_t)(FM_PCD_KG_KGAR_GO |
+ FM_PCD_KG_KGAR_READ |
+ FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
+ DUMMY_PORT_ID |
+ ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
+ FM_PCD_KG_KGAR_WSEL_MASK);
+
+
+ /* if we ever want to write 1 by 1, use:
+ sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));*/
+}
+
+uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
+{
+
+ return (uint32_t)(FM_PCD_KG_KGAR_GO |
+ FM_PCD_KG_KGAR_WRITE |
+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
+ hardwarePortId |
+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
+}
+
+uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
+{
+
+ return (uint32_t)(FM_PCD_KG_KGAR_GO |
+ FM_PCD_KG_KGAR_READ |
+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
+ hardwarePortId |
+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
+}
+uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
+{
+
+ return (uint32_t)(FM_PCD_KG_KGAR_GO |
+ FM_PCD_KG_KGAR_WRITE |
+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
+ hardwarePortId |
+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
+}
+
+uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
+}
+
+uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
+}
+
+uint8_t FmPcdKgGetSchemeSwId(t_Handle h_FmPcd, uint8_t schemeHwId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint8_t i;
+
+ for(i=0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
+ if(p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeHwId)
+ return i;
+ ASSERT_COND(i!=p_FmPcd->p_FmPcdKg->numOfSchemes);
+ return FM_PCD_KG_NUM_OF_SCHEMES;
+}
+
+uint8_t FmPcdKgGetNumOfPartitionSchemes(t_Handle h_FmPcd)
+{
+ return ((t_FmPcd*)h_FmPcd)->p_FmPcdKg->numOfSchemes;
+}
+
+uint8_t FmPcdKgGetPhysicalSchemeId(t_Handle h_FmPcd, uint8_t relativeSchemeId)
+{
+ return ((t_FmPcd*)h_FmPcd)->p_FmPcdKg->schemesIds[relativeSchemeId];
+}
+
+uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint8_t i;
+
+ for(i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
+ if(p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
+ return i;
+
+ if(i == p_FmPcd->p_FmPcdKg->numOfSchemes)
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
+
+ return FM_PCD_KG_NUM_OF_SCHEMES;
+}
+
+t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint8_t relativeSchemeId, physicalSchemeId;
+ uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction);
+
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
+ if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ if (FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Lock of the scheme FAILED"));
+
+ if(!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].pointedOwners ||
+ !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
+ {
+ if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
+ {
+ switch(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
+ {
+ case(e_FM_PCD_DONE):
+ if(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
+ {
+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ intFlags = FmPcdLock(p_FmPcd);
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
+ }
+ tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode);
+ ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
+ /* call indirect command for scheme write */
+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ FmPcdUnlock(p_FmPcd, intFlags);
+ }
+ break;
+ case(e_FM_PCD_PLCR):
+ if(!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
+ (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
+ }
+ err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
+ if(err)
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
+ }
+ }
+ }
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].pointedOwners += 1;
+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction |= requiredAction;
+
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+ return E_OK;
+}
+
+t_Error FmPcdKgSchemeTryLock(t_Handle h_FmPcd, uint8_t schemeId, bool intr)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ bool ans;
+
+ if (intr)
+ ans = TRY_LOCK(NULL, &p_FmPcd->p_FmPcdKg->schemes[schemeId].lock);
+ else
+ ans = TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->p_FmPcdKg->schemes[schemeId].lock);
+ if (ans)
+ return E_OK;
+ return ERROR_CODE(E_BUSY);
+}
+
+void FmPcdKgReleaseSchemeLock(t_Handle h_FmPcd, uint8_t schemeId)
+{
+ RELEASE_LOCK(((t_FmPcd*)h_FmPcd)->p_FmPcdKg->schemes[schemeId].lock);
+}
+
+t_Handle FM_PCD_KgSetScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t tmpReg;
+ t_FmPcdKgInterModuleSchemeRegs schemeRegs;
+ t_FmPcdKgInterModuleSchemeRegs *p_MemRegs;
+ uint8_t i;
+ t_Error err = E_OK;
+ uint32_t tmpKgarReg;
+ uint32_t intFlags;
+ uint8_t physicalSchemeId, relativeSchemeId;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdKgSetScheme(p_FmPcd->h_Hc, p_Scheme);
+
+ /* if not called for modification, check first that this scheme is unused */
+ if(!p_Scheme->modify)
+ {
+ /* check that schemeId is in range */
+ if(p_Scheme->id.relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
+ {
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of range"));
+ return NULL;
+ }
+ relativeSchemeId = p_Scheme->id.relativeSchemeId;
+
+ if (FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE))
+ return NULL;
+
+ physicalSchemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
+
+ /* read specified scheme into scheme registers */
+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ intFlags = FmPcdLock(p_FmPcd);
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ if (tmpReg & KG_SCH_MODE_EN)
+ {
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
+ ("Scheme %d(phys %d) is already used", relativeSchemeId, physicalSchemeId));
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+ return NULL;
+ }
+ }
+ else
+ {
+ SANITY_CHECK_RETURN_VALUE(p_Scheme->id.h_Scheme, E_INVALID_HANDLE, NULL);
+
+ intFlags = FmPcdLock(p_FmPcd);
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_Scheme->id.h_Scheme)-1);
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
+
+ /* check that schemeId is in range */
+ if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
+ {
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return NULL;
+ }
+
+ err = FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, TRUE);
+ FmPcdUnlock(p_FmPcd, intFlags);
+ if (err)
+ return NULL;
+ }
+
+ err = FmPcdKgBuildScheme(h_FmPcd, p_Scheme, &schemeRegs);
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ FmPcdKgInvalidateSchemeSw(h_FmPcd, relativeSchemeId);
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+ return NULL;
+ }
+
+ /* configure all 21 scheme registers */
+ p_MemRegs = &p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs;
+ intFlags = FmPcdLock(p_FmPcd);
+ WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
+ WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
+ WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
+ WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
+ WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
+ WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
+ WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
+ WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
+ WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
+ WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
+ WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
+ WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
+ WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
+ for(i=0 ; i<FM_PCD_KG_NUM_OF_GENERIC_REGS ; i++)
+ WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
+
+ /* call indirect command for scheme write */
+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_Scheme->schemeCounter.update);
+
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ FmPcdKgValidateSchemeSw(h_FmPcd, relativeSchemeId);
+
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+
+ return UINT_TO_PTR((uint64_t)physicalSchemeId+1);
+}
+
+t_Error FM_PCD_KgDeleteScheme(t_Handle h_FmPcd, t_Handle h_Scheme)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint8_t physicalSchemeId;
+ uint32_t tmpKgarReg, intFlags;
+ t_Error err = E_OK;
+ uint8_t relativeSchemeId;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
+
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
+
+ if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ if ((err = FmPcdKgSchemeTryLock(p_FmPcd, relativeSchemeId, FALSE)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ /* check that no port is bound to this scheme */
+ err = FmPcdKgCheckInvalidateSchemeSw(h_FmPcd, relativeSchemeId);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ intFlags = FmPcdLock(p_FmPcd);
+ /* clear mode register, including enable bit */
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode, 0);
+
+ /* call indirect command for scheme write */
+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
+
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ FmPcdKgInvalidateSchemeSw(h_FmPcd, relativeSchemeId);
+
+ RELEASE_LOCK(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].lock);
+
+ return E_OK;
+}
+
+uint32_t FM_PCD_KgGetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t tmpKgarReg, spc, intFlags;
+ uint8_t physicalSchemeId;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
+
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+
+ if(FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ intFlags = FmPcdLock(p_FmPcd);
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
+ spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_spc);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return spc;
+}
+
+t_Error FM_PCD_KgSetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t value)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t tmpKgarReg, intFlags;
+ uint8_t physicalSchemeId;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
+
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(h_Scheme)-1);
+ /* check that schemeId is in range */
+ if(FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+
+ /* read specified scheme into scheme registers */
+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
+ intFlags = FmPcdLock(p_FmPcd);
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
+ }
+
+ /* change counter value */
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->indirectAccessRegs.schemeRegs.kgse_spc, value);
+
+ /* call indirect command for scheme write */
+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
+
+ WriteKgarWait(p_FmPcd, tmpKgarReg);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+}
+
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c
new file mode 100644
index 0000000..0d176e8
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c
@@ -0,0 +1,2637 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_manip.c
+
+ @Description FM PCD manip ...
+*//***************************************************************************/
+#ifdef CONFIG_FMAN_P1023
+#ifdef FM_CAPWAP_SUPPORT
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "debug_ext.h"
+#include "fm_pcd_ext.h"
+#include "fm_muram_ext.h"
+#include "memcpy_ext.h"
+
+#include "fm_common.h"
+#include "fm_hc.h"
+#include "fm_manip.h"
+
+
+#ifdef CORE_8BIT_ACCESS_ERRATA
+#undef WRITE_UINT16
+#undef GET_UINT16
+#undef WRITE_UINT8
+#undef GET_UINT8
+
+#define WRITE_UINT16(addr, val) \
+ do{ \
+ if((int)&(addr) % 4) \
+ WRITE_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L), \
+ ((GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L)) & 0xffff0000) | (uint32_t)val)); \
+ else \
+ WRITE_UINT32(*(uint32_t*)&addr, \
+ ((GET_UINT32(*(uint32_t*)&addr) & 0x0000ffff) | (uint32_t)val<<16)); \
+ }while(0);
+#define GET_UINT16(addr) (((uint32_t)&addr%4) ? \
+ ((uint16_t)GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L))): \
+ ((uint16_t)(GET_UINT32(*(uint32_t*)(uint32_t)&addr) >> 16)))
+
+#define WRITE_UINT8(addr,val) WRITE_UINT8_ERRATA(&addr,val)
+#define GET_UINT8(addr) GET_UINT8_ERRATA(&addr)
+#endif /* CORE_8BIT_ACCESS_ERRATA */
+
+
+static void WRITE_UINT8_ERRATA(uint8_t *addr, uint8_t val)
+{
+ uint32_t newAddr, newVal;
+ newAddr = (uint32_t)addr & ~0x3L;
+ switch ((uint32_t)addr%4)
+ {
+ case (0):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x00ffffff) | (((uint32_t)val)<<24);
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ case (1):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xff00ffff) | (((uint32_t)val)<<16);
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ case (2):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xffff00ff) | (((uint32_t)val)<<8);
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ case (3):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xffffff00) | val;
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ }
+}
+
+static uint8_t GET_UINT8_ERRATA(uint8_t *addr)
+{
+ uint32_t newAddr, newVal=0;
+ newAddr = (uint32_t)addr & ~0x3L;
+ switch ((uint32_t)addr%4)
+ {
+ case (0):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xff000000)>>24;
+ break;
+ case (1):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x00ff0000)>>16;
+ break;
+ case (2):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x0000ff00)>>8;
+ break;
+ case (3):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x000000ff);
+ break;
+ }
+
+ return (uint8_t)newVal;
+}
+
+static t_Error GetPrOffsetByNonHeader(uint8_t *parseArrayOffset)
+{
+ /*For now - the only field in the Parse Array from the NON_BY_TYPE can be e_FM_PCD_KG_EXTRACT_FROM_CURR_END_OF_PARSE*/
+ /*Maybe extended in the future*/
+
+ *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
+
+ return E_OK;
+}
+
+static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
+{
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
+ t_Handle p_Ad;
+ uint32_t tmpReg32 = 0;
+ SANITY_CHECK_RETURN_ERROR(h_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ if(p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
+ {
+ tmpReg32 = *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
+ tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
+ *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets = tmpReg32;
+ p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
+ p_Manip->icOffset = icOffset;
+ }
+ else
+ {
+ if(p_Manip->icOffset != icOffset)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
+ }
+ break;
+#ifdef FM_CAPWAP_SUPPORT
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+ if(p_Manip->h_Frag)
+ {
+ if(p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
+ {
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
+ tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
+ p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
+ p_Manip->icOffset = icOffset;
+ }
+ else
+ {
+ if(p_Manip->icOffset != icOffset)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
+ }
+ }
+ break;
+#endif /* FM_CAPWAP_SUPPORT */
+ }
+
+ return E_OK;
+}
+
+static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
+{
+
+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
+ t_FmPortGetSetCcParams fmPortGetSetCcParams;
+ t_Error err;
+ uint32_t tmpReg32;
+
+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((p_Manip->type & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX), E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
+
+ if(p_Manip->updateParams)
+ {
+ if((!(p_Manip->updateParams & OFFSET_OF_PR)) ||
+ (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
+
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
+ fmPortGetSetCcParams.setCcParams.psoSize = 16;
+
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Parser result offset wasn't configured previousely"));
+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
+ ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
+#endif
+ }
+ else if (validate)
+ {
+ if((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) ||
+ (p_Manip->updateParams & OFFSET_OF_PR))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
+ fmPortGetSetCcParams.setCcParams.psoSize = 16;
+
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Parser result offset wasn't configured previousely"));
+
+ }
+
+ if(p_Manip->updateParams & OFFSET_OF_PR)
+ {
+ tmpReg32 = 0;
+ tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
+ WRITE_UINT32(p_Ad->matchTblPtr, (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
+ p_Manip->updateParams &= ~OFFSET_OF_PR;
+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
+ }
+ else if (validate)
+ {
+ tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
+ if((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"););
+ }
+
+ return E_OK;
+}
+
+#ifdef FM_CAPWAP_SUPPORT
+static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
+{
+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
+ t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(((p_Manip->type == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->type == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
+
+ if(p_Manip->updateParams)
+ {
+
+ if((!(p_Manip->updateParams & OFFSET_OF_DATA) &&
+ !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)) ||
+ ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
+ p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree, e_FM_MANIP_CAPWAP_INDX);
+ if(!p_SavedManipParams)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
+ p_Manip->fragParams.poolId = p_SavedManipParams->capwapParams.poolId;
+ p_Manip->fragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
+
+ tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
+ tmpReg32 |= ((uint32_t)p_Manip->fragParams.poolId << 8);
+ tmpReg32 |= ((uint32_t)p_Manip->fragParams.dataOffset<< 16);
+ WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
+
+ p_Manip->updateParams &= ~OFFSET_OF_DATA;
+ p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP;
+ p_Manip->shadowUpdateParams |= (OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP);
+ }
+ else if (validate)
+ {
+
+ p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree, e_FM_MANIP_CAPWAP_INDX);
+ if(!p_SavedManipParams)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
+ if((p_Manip->fragParams.poolId != p_SavedManipParams->capwapParams.poolId) ||
+ (p_Manip->fragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
+ }
+
+ return E_OK;
+}
+
+static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate, t_Handle h_FmTree)
+{
+ t_AdOfTypeContLookup *p_Ad;
+ t_FmPortGetSetCcParams fmPortGetSetCcParams;
+ t_Error err;
+ uint32_t tmpReg32 = 0;
+ t_FmPcdCcSavedManipParams *p_SavedManipParams;
+
+ UNUSED(h_Ad);
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(((p_Manip->type == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->type == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
+
+ if(p_Manip->updateParams)
+ {
+ if((!(p_Manip->updateParams & OFFSET_OF_DATA) &&
+ !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)) ||
+ ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
+ fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool doe header manipulation wasn't configured previousely"));
+
+ p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
+ p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
+ p_SavedManipParams->capwapParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip;
+
+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
+ ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
+#endif
+
+ FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams, e_FM_MANIP_CAPWAP_INDX);
+ }
+ else if (validate)
+ {
+ if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
+ !(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)) ||
+ ((p_Manip->updateParams & OFFSET_OF_DATA) ||
+ (p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
+ fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool doe header manipulation wasn't configured previousely"));
+ }
+
+ if(p_Manip->updateParams)
+ {
+ tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
+ tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.poolIdForManip << 8);
+ tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
+ WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
+
+ p_Manip->updateParams &= ~OFFSET_OF_DATA;
+ p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP;
+ p_Manip->shadowUpdateParams |= (OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP);
+ p_Manip->fragParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip;
+ p_Manip->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
+ }
+ else if (validate)
+ {
+ if((p_Manip->fragParams.poolId != fmPortGetSetCcParams.getCcParams.poolIdForManip) ||
+ (p_Manip->fragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
+ }
+
+ return E_OK;
+}
+
+static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
+ t_Handle h_FmPort,
+ t_FmPcdManip *p_Manip,
+ t_Handle h_Ad,
+ bool validate)
+{
+ t_CapwapReasmPram *p_ReassmTbl;
+ t_Error err;
+ t_FmPortGetSetCcParams fmPortGetSetCcParams;
+ uint8_t i = 0;
+ uint16_t size;
+ uint32_t tmpReg32;
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((p_Manip->type == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
+
+ if(p_Manip->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("handler of PCD previously was initiated by different value"));
+
+ UNUSED(h_Ad);
+
+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
+ p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
+
+ if(p_Manip->updateParams)
+ {
+ if((!(p_Manip->updateParams & NUM_OF_TASKS) && !(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP) &&
+ !(p_Manip->updateParams & OFFSET_OF_DATA) && !(p_Manip->updateParams & OFFSET_OF_PR) &&
+ !(p_Manip->updateParams & HW_PORT_ID)) ||
+ ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) ||
+ (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR)
+ ||(p_Manip->shadowUpdateParams & HW_PORT_ID)))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
+
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
+ fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("buffser pool id wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
+ ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
+#endif
+ }
+ else if (validate)
+ {
+ if((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && (!(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP)) &&
+ (!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) && (!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) &&
+ (!(p_Manip->shadowUpdateParams & HW_PORT_ID))) &&
+ ((p_Manip->updateParams & NUM_OF_TASKS) ||
+ (p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP) ||
+ (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR)||
+ (p_Manip->updateParams & HW_PORT_ID)))
+
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
+ fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Buffer pool for header manipulation wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
+ }
+
+ if(p_Manip->updateParams)
+ {
+ if(p_Manip->updateParams & NUM_OF_TASKS)
+ {
+ size = (uint16_t)(p_Manip->fragParams.maxNumFramesInProcess + fmPortGetSetCcParams.getCcParams.numOfTasks);
+ if(size > 255)
+ RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
+
+ p_Manip->fragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
+
+ /*p_ReassmFrmDescrIndxPoolTbl*/
+ p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ (uint32_t)(size + 1),
+ 4);
+ if(!p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
+
+ for( i = 0; i < size; i++)
+ WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
+
+ WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
+
+ /*p_ReassmFrmDescrPoolTbl*/
+ p_Manip->fragParams.p_ReassmFrmDescrPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
+ 4);
+
+ if(!p_Manip->fragParams.p_ReassmFrmDescrPoolTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
+
+ WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
+
+ /*p_TimeOutTbl*/
+
+ p_Manip->fragParams.p_TimeOutTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
+ 4);
+
+ if(!p_Manip->fragParams.p_TimeOutTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->fragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
+ WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
+
+
+ p_Manip->updateParams &= ~NUM_OF_TASKS;
+ p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
+ }
+
+ if(p_Manip->updateParams & BUFFER_POOL_ID_FOR_MANIP)
+ {
+
+ p_Manip->fragParams.poolId = fmPortGetSetCcParams.getCcParams.poolIdForManip;
+
+ tmpReg32 = GET_UINT32(p_ReassmTbl->bufferPoolIdAndRisc1SetIndexes);
+ tmpReg32 |= (uint32_t)p_Manip->fragParams.poolId << 16;
+ WRITE_UINT32(p_ReassmTbl->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
+
+ p_Manip->updateParams &= ~BUFFER_POOL_ID_FOR_MANIP;
+ p_Manip->shadowUpdateParams |= BUFFER_POOL_ID_FOR_MANIP;
+ }
+
+ if(p_Manip->updateParams & OFFSET_OF_DATA)
+ {
+ p_Manip->fragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
+ tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
+ tmpReg32|= p_Manip->fragParams.dataOffset;
+ WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
+ p_Manip->updateParams &= ~OFFSET_OF_DATA;
+ p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
+ }
+ if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
+ {
+ p_Manip->fragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
+
+ tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
+ tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
+ WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
+
+ tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
+ tmpReg32 |= (uint32_t)p_Manip->fragParams.prOffset << 24;
+ WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
+ p_Manip->updateParams &= ~OFFSET_OF_PR;
+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
+ }
+ else
+ {
+ p_Manip->fragParams.prOffset = 0xff;
+ p_Manip->updateParams &= ~OFFSET_OF_PR;
+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
+
+ }
+
+ p_Manip->fragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
+ p_Manip->updateParams &= ~HW_PORT_ID;
+ p_Manip->shadowUpdateParams |= HW_PORT_ID;
+
+ /*timeout hc */
+ ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->fragParams.fqidForTimeOutFrames;
+ ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->fragParams.hwPortId << 24;
+ ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
+ ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->fragParams.bitFor1Micro) * p_Manip->fragParams.timeoutRoutineRequestTime)/2;
+ return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
+
+ }
+ else if(validate)
+ {
+ if(fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->fragParams.hwPortId)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
+ if(fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->fragParams.numOfTasks)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
+
+ if(fmPortGetSetCcParams.getCcParams.poolIdForManip != p_Manip->fragParams.poolId)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("poolId for this manipulation previously was defined by another value "));
+
+ if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
+ {
+ if(p_Manip->fragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
+ }
+ else
+ {
+ if(p_Manip->fragParams.prOffset != 0xff)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
+ }
+ if(fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->fragParams.dataOffset)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
+ }
+
+ return E_OK;
+}
+#endif /* FM_CAPWAP_SUPPORT */
+
+#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
+static t_Error UpdateInitIPSec(t_Handle h_FmPort, t_FmPcdManip *p_Manip)
+{
+ SANITY_CHECK_RETURN_ERROR(h_FmPort,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->type == HMAN_OC_IPSEC, E_INVALID_STATE);
+
+ /*
+ if(p_Manip->cnia)
+ {
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+
+ WRITE_UINT32(p_Ad->ccAdBase, GET_UINT32(p_Ad->ccAdBase) | FM_PCD_MANIP_IPSEC_CNIA);
+ }
+*/
+ return E_OK;
+}
+#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))*/
+
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+static t_Error UpdateInitIpFragmentation(t_Handle h_FmPort, t_FmPcdManip *p_Manip)
+{
+ t_FmPortGetSetCcParams fmPortGetSetCcParams;
+ t_Error err;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->type == HMAN_OC_IP_FRAGMENTATION, E_INVALID_STATE);
+
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ return E_OK;
+}
+
+static t_Error CreateIpReassCommonParamTable(t_FmPcdManip *p_Manip,
+ t_FmPcd *p_FmPcd ,
+ t_IpReasmCommonTbl *p_IpReasmCommonPramTbl)
+{
+ uint32_t tmpReg32 = 0, i;
+ uint64_t tmpReg64, size;
+
+ p_Manip->ipReassmParams.h_IpReassCommonParamsTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE,
+ FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_ALIGN);
+
+ if(!p_Manip->ipReassmParams.h_IpReassCommonParamsTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ p_IpReasmCommonPramTbl = (t_IpReasmCommonTbl *)(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl);
+
+ IOMemSet32(p_IpReasmCommonPramTbl, 0, FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE);
+
+ tmpReg32 = 0;
+ if(p_Manip->ipReassmParams.timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
+ tmpReg32 |= FM_PCD_MANIP_IP_REASM_TIME_OUT_BETWEEN_FRAMES;
+
+ tmpReg32 |= p_Manip->ipReassmParams.fqidForTimeOutFrames;
+ WRITE_UINT32(p_IpReasmCommonPramTbl->timeoutModeAndFqid, tmpReg32);
+
+
+ size = p_Manip->ipReassmParams.maxNumFramesInProcess + 129;
+
+ /*p_ReassmFrmDescrIndxPoolTbl */
+ p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ (uint32_t)(size * 2),
+ 256);
+ if(!p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size * 2));
+
+ for( i = 0; i < size - 1; i++)
+ WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
+
+ WRITE_UINT32(p_IpReasmCommonPramTbl->reassFrmDescIndexPoolTblPtr, tmpReg32);
+
+ /*p_ReassmFrmDescrPoolTbl*/
+ p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl = (t_Handle)XX_MallocSmart((uint32_t)(size * 32), p_Manip->ipReassmParams.dataMemId, 32);
+
+ if(!p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
+
+ IOMemSet32(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl, 0, (uint32_t)(size * 32));
+
+ tmpReg64 = (uint64_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl));
+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT);
+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT);
+ WRITE_UINT32(p_IpReasmCommonPramTbl->liodnAndReassFrmDescPoolPtrHi, (uint32_t)(tmpReg64 >> 32));
+ WRITE_UINT32(p_IpReasmCommonPramTbl->reassFrmDescPoolPtrLow, (uint32_t)tmpReg64);
+
+ /*p_TimeOutTbl*/
+ p_Manip->ipReassmParams.h_TimeOutTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ (uint32_t)(size * 8),8);
+
+ if(!p_Manip->ipReassmParams.h_TimeOutTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->ipReassmParams.h_TimeOutTbl, 0, (uint16_t)(size * 8));
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_TimeOutTbl) - p_FmPcd->physicalMuramBase);
+ WRITE_UINT32(p_IpReasmCommonPramTbl->timeOutTblPtr, tmpReg32);
+
+ /* Expiration Delay */
+ tmpReg32 = 0;
+ tmpReg32 |= p_Manip->ipReassmParams.timeoutThresholdForReassmProcess;
+ WRITE_UINT32(p_IpReasmCommonPramTbl->expirationDelay, tmpReg32);
+
+ /* Counts the number of TimeOut occurrences - Must be initialized to zero.*/
+ WRITE_UINT32(p_IpReasmCommonPramTbl->totalTimeOutCounter, 0);
+ /* Counts the number of failed attempts to allocate a Reassembly Frame Descriptor - Must be initialized to zero.*/
+ WRITE_UINT32(p_IpReasmCommonPramTbl->totalRfdPoolBusyCounter, 0);
+ /* Counts the number of times an internal buffer busy occured.*/
+ WRITE_UINT32(p_IpReasmCommonPramTbl->totalInternalBufferBusy, 0);
+ /* Counts the number of times external buffer busy occured. */
+ WRITE_UINT32(p_IpReasmCommonPramTbl->totalExternalBufferBusy, 0);
+
+ return E_OK;
+}
+
+static t_Error CreateIpReassParamTable(t_FmPcdManip *p_Manip, t_Handle h_IpReassParamsTblPtr, bool ipv4)
+{
+ t_IpReasmPram *p_Table;
+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
+ uint32_t tmpReg32, autoLearnHashTblSize;
+ uint32_t numOfWays, setSize, setSizeCode, tmpSetSize;
+ uint32_t waySize, numOfSets, tmpNumOfSets, numOfEntries;
+ uint64_t tmpReg64;
+ t_Handle h_AutoLearnHashTbl, h_AutoLearnSetLockTblPtr;
+
+ /*Pointer to fragment ID*/
+ h_IpReassParamsTblPtr = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_MANIP_IP_REASM_TABLE_SIZE,
+ FM_PCD_MANIP_IP_REASM_TABLE_ALIGN);
+
+ if(!h_IpReassParamsTblPtr)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(h_IpReassParamsTblPtr, 0, FM_PCD_MANIP_IP_REASM_TABLE_SIZE);
+
+ p_Table = (t_IpReasmPram *)h_IpReassParamsTblPtr;
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl) - p_FmPcd->physicalMuramBase);
+ WRITE_UINT32(((t_IpReasmPram *)h_IpReassParamsTblPtr)->ipReassCommonPrmTblPtr, tmpReg32);
+
+ /* waysNumAndSetSize calculation */
+ numOfWays = p_Manip->ipReassmParams.numOfFramesPerHashEntry;
+
+ /*It is recommended that the total number of entries in this table
+ (number of sets * number of ways) will be twice the number of frames that
+ are expected to be reassembled simultaneously.*/
+ numOfEntries = (uint32_t)(p_Manip->ipReassmParams.maxNumFramesInProcess * 2);
+
+ /* sets number calculation - number of entries = number of sets * number of ways */
+ numOfSets = numOfEntries / numOfWays;
+
+ /*TODO - Handle way size*/
+ switch(p_Manip->ipReassmParams.hdr)
+ {
+ case(HEADER_TYPE_IPv6):
+ /* WaySize is rounded-up to next multiple of 8 */
+ waySize = ROUND_UP(((16 + 16 + 4 + 2) /* * numOfWays*/),8);
+ break;
+ case(HEADER_TYPE_IPv4):
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
+ }
+ /* Set size is rounded-up to next power of 2 */
+ LOG2(numOfWays * waySize, tmpSetSize);
+ setSize = (uint32_t)(1 << (tmpSetSize + (POWER_OF_2(numOfWays * waySize) ? 0 : 1)));
+
+ LOG2(setSize, setSizeCode);
+ WRITE_UINT16(((t_IpReasmPram *)p_Table)->waysNumAndSetSize, (uint16_t)((numOfWays << 8) | setSizeCode));
+
+ LOG2(numOfSets, tmpNumOfSets);
+ numOfSets = (uint32_t)(1 << (tmpNumOfSets + (POWER_OF_2(numOfSets) ? 0 : 1)));
+
+ WRITE_UINT16(((t_IpReasmPram *)p_Table)->autoLearnHashKeyMask, (uint16_t)(numOfSets - 1));
+
+ /*autoLearnHashTbl allocation
+ Table size = set size * number of sets
+ This table’s base address should be aligned to SetSize.*/
+ autoLearnHashTblSize = numOfSets * setSize;
+
+ if (ipv4)
+ h_AutoLearnHashTbl = p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl;
+ else
+ h_AutoLearnHashTbl = p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl;
+
+ h_AutoLearnHashTbl = (t_Handle)XX_MallocSmart(autoLearnHashTblSize, p_Manip->ipReassmParams.dataMemId, setSizeCode);
+
+ if(!h_AutoLearnHashTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
+
+ IOMemSet32(h_AutoLearnHashTbl, 0, autoLearnHashTblSize);
+
+ tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT);
+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT);
+ tmpReg64 |= XX_VirtToPhys(h_AutoLearnHashTbl);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->liodnAlAndAutoLearnHashTblPtrHi, (uint32_t)(tmpReg64 >> 32));
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
+
+ /* AutoLearnSetLockTbl allocation - The size of this table is (number of sets in the IP
+ Reassembly Automatic Learning Hash table)*4 bytes. This table resides in external memory
+ and its base address should be 4-byte aligned */
+ if (ipv4)
+ h_AutoLearnSetLockTblPtr = p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr;
+ else
+ h_AutoLearnSetLockTblPtr = p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr;
+
+ h_AutoLearnSetLockTblPtr = (t_Handle)XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->ipReassmParams.dataMemId, 4);
+
+ if(!h_AutoLearnSetLockTblPtr)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
+
+ IOMemSet32(h_AutoLearnSetLockTblPtr, 0, (numOfSets * 4));
+
+ tmpReg64 = ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT);
+ tmpReg64 |= ((uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT);
+ tmpReg64 |= XX_VirtToPhys(h_AutoLearnSetLockTblPtr);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->liodnSlAndAutoLearnSetLockTblPtrHi, (uint32_t)(tmpReg64 >> 32));
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
+
+ /* Setting the First/Middle fragment minimum size in Bytes */
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->minFragSize, p_Manip->ipReassmParams.minFragSize);
+
+ /* Zeroes all counters */
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalSuccessfullyReasmFramesCounter, 0);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalValidFragmentCounter, 0);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalProcessedFragCounter, 0);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalMalformdFragCounter, 0);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalSetBusyCounter, 0);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalDiscardedFragsCounter, 0);
+ WRITE_UINT32(((t_IpReasmPram *)p_Table)->totalMoreThan16FramesCounter, 0);
+
+ return E_OK;
+}
+
+static t_Error UpdateInitIpReasm(t_Handle h_FmPcd,
+ t_Handle h_FmPort,
+ t_FmPcdManip *p_Manip,
+ t_Handle h_Ad,
+ bool validate)
+{
+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ t_IpReasmCommonTbl *p_ReassmCommonTbl = NULL;
+ t_FmPortGetSetCcParams fmPortGetSetCcParams;
+ uint8_t i = 0;
+ uint32_t tmpReg32;
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((p_Manip->type == HMAN_OC_IP_REASSEMBLY), E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
+
+ UNUSED(h_Ad);
+
+ if(p_Manip->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("handler of PCD previously was initiated by different value"));
+
+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
+
+
+ if(p_Manip->updateParams)
+ {
+ if((!(p_Manip->updateParams & OFFSET_OF_DATA) && !(p_Manip->updateParams & OFFSET_OF_PR) &&
+ !(p_Manip->updateParams & HW_PORT_ID)) ||
+ ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || (p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) ||
+ (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR)
+ ||(p_Manip->shadowUpdateParams & HW_PORT_ID)))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
+
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
+ fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_RFENE;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CLOSING_FRAG_CHECK;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
+
+ }
+ else if (validate)
+ {
+ if((!(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) &&
+ (!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) && (!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) &&
+ (!(p_Manip->shadowUpdateParams & HW_PORT_ID))) &&
+ ((p_Manip->updateParams & NUM_OF_TASKS) ||
+ (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR)||
+ (p_Manip->updateParams & HW_PORT_ID)))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
+
+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
+ fmPortGetSetCcParams.getCcParams.poolIndex = p_Manip->fragParams.poolIndx;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_FRAG | NIA_ENG_FM_CTL;
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_RFENE;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CLOSING_FRAG_CHECK;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
+ if(fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
+ }
+
+ if(p_Manip->updateParams)
+ {
+ if(p_Manip->updateParams & OFFSET_OF_DATA)
+ {
+ p_Manip->ipReassmParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
+ tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
+ tmpReg32 |= p_Manip->ipReassmParams.dataOffset;
+ WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
+
+ p_Manip->updateParams &= ~OFFSET_OF_DATA;
+ p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
+ }
+
+ p_Manip->updateParams &= ~HW_PORT_ID;
+ p_Manip->shadowUpdateParams |= HW_PORT_ID;
+ }
+ else
+ {
+ if(validate)
+ {
+ /* TODO - Handle validate..*/
+ /*if(fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->fragParams.hwPortId)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
+ if(fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->fragParams.numOfTasks)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
+
+ if(fmPortGetSetCcParams.getCcParams.poolIdForManip != p_Manip->fragParams.poolId)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("poolId for this manipulation previously was defined by another value "));
+
+ if(!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
+ {
+ if(p_Manip->fragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
+ }
+ else
+ {
+ if(p_Manip->fragParams.prOffset != 0xff)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
+ }
+ if(fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->fragParams.dataOffset)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));*/
+
+ }
+ }
+
+ return E_OK;
+}
+#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
+
+static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
+{
+ if(p_Manip->h_Ad)
+ {
+ if(p_Manip->muramAllocate)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
+ else
+ XX_Free(p_Manip->h_Ad);
+ p_Manip->h_Ad = NULL;
+ }
+ if(p_Manip->p_Template)
+ {
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
+ p_Manip->p_Template = NULL;
+ }
+ if(p_Manip->h_Frag)
+ {
+ if(p_Manip->fragParams.p_AutoLearnHashTbl)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_AutoLearnHashTbl);
+ if(p_Manip->fragParams.p_ReassmFrmDescrPoolTbl)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrPoolTbl);
+ if(p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_ReassmFrmDescrIndxPoolTbl);
+ if(p_Manip->fragParams.p_TimeOutTbl)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_TimeOutTbl);
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
+
+ }
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ if (p_Manip->ipFragParams.h_Frag)
+ {
+ if(p_Manip->ipFragParams.h_FragId)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipFragParams.h_FragId);
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipFragParams.h_Frag);
+ }
+ if (p_Manip->reassm)
+ {
+ if(p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl)
+ XX_Free(p_Manip->ipReassmParams.h_Ipv4AutoLearnHashTbl);
+ if(p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl)
+ XX_Free(p_Manip->ipReassmParams.h_Ipv6AutoLearnHashTbl);
+ if(p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr)
+ XX_Free(p_Manip->ipReassmParams.h_Ipv4AutoLearnSetLockTblPtr);
+ if(p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr)
+ XX_Free(p_Manip->ipReassmParams.h_Ipv6AutoLearnSetLockTblPtr);
+ if(p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr);
+ if(p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr);
+ if(p_Manip->ipReassmParams.h_IpReassCommonParamsTbl)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_IpReassCommonParamsTbl);
+ if(p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->ipReassmParams.h_ReassmFrmDescrIndxPoolTbl);
+ if(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl)
+ XX_Free(p_Manip->ipReassmParams.h_ReassmFrmDescrPoolTbl);
+ }
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+ if(p_Manip->p_StatsTbl)
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
+}
+
+static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
+{
+
+ if(p_ManipParams->rmv)
+ {
+ switch(p_ManipParams->rmvParams.type)
+ {
+ case(e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION):
+ switch(p_ManipParams->rmvParams.rmvSpecificLocationParams.type)
+ {
+ case(e_FM_PCD_MANIP_LOC_BY_HDR) :
+ switch(p_ManipParams->rmvParams.rmvSpecificLocationParams.manipByHdr.hdr)
+ {
+ case(HEADER_TYPE_CAPWAP_DTLS) :
+
+ p_Manip->type = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
+ p_Manip->muramAllocate = TRUE;
+
+ if(p_ManipParams->insrt)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
+
+ if(p_ManipParams->fragOrReasm)
+ {
+ if(!p_ManipParams->fragOrReasmParams.frag)
+ {
+ switch(p_ManipParams->fragOrReasmParams.hdr)
+ {
+ case(HEADER_TYPE_CAPWAP):
+ p_Manip->type = HMAN_OC_CAPWAP_REASSEMBLY;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
+ }
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
+ }
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
+
+ }
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid type of remove location"));
+
+ }
+ break;
+ case(e_FM_PCD_MANIP_RMV_INT_FRAME_HDR) :
+ if(p_ManipParams->insrt || p_ManipParams->fragOrReasm)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For the type of remove e_FM_PCD_MANIP_RMV_INT_FRAME_HDR the only valid option rmv = TRUE, insrt = FALSE, fragOrReasm = FALSE"));
+ p_Manip->type = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
+ p_Manip->muramAllocate = FALSE;
+ break;
+ case(e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION) :
+ if (p_ManipParams->fragOrReasm ||
+ ((p_ManipParams->insrt) && p_ManipParams->insrtParams.type != e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION the only allowed insertion type is e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR"));
+ p_Manip->type = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
+ p_Manip->muramAllocate = TRUE;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
+ }
+ }
+ else if(p_ManipParams->insrt)
+ {
+ switch(p_ManipParams->insrtParams.type)
+ {
+ case(e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE) :
+
+ p_Manip->type = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
+ p_Manip->muramAllocate = FALSE;
+
+ if(p_ManipParams->fragOrReasm)
+ {
+ if(p_ManipParams->fragOrReasmParams.frag)
+ {
+ switch(p_ManipParams->fragOrReasmParams.hdr)
+ {
+ case(HEADER_TYPE_CAPWAP):
+ p_Manip->type = HMAN_OC_CAPWAP_FRAGMENTATION;
+ break;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
+ }
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
+ }
+ break;
+ case(e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR) :
+ if(p_ManipParams->fragOrReasm)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of insert can not be fragOrReasm = TRUE"));
+ p_Manip->type = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
+ p_Manip->muramAllocate = TRUE;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
+ }
+ }
+ else if(p_ManipParams->fragOrReasm)
+ {
+ if(p_ManipParams->fragOrReasmParams.frag)
+ {
+ switch(p_ManipParams->fragOrReasmParams.hdr)
+ {
+ case(HEADER_TYPE_CAPWAP):
+ p_Manip->type = HMAN_OC_CAPWAP_FRAGMENTATION;
+ p_Manip->muramAllocate = FALSE;
+ break;
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ case(HEADER_TYPE_IPv4):
+ p_Manip->type = HMAN_OC_IP_FRAGMENTATION;
+ p_Manip->muramAllocate = TRUE;
+ break;
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
+ }
+ }
+ else
+ {
+ switch (p_ManipParams->fragOrReasmParams.hdr)
+ {
+ case(HEADER_TYPE_CAPWAP):
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS"));
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ case(HEADER_TYPE_IPv4):
+ p_Manip->type = HMAN_OC_IP_REASSEMBLY;
+ p_Manip->muramAllocate = TRUE;
+ p_Manip->ipReassmParams.hdr = HEADER_TYPE_IPv4;
+ break;
+ case(HEADER_TYPE_IPv6):
+ p_Manip->type = HMAN_OC_IP_REASSEMBLY;
+ p_Manip->muramAllocate = TRUE;
+ p_Manip->ipReassmParams.hdr = HEADER_TYPE_IPv6;
+ break;
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
+
+ }
+ }
+
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
+
+ p_Manip->insrt = p_ManipParams->insrt;
+ p_Manip->rmv = p_ManipParams->rmv;
+
+ return E_OK;
+}
+static t_Error UpdateIndxStats( t_Handle h_FmPcd,
+ t_Handle h_FmPort,
+ t_FmPcdManip *p_Manip)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint32_t tmpReg32 = 0;
+ t_AdOfTypeContLookup *p_Ad;
+ t_FmPortGetSetCcParams fmPortGetSetCcParams;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ if(p_Manip->h_FmPcd != h_FmPcd)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,
+ ("handler of PCD previously was initiated by different value"));
+
+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
+
+ if(!p_Manip->p_StatsTbl)
+ {
+
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
+
+ p_Manip->p_StatsTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
+ 4);
+ if(!p_Manip->p_StatsTbl)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
+
+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
+
+ if(p_Manip->cnia)
+ tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
+
+ tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
+
+ }
+ else
+ {
+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ return E_OK;
+}
+
+static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree)
+{
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(h_Manip,E_INVALID_HANDLE);
+ UNUSED(h_FmPcd);
+ UNUSED(h_FmTree);
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
+ if(level != 1)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree"));
+ err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort, p_Manip, h_Ad, validate);
+ break;
+#ifdef FM_CAPWAP_SUPPORT
+ case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
+ if(!p_Manip->h_Frag)
+ break;
+ case(HMAN_OC_CAPWAP_FRAGMENTATION):
+ if(level != 2)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP fragmentation the manipulation has to be in the first level of the tree"));
+ err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
+ break;
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+ if(p_Manip->h_Frag)
+ {
+ if(level != 2)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree"));
+ err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
+ }
+ break;
+#endif /* FM_CAPWAP_SUPPORT */
+#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
+ case(HMAN_OC_IPSEC):
+ err = UpdateInitIPSec(h_FmPort, p_Manip);
+ if (err != E_OK)
+ RETURN_ERROR(MAJOR, err, ("UpdateInitIPSec failed"));
+ if(!p_Manip->h_Frag)
+ break;
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ case(HMAN_OC_IP_FRAGMENTATION):
+ err = UpdateInitIpFragmentation(h_FmPort, p_Manip);
+ break;
+ case(HMAN_OC_IP_REASSEMBLY):
+ err = UpdateInitIpReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
+ break;
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))*/
+ case(HMAN_OC_CAPWAP_INDEXED_STATS):
+ if(level != 2)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For index statistics the manipulation has to be in the first level of the tree"));
+ err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
+ break;
+ default:
+ return E_OK;
+ }
+ return err;
+}
+
+static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree)
+{
+
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
+ t_Error err = E_OK;
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("modify node with this type of manipulation is not suppported"));
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+
+ if(p_Manip->h_Frag)
+ {
+ if(!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && !(p_Manip->shadowUpdateParams & BUFFER_POOL_ID_FOR_MANIP) &&
+ !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("modify node with this type of manipulation requires manipulation be updated previousely in SetPcd function"));
+ if(level != 2)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP reassembly the manipulation has to be in the first level of the tree"));
+ }
+ break;
+#ifdef FM_CAPWAP_SUPPORT
+ case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
+ if(p_Manip->h_Frag)
+ {
+ if(level != 2)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For CAPWAP fragmentation the manipulation has to be in the first level of the tree"));
+ err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
+ }
+ break;
+#endif /* FM_CAPWAP_SUPPORT */
+ default:
+ return E_OK;
+
+ }
+ return err;
+
+}
+
+static t_Error GetPrOffsetByHeaderOrField(t_FmPcdManipLocationParams *p_ManipParams, uint8_t *parseArrayOffset)
+{
+ e_NetHeaderType hdr = p_ManipParams->manipByHdr.hdr;
+ e_FmPcdHdrIndex hdrIndex = p_ManipParams->manipByHdr.hdrIndex;
+ bool byField = p_ManipParams->manipByHdr.byField;
+ t_FmPcdFields field;
+
+ if(byField)
+ field = p_ManipParams->manipByHdr.fullField;
+
+ if(byField)
+ {
+ switch(hdr)
+ {
+ case(HEADER_TYPE_ETH):
+ switch(field.eth)
+ {
+ case(NET_HEADER_FIELD_ETH_TYPE):
+ *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of the type Ethernet with this field not supported"));
+ }
+ break;
+ case(HEADER_TYPE_VLAN):
+ switch(field.vlan)
+ {
+ case(NET_HEADER_FIELD_VLAN_TCI) :
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of the type VLAN with this field not supported"));
+ }
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of this header by field not supported"));
+ }
+ }
+ else
+ {
+ switch(hdr){
+ case(HEADER_TYPE_ETH):
+ *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
+ break;
+ case(HEADER_TYPE_USER_DEFINED_SHIM1):
+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
+ break;
+ case(HEADER_TYPE_USER_DEFINED_SHIM2):
+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
+ break;
+ /* TODO - to take care about SHIM3
+ case(HEADER_TYPE_USER_DEFINED_SHIM3):
+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM3_OFFSET;
+ break;
+ */
+ case(HEADER_TYPE_LLC_SNAP):
+ *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
+ break;
+ case(HEADER_TYPE_PPPoE):
+ *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
+ break;
+ case(HEADER_TYPE_MPLS):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
+ *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
+ break;
+ case(HEADER_TYPE_IPv4):
+ case(HEADER_TYPE_IPv6):
+ if((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
+ *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
+ else if(hdrIndex == e_FM_PCD_HDR_INDEX_2)
+ *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
+ break;
+ case(HEADER_TYPE_MINENCAP):
+ *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
+ break;
+ case(HEADER_TYPE_GRE):
+ *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
+ break;
+ case(HEADER_TYPE_TCP):
+ case(HEADER_TYPE_UDP):
+ case(HEADER_TYPE_IPSEC_AH):
+ case(HEADER_TYPE_IPSEC_ESP):
+ case(HEADER_TYPE_DCCP):
+ case(HEADER_TYPE_SCTP):
+ *parseArrayOffset = CC_PC_PR_L4_OFFSET;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header manipulation of this header is not supported"));
+ }
+ }
+ return E_OK;
+}
+
+static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
+{
+ t_AdOfTypeContLookup *p_Ad;
+ uint32_t tmpReg32 = 0;
+ uint8_t prsArrayOffset = 0;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ if(p_Manip->rmv)
+ {
+ switch(p_ManipParams->rmvSpecificLocationParams.type)
+ {
+ case(e_FM_PCD_MANIP_LOC_BY_HDR) :
+ err = GetPrOffsetByHeaderOrField(&p_ManipParams->rmvSpecificLocationParams, &prsArrayOffset);
+ break;
+ case(e_FM_PCD_MANIP_LOC_NON_HDR) :
+ err = GetPrOffsetByNonHeader(&prsArrayOffset);
+ break;
+ default :
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid type of location header manipulation of type Remove"));
+ }
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ tmpReg32 |= (uint32_t)prsArrayOffset << 24;
+ tmpReg32 |= HMAN_RMV_HDR;
+ }
+
+ if(p_Manip->insrt)
+ tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
+
+ tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
+
+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
+
+ return E_OK;
+}
+
+static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip, bool caamUsed)
+{
+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Ad,E_INVALID_HANDLE);
+
+ p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
+
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
+
+ /*TODO - update offsetInBufferPrefixForIntFrameHdr when port connected to tree
+ tmpReg32 = 0;
+ tmpReg32 |= offsetInBufferPrefixForIntFrameHdr;
+ *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;*/
+
+ tmpReg32 = 0;
+ tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
+ tmpReg32 |= (uint32_t)0x16 << 16;
+ *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
+
+ if (caamUsed)
+ *(uint32_t *)&p_Ad->gmask = 0xf0000000;
+
+ return E_OK;
+}
+
+#ifdef FM_CAPWAP_SUPPORT
+static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
+{
+ t_AdOfTypeContLookup *p_Ad;
+ uint32_t tmpReg32 = 0;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+
+ tmpReg32 = 0;
+ tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+
+
+ if(p_Manip->h_Frag)
+ {
+ p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
+ }
+
+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
+
+ return err;
+}
+
+static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd, uint8_t poolIndex)
+{
+ t_Handle p_Table;
+ uint32_t tmpReg32 = 0;
+ int i = 0;
+ uint8_t log2Num;
+ uint8_t numOfSets;
+ uint32_t j = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
+
+ if(!p_FmPcd->h_Hc)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
+ if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
+ if(!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
+ if(!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
+ DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
+ if(p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
+ {
+ if((p_ManipParams->maxNumFramesInProcess < 4) ||
+ (p_ManipParams->maxNumFramesInProcess > 512))
+ RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512"));
+ }
+ else
+ {
+ if((p_ManipParams->maxNumFramesInProcess < 8) ||
+ (p_ManipParams->maxNumFramesInProcess > 2048))
+ RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048"));
+ }
+
+ p_Manip->updateParams |= (NUM_OF_TASKS | BUFFER_POOL_ID_FOR_MANIP | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
+
+ p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
+ FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
+ if(!p_Manip->h_Frag)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
+
+ p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
+
+ p_Manip->fragParams.p_AutoLearnHashTbl = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
+ FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
+
+ IOMemSet32(p_Manip->fragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
+
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
+
+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
+
+ tmpReg32 = 0;
+ if(p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
+ if(p_ManipParams->haltOnDuplicationFrag)
+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
+ if(p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
+ {
+ i = 8;
+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
+ }
+ else
+ i = 4;
+
+ numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
+ LOG2(numOfSets, log2Num);
+ tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
+
+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
+
+ for(j = 0; j < p_ManipParams->maxNumFramesInProcess * 2; j++)
+ {
+ if(((j / i) % 2)== 0)
+ {
+ WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->fragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
+ }
+ }
+
+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, 0x00008000);
+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
+
+ p_Manip->fragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
+
+ p_Manip->fragParams.poolIndx = poolIndex;
+
+ p_Manip->fragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
+ p_Manip->fragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
+ /*TODO - to take care about this function FmGetTimeStampScale - it return t_Error
+ now we have problems with all calls to this fucntion*/
+ p_Manip->fragParams.bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
+
+ tmpReg32 = 0;
+ tmpReg32 |= (((uint32_t)1<<p_Manip->fragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
+
+ return E_OK;
+
+}
+
+static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd, uint8_t poolIndex)
+{
+ t_AdOfTypeContLookup *p_Ad;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+
+ p_Manip->updateParams |= OFFSET_OF_DATA | BUFFER_POOL_ID_FOR_MANIP;
+
+ p_Manip->frag = TRUE;
+
+ p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_Manip->h_Frag)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
+
+ tmpReg32 = 0;
+ tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
+
+ if(p_ManipParams->headerOptionsCompr)
+ tmpReg32 = FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
+
+
+ p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
+ p_Manip->fragParams.poolIndx = poolIndex;
+
+ return E_OK;
+}
+#endif /* FM_CAPWAP_SUPPORT */
+
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+static t_Error IpFragmentation(t_IpFragmentationParams *p_ManipParams,t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd, uint8_t poolIndex)
+{
+ t_AdOfTypeContLookup *p_Ad;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+
+ p_Manip->ipFragParams.h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+
+ if( !p_Manip->ipFragParams.h_Frag)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32( p_Manip->ipFragParams.h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->ipFragParams.h_Frag;
+
+ tmpReg32 = 0;
+ tmpReg32 |= (uint32_t)HMAN_OC_IP_FRAGMENTATION;
+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ tmpReg32 |= (p_ManipParams->dontFragAction << 30);
+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
+
+ p_Manip->frag = TRUE;
+
+ p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
+ p_Manip->ipFragParams.poolIndx = poolIndex;
+
+ /*Pointer to fragment ID*/
+ p_Manip->ipFragParams.h_FragId= (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,4, 4);
+
+ if(!p_Manip->ipFragParams.h_FragId)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ IOMemSet32(p_Manip->ipFragParams.h_FragId, 0, 4);
+
+ tmpReg32 = 0;
+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->ipFragParams.h_FragId) - (p_FmPcd->physicalMuramBase));
+ tmpReg32 |= p_ManipParams->scratchBpid << 24;
+ WRITE_UINT32(p_Ad->gmask, tmpReg32);
+
+ return E_OK;
+}
+
+static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool ipv4)
+{
+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
+ uint32_t tmpReg32;
+ t_Error err;
+ t_Handle h_IpReassParamsTblPtr;
+
+ /* First Ad register */
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+
+ if (ipv4)
+ h_IpReassParamsTblPtr = p_Manip->ipReassmParams.h_Ipv4ReassParamsTblPtr;
+ else
+ h_IpReassParamsTblPtr = p_Manip->ipReassmParams.h_Ipv6ReassParamsTblPtr;
+
+ err = CreateIpReassParamTable(p_Manip, h_IpReassParamsTblPtr, ipv4);
+
+ if (err == E_OK)
+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(h_IpReassParamsTblPtr) - (p_FmPcd->physicalMuramBase));
+ else
+ return err;
+
+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
+
+ /* Second Ad register */
+ tmpReg32 = (uint32_t)(p_Manip->ipReassmParams.bpid << 8);
+ WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
+
+ p_Manip->updateParams = OFFSET_OF_DATA;
+
+ /* Third Ad register */
+ tmpReg32 = 0;
+ tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
+ tmpReg32 |= (uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_LIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_LIODN_SHIFT;
+ tmpReg32 |= (uint64_t)(p_Manip->ipReassmParams.liodnOffset & FM_PCD_MANIP_IP_REASM_ELIODN_MASK) << (uint64_t)FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT;
+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
+
+ p_Manip->reassm = TRUE;
+
+ return E_OK;
+}
+
+static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
+
+ if(p_Manip->muramAllocate)
+ {
+ p_Manip->ipReassmParams.h_Ipv4Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_Manip->ipReassmParams.h_Ipv4Ad)
+ {
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+ }
+
+ IOMemSet32(p_Manip->ipReassmParams.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+ }
+ else
+ {
+ p_Manip->ipReassmParams.h_Ipv4Ad = (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t), p_Manip->ipReassmParams.dataMemId, 0);
+ if(!p_Manip->ipReassmParams.h_Ipv4Ad)
+ {
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+ }
+
+ memset(p_Manip->ipReassmParams.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
+ }
+
+ FillReassmManipParams(p_Manip, p_Manip->ipReassmParams.h_Ipv6Ad, TRUE);
+
+ return E_OK;
+}
+
+static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
+
+ if(p_Manip->muramAllocate)
+ {
+ p_Manip->ipReassmParams.h_Ipv6Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_Manip->ipReassmParams.h_Ipv6Ad)
+ {
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+ }
+
+ IOMemSet32(p_Manip->ipReassmParams.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+ }
+ else
+ {
+ p_Manip->ipReassmParams.h_Ipv6Ad = (t_Handle)XX_MallocSmart(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t), p_Manip->ipReassmParams.dataMemId, 0);
+ if(!p_Manip->ipReassmParams.h_Ipv6Ad)
+ {
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+ }
+
+ memset(p_Manip->ipReassmParams.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
+ }
+
+ FillReassmManipParams(p_Manip, p_Manip->ipReassmParams.h_Ipv6Ad, FALSE);
+
+ return E_OK;
+}
+
+
+static t_Error IpReassembly(t_FmPcdManipFragOrReasmParams *p_ManipParams,t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
+{
+ uint32_t tmpReg32 = 0, maxSetNumber = 10000;
+ t_IpReasmCommonTbl *p_IpReasmCommonPramTbl = NULL;
+ t_IpReassemblyParams reassmManipParams = p_ManipParams->ipReasmParams;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
+
+ if (!p_FmPcd->h_Hc)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
+ if (!POWER_OF_2(reassmManipParams.maxNumFramesInProcess))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
+
+ if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) && (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
+
+ /*It is recommended that the total number of entries in this table (number of sets * number of ways)
+ will be twice the number of frames that are expected to be reassembled simultaneously.*/
+ if (reassmManipParams.maxNumFramesInProcess > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
+
+ p_Manip->ipReassmParams.maxNumFramesInProcess = reassmManipParams.maxNumFramesInProcess;
+ p_Manip->ipReassmParams.timeOutMode = reassmManipParams.timeOutMode;
+ p_Manip->ipReassmParams.fqidForTimeOutFrames = reassmManipParams.fqidForTimeOutFrames;
+ p_Manip->ipReassmParams.numOfFramesPerHashEntry = reassmManipParams.numOfFramesPerHashEntry;
+ p_Manip->ipReassmParams.timeoutThresholdForReassmProcess = reassmManipParams.timeoutThresholdForReassmProcess;
+ p_Manip->ipReassmParams.liodnOffset = reassmManipParams.liodnOffset;
+ p_Manip->ipReassmParams.minFragSize = reassmManipParams.minFragSize;
+ p_Manip->ipReassmParams.dataMemId = reassmManipParams.dataMemId;
+ p_Manip->ipReassmParams.bpid = p_ManipParams->extBufPoolIndx;
+
+ CreateIpReassCommonParamTable(p_Manip, p_FmPcd, p_IpReasmCommonPramTbl);
+
+ if ((p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4_AND_IPv6) || (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4))
+ return SetIpv4ReassmManip(p_Manip);
+
+ if ((p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv4_AND_IPv6) || (p_Manip->ipReassmParams.hdr == HEADER_TYPE_IPv6))
+ return SetIpv6ReassmManip(p_Manip);
+
+ err = FM_PCD_RegisterReassmPort(p_FmPcd, p_IpReasmCommonPramTbl);
+ if (err != E_OK)
+ {
+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_IpReasmCommonPramTbl);
+ RETURN_ERROR(MAJOR, err, ("port registration"));
+ }
+
+ return E_OK;
+}
+#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
+
+static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
+{
+ t_AdOfTypeContLookup *p_Ad;
+ uint32_t tmpReg32 = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+
+ UNUSED(p_FmPcd);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+
+ tmpReg32 = 0;
+ tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
+ if(p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
+ tmpReg32 |= (uint32_t)0x16 << 16;
+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
+
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
+
+ return E_OK;
+}
+
+static t_Error InsrtHdrByTempl(t_FmPcdManipInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
+{
+ t_FmPcdManipInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->insrtByTemplateParams;
+ uint8_t tmpReg8 = 0xff;
+ t_AdOfTypeContLookup *p_Ad;
+ bool ipModify = FALSE;
+ uint32_t tmpReg32 = 0, tmpRegNia = 0;
+ uint16_t tmpReg16 = 0;
+ t_Error err = E_OK;
+ uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0;
+ uint8_t *p_Template = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
+
+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ if(p_Manip->insrt)
+ {
+ if((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
+ (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
+
+ if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
+
+ if(p_InsrtByTemplate->size > 128)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
+
+ if(p_InsrtByTemplate->size)
+ {
+ p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ p_InsrtByTemplate->size,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_Manip->p_Template)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+
+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
+ tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
+ *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
+ }
+
+ tmpReg32 = 0;
+
+ p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
+
+ if(!p_Template)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
+
+ memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
+
+
+ if(p_InsrtByTemplate->modifyOuterIp)
+ {
+ ipModify = TRUE;
+
+ tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
+
+ if((tmpReg8 & 0xf0) == 0x40)
+ tmpReg8 = 4;
+ else if((tmpReg8 & 0xf0) == 0x60)
+ tmpReg8 = 6;
+ else
+ tmpReg8 = 0xff;
+
+ if(tmpReg8 == 4)
+ {
+ if((IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size"));
+
+ if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
+
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
+
+ if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
+ {
+
+ if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
+ extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
+ blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
+ extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
+ /*IP header template - IP totalLength -
+ (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
+ in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
+ second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
+ }
+ if(blockSize)
+ {
+ if (!POWER_OF_2(blockSize))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
+ blockSize -= 1;
+ }
+
+ if((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
+
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize;
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);
+
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_ID_FIELD_OFFSET_FROM_IP] = 0x00;
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
+
+
+ /*IP header template - relevant only for ipv4 CheckSum = 0*/
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
+
+
+ /*UDP checksum has to be 0*/
+ if(p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
+ {
+ if((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_UDPCHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
+
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
+
+ }
+
+ if(p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
+
+ tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
+ }
+
+ tmpReg32 = tmpReg16 = tmpReg8 = 0;
+ /*TODO - check it*/
+ if(p_InsrtByTemplate->modifyOuterVlan)
+ {
+ if(p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
+
+ memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
+ if((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
+
+ memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
+ tmpReg8 &= 0x1f;
+ tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
+
+ p_Template[14] = tmpReg8;
+ }
+
+ Mem2IOCpy32(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
+
+ XX_Free(p_Template);
+ }
+
+ tmpReg32 = 0;
+ if(p_Manip->h_Frag)
+ {
+ tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
+ tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
+ }
+ else
+ tmpReg32 = 0xffff0000;
+
+ if(ipModify)
+ tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
+ else
+ tmpReg32 |= (uint32_t)0x0000ff00;
+
+ tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
+ *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
+
+ tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
+
+ return err;
+}
+
+#if defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC)
+static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
+{
+
+ t_Error err = E_OK;
+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
+ uint32_t tmpReg32 = 0, tmpRegNia = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_INVALID_HANDLE);
+
+ if(p_Manip->frag == TRUE)
+ {
+ tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
+ tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
+ }
+ else
+ tmpReg32 = 0xffff0000;
+
+ tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
+ tmpReg32 |= HMAN_OC_IPSEC;
+
+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
+ WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
+ WRITE_UINT32(p_Ad->gmask, 0); /* Total frame counter - MUST be initialized to zero.*/
+
+/*
+ TODO - Fill the following:
+ - Over write OuterTos
+ - SaveInnerTos
+ - support in CNIA
+*/
+
+ return err;
+}
+#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
+
+static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
+{
+
+ switch(p_StatsParams->type)
+ {
+ case(e_FM_PCD_STATS_PER_FLOWID):
+ p_Manip->type = HMAN_OC_CAPWAP_INDEXED_STATS;
+ p_Manip->muramAllocate = TRUE;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
+ }
+
+ return E_OK;
+}
+
+static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params, bool stats)
+{
+ t_FmPcdManip *p_Manip;
+ t_Error err;
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+
+ p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
+ if(!p_Manip)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
+ return NULL;
+ }
+ memset(p_Manip, 0, sizeof(t_FmPcdManip));
+
+ if(!stats)
+ {
+ err = CheckManipParamsAndSetType(p_Manip, (t_FmPcdManipParams *)p_Params);
+ }
+ else
+ {
+ err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
+ }
+
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("INVALID HEADER MANIPULATION TYPE"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ if(p_Manip->type != HMAN_OC_IP_REASSEMBLY)
+ {
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+ if(p_Manip->muramAllocate)
+ {
+ p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
+ FM_PCD_CC_AD_ENTRY_SIZE,
+ FM_PCD_CC_AD_TABLE_ALIGN);
+ if(!p_Manip->h_Ad)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+
+ IOMemSet32(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
+ }
+ else
+ {
+ p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
+ if(!p_Manip->h_Ad)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+
+ memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
+ }
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ }
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+ p_Manip->h_FmPcd = h_FmPcd;
+
+ return p_Manip;
+}
+
+
+t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify)
+{
+ t_Error err;
+
+ if(!modify)
+ {
+ err = FmPcdManipInitUpdate(h_FmPcd, h_FmPort, h_Manip, h_Ad, validate, level, h_FmTree);
+ }
+ else
+ {
+ err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
+ }
+ return err;
+}
+
+uint32_t FmPcdManipGetRequiredAction (t_Handle h_Manip)
+{
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
+
+ ASSERT_COND(h_Manip);
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+ case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
+ return UPDATE_NIA_ENQ_WITHOUT_DMA;
+ default:
+ return 0;
+ }
+}
+
+void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
+{
+
+ if(add)
+ ((t_FmPcdManip *)h_Manip)->owner++;
+ else
+ {
+ ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
+ ((t_FmPcdManip *)h_Manip)->owner--;
+ }
+}
+
+t_Error FmPcdManipCheckParamsForCcNextEgine(t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, uint32_t *requiredAction)
+{
+ t_FmPcdManip *p_Manip;
+ t_Error err;
+
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip, E_NULL_POINTER);
+
+ p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
+ *requiredAction = 0;
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_CAPWAP_INDEXED_STATS):
+ if(p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
+ if(p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
+ p_Manip->cnia = TRUE;
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+ *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
+ case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
+ p_Manip->ownerTmp++;
+ break;
+ case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
+ if((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
+ p_Manip->ownerTmp++;
+ break;
+ case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
+ if((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC) &&
+ (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) != CC_PC_GENERIC_IC_HASH_INDEXED))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP"));
+ err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip, FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
+ break;
+#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
+ case(HMAN_OC_IPSEC):
+
+ if((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_DONE) &&
+ !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
+ p_Manip->cnia = FALSE;
+ else
+ p_Manip->cnia = TRUE;
+ if(!p_Manip->h_Frag)
+ {
+ p_Manip->ownerTmp++;
+ break;
+ }
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ case(HMAN_OC_IP_FRAGMENTATION):
+ if(p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
+ p_Manip->ownerTmp++;
+ break;
+#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
+ break;
+#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("invalid type of header manipulation for this state"));
+ }
+
+ return E_OK;
+}
+
+t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode)
+{
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_CAPWAP_INDEXED_STATS):
+ if(p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
+ break;
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+ if(p_Manip->h_Frag)
+ {
+ if(p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
+ err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ break;
+ default:
+ break;
+ }
+ return err;
+}
+
+void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew)
+{
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
+
+ ASSERT_COND(p_Manip);
+
+ FmPcdManipUpdateOwner(h_Manip, TRUE);
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+ case(HMAN_OC_CAPWAP_INDEXED_STATS):
+#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
+ case(HMAN_OC_IP_FRAGMENTATION):
+ case(HMAN_OC_IP_REASSEMBLY):
+#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
+ *p_AdNew = p_Manip->h_Ad;
+ break;
+ case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
+ case(HMAN_OC_CAPWAP_FRAGMENTATION):
+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
+ *p_AdNew = NULL;
+ break;
+#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
+ case(HMAN_OC_IPSEC):
+ if (p_Manip->cnia)
+ *p_AdNew = p_Manip->h_Ad;
+ else
+ {
+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia, ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
+ *p_AdNew = NULL;
+ }
+ break;
+#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
+ default:
+ break;
+ }
+}
+
+void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset)
+{
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
+
+ ASSERT_COND(p_Manip);
+
+ FmPcdManipUpdateOwner(h_Manip, TRUE);
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask, ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
+ *p_AdNew = NULL;
+ break;
+ default:
+ break;
+ }
+}
+
+t_Handle FM_PCD_ManipSetNode(t_Handle h_FmPcd, t_FmPcdManipParams *p_ManipParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdManip *p_Manip;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
+ SANITY_CHECK_RETURN_VALUE(p_ManipParams,E_INVALID_HANDLE,NULL);
+
+
+ p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
+ if(!p_Manip)
+ return NULL;
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
+ /* HmanType1 */
+ err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->rmvParams, p_Manip);
+ break;
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ case(HMAN_OC_IP_REASSEMBLY):
+ /* IpReassembly */
+ err = IpReassembly(&p_ManipParams->fragOrReasmParams, p_Manip, p_FmPcd);
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+ break;
+ case(HMAN_OC_IP_FRAGMENTATION):
+ /* IpFragmentation */
+ err = IpFragmentation(&p_ManipParams->fragOrReasmParams.ipFragParams ,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx);
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+#if (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || defined(UNDER_CONSTRUCTION_IPSEC))
+ case(HMAN_OC_IPSEC) :
+ err = IPSecManip(p_ManipParams, p_Manip, p_FmPcd);
+ break;
+#endif /* (defined(UNDER_CONSTRUCTION_FRAG_REASSEMBLY) || ... */
+#ifdef FM_CAPWAP_SUPPORT
+ case(HMAN_OC_CAPWAP_FRAGMENTATION):
+ /* CapwapFragmentation */
+ err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.capwapFragParams ,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx);
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+ if(p_Manip->insrt)
+ p_Manip->type = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
+ case(HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
+ /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
+ err = InsrtHdrByTempl(&p_ManipParams->insrtParams, p_Manip, p_FmPcd);
+ break;
+ case(HMAN_OC_CAPWAP_REASSEMBLY) :
+ /*CAPWAP Reassembly*/
+ err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.capwapReasmParams,p_Manip, p_FmPcd, p_ManipParams->fragOrReasmParams.extBufPoolIndx);
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+ if(p_Manip->rmv)
+ p_Manip->type = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
+ case(HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
+ /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
+ err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
+ break;
+#endif /* FM_CAPWAP_SUPPORT */
+ case(HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
+ /*Application Specific type 1*/
+ err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, (bool)(p_ManipParams->treatFdStatusFieldsAsErrors ? TRUE : FALSE));
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+ return p_Manip;
+}
+
+t_Error FM_PCD_ManipDeleteNode(t_Handle h_FmPcd, t_Handle h_ManipNode)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
+
+ if(p_Manip->owner)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
+
+ ReleaseManipHandler(p_Manip,p_FmPcd);
+
+ XX_Free(h_ManipNode);
+
+ return E_OK;
+}
+
+t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdManip *p_Manip;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
+ SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
+
+ p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
+ if(!p_Manip)
+ return NULL;
+
+ switch(p_Manip->type)
+ {
+ case(HMAN_OC_CAPWAP_INDEXED_STATS):
+ /* Indexed statistics */
+ err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+
+ }
+ if(err)
+ {
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ ReleaseManipHandler(p_Manip, p_FmPcd);
+ XX_Free(p_Manip);
+ return NULL;
+ }
+ return p_Manip;
+}
+
+#endif /* FM_CAPWAP_SUPPORT */
+#endif /* CONFIG_FMAN_P1023 */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h
new file mode 100644
index 0000000..dbe9c1d
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_manip.h
@@ -0,0 +1,310 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_manip.h
+
+ @Description FM PCD manip...
+*//***************************************************************************/
+#ifndef __FM_MANIP_H
+#define __FM_MANIP_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "list_ext.h"
+
+#include "fm_cc.h"
+
+
+/***********************************************************************/
+/* Header manipulations defines */
+/***********************************************************************/
+
+#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
+#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
+#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
+#define HMAN_OC_IPSEC 0x34
+#define HMAN_OC_IP_FRAGMENTATION 0x74
+#define HMAN_OC_IP_REASSEMBLY 0xB4
+#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
+#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
+#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
+#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
+
+#define HMAN_RMV_HDR 0x80000000
+#define HMAN_INSRT_INT_FRM_HDR 0x40000000
+
+#define UDP_UDPHECKSUM_FIELD_OFFSET_FROM_UDP 6
+#define UDP_UDPCHECKSUM_FIELD_SIZE 2
+
+#define IP_DSCECN_FIELD_OFFSET_FROM_IP 1
+#define IP_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
+#define IP_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
+#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
+#define IP_ID_FIELD_OFFSET_FROM_IP 4
+
+#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 80
+#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
+#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
+#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
+#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
+
+
+#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
+#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
+#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
+#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
+
+#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
+
+#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
+#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
+#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
+
+#define FM_PCD_MANIP_IPSEC_CALC_UDP_LENGTH 0x01000000
+#define FM_PCD_MANIP_IPSEC_CNIA 0x20000000
+
+#define e_FM_MANIP_CAPWAP_INDX 0
+
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+#define FM_PCD_MANIP_IP_REASM_TABLE_SIZE 0x40
+#define FM_PCD_MANIP_IP_REASM_TABLE_ALIGN 8
+
+#define FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_SIZE 64
+#define FM_PCD_MANIP_IP_REASM_COMMON_PARAM_TABLE_ALIGN 8
+#define FM_PCD_MANIP_IP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
+#define e_FM_MANIP_IP_INDX 1
+#define FM_PCD_MANIP_IP_REASM_LIODN_MASK 0x000003F0
+#define FM_PCD_MANIP_IP_REASM_LIODN_SHIFT 56
+#define FM_PCD_MANIP_IP_REASM_ELIODN_MASK 0x0000000F
+#define FM_PCD_MANIP_IP_REASM_ELIODN_SHIFT 44
+
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+
+
+/***********************************************************************/
+/* Memory map */
+/***********************************************************************/
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+
+typedef _Packed struct {
+ volatile uint32_t mode;
+ volatile uint32_t autoLearnHashTblPtr;
+ volatile uint32_t intStatsTblPtr;
+ volatile uint32_t reasmFrmDescPoolTblPtr;
+ volatile uint32_t reasmFrmDescIndexPoolTblPtr;
+ volatile uint32_t timeOutTblPtr;
+ volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
+ volatile uint32_t risc23SetIndexes;
+ volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
+ volatile uint32_t extendedStatsTblPtr;
+ volatile uint32_t expirationDelay;
+ volatile uint32_t totalProcessedFragCounter;
+ volatile uint32_t totalUnsuccessfulReasmFramesCounter;
+ volatile uint32_t totalDuplicatedFragCounter;
+ volatile uint32_t totalMalformdFragCounter;
+ volatile uint32_t totalTimeOutCounter;
+ volatile uint32_t totalSetBusyCounter;
+ volatile uint32_t totalRfdPoolBusyCounter;
+ volatile uint32_t totalDiscardedFragsCounter;
+ volatile uint32_t totalMoreThan16FramesCounter;
+ volatile uint32_t internalBufferBusy;
+ volatile uint32_t externalBufferBusy;
+ volatile uint8_t res[16];
+} _PackedType t_CapwapReasmPram;
+
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+typedef _Packed struct t_IpReasmPram{
+ volatile uint16_t waysNumAndSetSize;
+ volatile uint16_t autoLearnHashKeyMask;
+ volatile uint32_t ipReassCommonPrmTblPtr;
+ volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
+ volatile uint32_t autoLearnHashTblPtrLow;
+ volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
+ volatile uint32_t autoLearnSetLockTblPtrLow;
+ volatile uint16_t minFragSize;
+ volatile uint16_t reserved1;
+ volatile uint32_t totalSuccessfullyReasmFramesCounter;
+ volatile uint32_t totalValidFragmentCounter;
+ volatile uint32_t totalProcessedFragCounter;
+ volatile uint32_t totalMalformdFragCounter;
+ volatile uint32_t totalSetBusyCounter;
+ volatile uint32_t totalDiscardedFragsCounter;
+ volatile uint32_t totalMoreThan16FramesCounter;
+ volatile uint32_t reserved2[2];
+} _PackedType t_IpReasmPram;
+
+typedef _Packed struct t_IpReasmCommonTbl{
+ volatile uint32_t timeoutModeAndFqid;
+ volatile uint32_t reassFrmDescIndexPoolTblPtr;
+ volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
+ volatile uint32_t reassFrmDescPoolPtrLow;
+ volatile uint32_t timeOutTblPtr;
+ volatile uint32_t expirationDelay;
+ volatile uint32_t reseervd1;
+ volatile uint32_t reseervd2;
+ volatile uint32_t totalTimeOutCounter;
+ volatile uint32_t totalRfdPoolBusyCounter;
+ volatile uint32_t totalInternalBufferBusy;
+ volatile uint32_t totalExternalBufferBusy;
+ volatile uint32_t reserved3[4];
+} _PackedType t_IpReasmCommonTbl;
+
+#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/***********************************************************************/
+/* Driver's internal structures */
+/***********************************************************************/
+
+typedef struct
+{
+ t_Handle p_AutoLearnHashTbl;
+ t_Handle p_ReassmFrmDescrPoolTbl;
+ t_Handle p_ReassmFrmDescrIndxPoolTbl;
+ t_Handle p_TimeOutTbl;
+ uint8_t maxNumFramesInProcess;
+ uint8_t numOfTasks;
+ uint8_t poolId;
+ uint8_t prOffset;
+ uint16_t dataOffset;
+ uint8_t poolIndx;
+ uint8_t hwPortId;
+ uint32_t fqidForTimeOutFrames;
+ uint32_t timeoutRoutineRequestTime;
+ uint32_t bitFor1Micro;
+} t_FragParams;
+
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+typedef struct
+{
+ t_Handle h_Frag;
+ t_Handle h_FragId;
+ uint8_t poolId;
+ uint16_t dataOffset;
+ uint8_t poolIndx;
+}t_IpFragParams;
+
+typedef struct t_IpReassmParams
+{
+ t_Handle h_Ipv4Ad;
+ t_Handle h_Ipv6Ad;
+ e_NetHeaderType hdr; /**< Header selection */
+ uint32_t fqidForTimeOutFrames;
+ uint16_t dataOffset;
+ t_Handle h_IpReassCommonParamsTbl;
+ t_Handle h_Ipv4ReassParamsTblPtr;
+ t_Handle h_Ipv6ReassParamsTblPtr;
+ t_Handle h_Ipv4AutoLearnHashTbl;
+ t_Handle h_Ipv6AutoLearnHashTbl;
+ t_Handle h_Ipv4AutoLearnSetLockTblPtr;
+ t_Handle h_Ipv6AutoLearnSetLockTblPtr;
+ t_Handle h_ReassmFrmDescrIndxPoolTbl;
+ t_Handle h_ReassmFrmDescrPoolTbl;
+ t_Handle h_TimeOutTbl;
+ uint32_t maxNumFramesInProcess;
+ uint32_t liodnOffset;
+ uint32_t minFragSize;
+ uint8_t dataMemId; /**< Memory partition ID for data buffers */
+ uint32_t bpid;
+ e_FmPcdManipReassemTimeOutMode timeOutMode;
+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
+ uint32_t timeoutThresholdForReassmProcess;
+
+}t_IpReassmParams;
+
+typedef struct t_IpCommonReassmParams
+{
+ uint8_t numOfTasks;
+ uint32_t bitFor1Micro;
+ t_Handle h_ReassmFrmDescrPoolTbl;
+ t_Handle h_ReassmFrmDescrIndxPoolTbl;
+ t_Handle h_TimeOutTbl;
+}t_IpCommonReassmParams;
+
+#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
+
+typedef struct{
+ bool muramAllocate;
+ t_Handle h_Ad;
+ uint32_t type;
+ bool rmv;
+ bool insrt;
+ uint8_t *p_Template;
+ t_Handle h_Frag;
+ bool frag;
+ bool reassm;
+ uint16_t sizeForFragmentation;
+ uint8_t owner;
+ uint32_t updateParams;
+ uint32_t shadowUpdateParams;
+ t_FragParams fragParams;
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ t_IpReassmParams ipReassmParams;
+ t_IpFragParams ipFragParams;
+#endif /* UNDER_CONSTRUCTION_FRAG_REASSEMBLY */
+ uint8_t icOffset;
+ uint16_t ownerTmp;
+ bool cnia;
+ t_Handle p_StatsTbl;
+ t_Handle h_FmPcd;
+} t_FmPcdManip;
+
+typedef struct t_FmPcdCcSavedManipParams
+{
+ union
+ {
+ struct
+ {
+ uint16_t dataOffset;
+ uint8_t poolId;
+ }capwapParams;
+#ifdef UNDER_CONSTRUCTION_FRAG_REASSEMBLY
+ struct
+ {
+ uint16_t dataOffset;
+ uint8_t poolId;
+ }ipParams;
+#endif /*UNDER_CONSTRUCTION_FRAG_REASSEMBLY*/
+ };
+
+} t_FmPcdCcSavedManipParams;
+
+
+#endif /* __FM_MANIP_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c
new file mode 100644
index 0000000..e3af876
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c
@@ -0,0 +1,1693 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_pcd.c
+
+ @Description FM PCD ...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "xx_ext.h"
+#include "sprint_ext.h"
+#include "debug_ext.h"
+#include "net_ext.h"
+#include "fm_ext.h"
+#include "fm_pcd_ext.h"
+
+#include "fm_common.h"
+#include "fm_pcd.h"
+#include "fm_pcd_ipc.h"
+#include "fm_hc.h"
+
+
+static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
+{
+ if(!p_FmPcd->h_Fm)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
+
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ if(p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
+
+ if(p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
+
+ if(!p_FmPcd->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
+
+ if((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
+
+ if(p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
+ }
+
+ return E_OK;
+}
+
+static volatile bool blockingFlag = FALSE;
+static void FmPcdIpcMsgCompletionCB(t_Handle h_FmPcd,
+ uint8_t *p_Msg,
+ uint8_t *p_Reply,
+ uint32_t replyLength,
+ t_Error status)
+{
+ UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
+ blockingFlag = FALSE;
+}
+
+static t_Error FmPcdHandleIpcMsgCB(t_Handle h_FmPcd,
+ uint8_t *p_Msg,
+ uint32_t msgLength,
+ uint8_t *p_Reply,
+ uint32_t *p_ReplyLength)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_Error err = E_OK;
+ t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
+ t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
+
+#ifdef DISABLE_SANITY_CHECKS
+ UNUSED(msgLength);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ ASSERT_COND(p_Msg);
+
+ memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
+ *p_ReplyLength = 0;
+
+ switch(p_IpcMsg->msgId)
+ {
+ case (FM_PCD_MASTER_IS_ALIVE):
+ *(uint8_t*)(p_IpcReply->replyBody) = 1;
+ p_IpcReply->error = E_OK;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ case (FM_PCD_MASTER_IS_ENABLED):
+ /* count partitions registrations */
+ if(p_FmPcd->enabled)
+ p_FmPcd->numOfEnabledGuestPartitionsPcds++;
+ *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
+ p_IpcReply->error = E_OK;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ case (FM_PCD_GUEST_DISABLE):
+ if(p_FmPcd->numOfEnabledGuestPartitionsPcds)
+ {
+ p_FmPcd->numOfEnabledGuestPartitionsPcds--;
+ p_IpcReply->error = E_OK;
+ }
+ else
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
+ p_IpcReply->error = E_INVALID_STATE;
+ }
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+ case(FM_PCD_GET_COUNTER):
+ {
+ e_FmPcdCounters inCounter;
+ uint32_t outCounter;
+
+ memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
+ outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
+ p_IpcReply->error = E_OK;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (FM_PCD_ALLOC_KG_SCHEMES):
+ {
+ t_FmPcdIpcKgSchemesParams ipcSchemesParams;
+
+ memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
+ err = FmPcdKgAllocSchemes(h_FmPcd,
+ ipcSchemesParams.numOfSchemes,
+ ipcSchemesParams.guestId,
+ p_IpcReply->replyBody);
+ p_IpcReply->error = err;
+ *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
+ break;
+ }
+ case (FM_PCD_FREE_KG_SCHEMES):
+ {
+ t_FmPcdIpcKgSchemesParams ipcSchemesParams;
+
+ memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
+ err = FmPcdKgFreeSchemes(h_FmPcd,
+ ipcSchemesParams.numOfSchemes,
+ ipcSchemesParams.guestId,
+ ipcSchemesParams.schemesIds);
+ p_IpcReply->error = err;
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+ }
+ case (FM_PCD_ALLOC_KG_CLSPLAN):
+ {
+ t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
+
+ memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
+ err = KgAllocClsPlanEntries(h_FmPcd,
+ ipcKgClsPlanParams.numOfClsPlanEntries,
+ ipcKgClsPlanParams.guestId,
+ p_IpcReply->replyBody);
+ p_IpcReply->error = err;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ }
+ case (FM_PCD_FREE_KG_CLSPLAN):
+ {
+ t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
+
+ memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
+ KgFreeClsPlanEntries(h_FmPcd,
+ ipcKgClsPlanParams.numOfClsPlanEntries,
+ ipcKgClsPlanParams.guestId,
+ ipcKgClsPlanParams.clsPlanBase);
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+ }
+ case (FM_PCD_ALLOC_PROFILES):
+ {
+ t_FmPcdIpcPlcrAllocParams ipcPlcrAllocParams;
+ uint16_t profilesBase;
+
+ memcpy((uint8_t*)&ipcPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPlcrAllocParams));
+ err = PlcrAllocProfiles(h_FmPcd,
+ ipcPlcrAllocParams.hardwarePortId,
+ ipcPlcrAllocParams.num,
+ &profilesBase);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&profilesBase, sizeof(uint16_t));
+ p_IpcReply->error = err;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
+ break;
+ }
+ case (FM_PCD_FREE_PROFILES):
+ {
+ t_FmPcdIpcPlcrAllocParams ipcPlcrAllocParams;
+
+ memcpy((uint8_t*)&ipcPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPlcrAllocParams));
+ err = PlcrFreeProfiles(h_FmPcd,
+ ipcPlcrAllocParams.hardwarePortId,
+ ipcPlcrAllocParams.num,
+ ipcPlcrAllocParams.plcrProfilesBase);
+ p_IpcReply->error = err;
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+ }
+ case (FM_PCD_ALLOC_SHARED_PROFILES):
+ {
+ uint16_t numOfProfiles;
+ uint16_t profilesIds[FM_PCD_PLCR_NUM_ENTRIES];
+ uint32_t profilesMask[FM_PCD_PLCR_NUM_ENTRIES/32];
+ int i;
+
+ memset(profilesMask, 0, FM_PCD_PLCR_NUM_ENTRIES/32 * sizeof(uint32_t));
+ memcpy((uint8_t*)&numOfProfiles, p_IpcMsg->msgBody, sizeof(uint16_t));
+ err = PlcrAllocSharedProfiles(h_FmPcd,
+ numOfProfiles,
+ profilesIds);
+ p_IpcReply->error = err;
+
+ /* translate the allocated profile id's to a 32bit * 8regs mask */
+ for(i = 0;i<numOfProfiles;i++)
+ profilesMask[profilesIds[i]/32] |= (0x80000000 >> (profilesIds[i] % 32));
+
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&profilesMask, sizeof(profilesMask));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(profilesMask); /* num-of-shared-profiles */
+ break;
+ }
+ case (FM_PCD_FREE_SHARED_PROFILES):
+ {
+ t_FmPcdIpcSharedPlcrAllocParams ipcSharedPlcrAllocParams;
+ uint16_t profilesIds[FM_PCD_PLCR_NUM_ENTRIES];
+ int i,j, index = 0;
+ uint32_t walking1Mask = 0x80000000;
+
+ memset(profilesIds, 0, FM_PCD_PLCR_NUM_ENTRIES*sizeof(uint16_t));
+ memcpy((uint8_t*)&ipcSharedPlcrAllocParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSharedPlcrAllocParams));
+ for(i = 0; i<FM_PCD_PLCR_NUM_ENTRIES/32 ; i++)
+ {
+ if(ipcSharedPlcrAllocParams.sharedProfilesMask[i])
+ {
+ for(j = 0 ; j<32 ; j++)
+ {
+ if(ipcSharedPlcrAllocParams.sharedProfilesMask[i] & walking1Mask)
+ profilesIds[index++] = (uint16_t)(i*32+j);
+ walking1Mask >>= 1;
+ }
+ walking1Mask = 0x80000000;
+ }
+ }
+
+ PlcrFreeSharedProfiles(h_FmPcd,
+ ipcSharedPlcrAllocParams.num,
+ profilesIds);
+ break;
+ }
+ case(FM_PCD_GET_SW_PRS_OFFSET):
+ {
+ t_FmPcdIpcSwPrsLable ipcSwPrsLable;
+ uint32_t swPrsOffset;
+
+ memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
+ swPrsOffset =
+ FmPcdGetSwPrsOffset(h_FmPcd,
+ (e_NetHeaderType)ipcSwPrsLable.enumHdr,
+ ipcSwPrsLable.indexPerHdr);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case(FM_PCD_PRS_INC_PORT_STATS):
+ {
+ t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
+
+ memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
+ PrsIncludePortInStatistics(h_FmPcd,
+ ipcPrsIncludePort.hardwarePortId,
+ ipcPrsIncludePort.include);
+ break;
+ }
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ case(FM_PCD_DUMP_REGS):
+ if((err = FM_PCD_DumpRegs(h_FmPcd)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ case(FM_PCD_KG_DUMP_REGS):
+ if((err = FM_PCD_KgDumpRegs(h_FmPcd)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ case(FM_PCD_PLCR_DUMP_REGS):
+ if((err = FM_PCD_PlcrDumpRegs(h_FmPcd)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ case(FM_PCD_PLCR_PROFILE_DUMP_REGS):
+ {
+ t_Handle h_Profile;
+ memcpy((uint8_t*)&h_Profile, p_IpcMsg->msgBody, sizeof(t_Handle));
+ if((err = FM_PCD_PlcrProfileDumpRegs(h_FmPcd, h_Profile)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+
+ }
+ case(FM_PCD_PRS_DUMP_REGS):
+ if((err = FM_PCD_PrsDumpRegs(h_FmPcd)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
+ default:
+ *p_ReplyLength = 0;
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
+ }
+ return E_OK;
+}
+
+void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
+{
+ p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
+}
+
+t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
+{
+ uint8_t netEnvId = p_GrpParams->netEnvId;
+ int i, k, j;
+
+ if(p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
+ {
+ p_GrpParams->grpExists = TRUE;
+ p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
+ return E_OK;
+ }
+
+ for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
+ {
+ for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
+ {
+ /* if an option exists, add it to the opts list */
+ if(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
+ {
+ /* check if this option already exists, add if it doesn't */
+ for(j = 0;j<p_GrpParams->numOfOptions;j++)
+ {
+ if(p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
+ break;
+ }
+ p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
+ if(j == p_GrpParams->numOfOptions)
+ {
+ p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
+ p_GrpParams->numOfOptions++;
+ }
+ }
+ }
+ }
+
+ if(p_GrpParams->numOfOptions == 0)
+ {
+ if(p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
+ {
+ p_GrpParams->grpExists = TRUE;
+ p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
+ }
+ }
+
+ return E_OK;
+
+}
+
+t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
+{
+ uint8_t j,k;
+
+ *p_Vector = 0;
+
+ for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
+ (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
+ {
+ for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
+ (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
+ {
+ if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
+ *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
+ }
+ }
+
+ if (!*p_Vector)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
+ else
+ return E_OK;
+}
+
+t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
+{
+ int i;
+
+ p_Params->vector = 0;
+ for(i=0; i<p_Params->numOfDistinctionUnits ;i++)
+ {
+ if(p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
+ ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
+ p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
+ }
+
+ return E_OK;
+}
+
+bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
+{
+ int i=0, k;
+ /* check whether a given unit may be used by non-clsPlan users. */
+ /* first, recognize the unit by its vector */
+ while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
+ {
+ if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
+ {
+ for (k=0;
+ ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
+ k++)
+ /* check that no option exists */
+ if((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
+ return FALSE;
+ break;
+ }
+ i++;
+ }
+ /* assert that a unit was found to mach the vector */
+ ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
+
+ return TRUE;
+}
+bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ int i, k;
+
+ ASSERT_COND(p_FmPcd);
+
+ for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
+ {
+ for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
+ if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
+ return TRUE;
+ }
+ for (i=0; ((i < FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) &&
+ (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
+ {
+ if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
+{
+ int i;
+
+ ASSERT_COND(p_FmPcd);
+
+ for (i=0; (i < FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
+ && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
+ {
+ if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
+ return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
+ }
+
+ return HEADER_TYPE_NONE;
+}
+
+void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint16_t swPortIndex = 0;
+
+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
+
+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
+}
+
+uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
+}
+
+uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ return p_FmPcd->netEnvs[netEnvId].macsecVector;
+}
+
+void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
+{
+ ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
+}
+
+void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
+{
+ ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
+ ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
+}
+
+uint32_t FmPcdLock(t_Handle h_FmPcd)
+{
+ return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
+}
+
+void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
+{
+ XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
+}
+
+t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
+{
+ ASSERT_COND(h_FmPcd);
+ SANITY_CHECK_RETURN_VALUE(((t_FmPcd*)h_FmPcd)->h_Hc, E_INVALID_HANDLE, NULL);
+ return ((t_FmPcd*)h_FmPcd)->h_Hc;
+}
+
+/**********************************************************************************************************/
+/* API */
+/**********************************************************************************************************/
+
+t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
+{
+ t_FmPcd *p_FmPcd = NULL;
+ t_FmPhysAddr physicalMuramBase;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
+
+ p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
+ if (!p_FmPcd)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd"));
+ return NULL;
+ }
+ memset(p_FmPcd, 0, sizeof(t_FmPcd));
+
+ p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
+ if (!p_FmPcd->p_FmPcdDriverParam)
+ {
+ XX_Free(p_FmPcd);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Driver Param"));
+ return NULL;
+ }
+ memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
+
+ p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
+ p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
+ p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
+ FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
+ p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
+
+ for(i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
+ p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
+
+ if (p_FmPcdParams->useHostCommand)
+ {
+ t_FmHcParams hcParams;
+
+ memset(&hcParams, 0, sizeof(hcParams));
+ hcParams.h_Fm = p_FmPcd->h_Fm;
+ hcParams.h_FmPcd = (t_Handle)p_FmPcd;
+ memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
+ p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
+ if (!p_FmPcd->h_Hc)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd HC"));
+ FM_PCD_Free(p_FmPcd);
+ return NULL;
+ }
+ }
+ else if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
+
+ if(p_FmPcdParams->kgSupport)
+ {
+ p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
+ if(!p_FmPcd->p_FmPcdKg)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Keygen"));
+ FM_PCD_Free(p_FmPcd);
+ return NULL;
+ }
+ }
+
+ if(p_FmPcdParams->plcrSupport)
+ {
+ p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
+ if(!p_FmPcd->p_FmPcdPlcr)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Policer"));
+ FM_PCD_Free(p_FmPcd);
+ return NULL;
+ }
+ }
+
+ if(p_FmPcdParams->prsSupport)
+ {
+ p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
+ if(!p_FmPcd->p_FmPcdPrs)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd Parser"));
+ FM_PCD_Free(p_FmPcd);
+ return NULL;
+ }
+ }
+
+ p_FmPcd->h_Spinlock = XX_InitSpinlock();
+ if (!p_FmPcd->h_Spinlock)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd spinlock"));
+ FM_PCD_Free(p_FmPcd);
+ return NULL;
+ }
+
+ p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
+
+ p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
+ p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
+ p_FmPcd->h_App = p_FmPcdParams->h_App;
+
+ return p_FmPcd;
+}
+
+t_Error FM_PCD_Init(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_Error err = E_OK;
+ t_FmPcdIpcMsg msg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ uint8_t isMasterAlive = 0;
+ t_FmPcdIpcReply reply;
+ uint32_t replyLength;
+
+ memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
+ if(Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
+ if(Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+
+ p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
+ if (p_FmPcd->h_IpcSession == NULL)
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM PCD Guest %d IPC session", p_FmPcd->guestId));
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_PCD_MASTER_IS_ALIVE;
+ msg.msgBody[0] = p_FmPcd->guestId;
+ blockingFlag = TRUE;
+
+ do
+ {
+ replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
+ (uint8_t*)&reply,
+ &replyLength,
+ FmPcdIpcMsgCompletionCB,
+ h_FmPcd)) != E_OK)
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ while(blockingFlag) ;
+ if(replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ isMasterAlive = *(uint8_t*)(reply.replyBody);
+ } while (!isMasterAlive);
+ }
+
+ CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
+
+ if(p_FmPcd->p_FmPcdKg)
+ {
+ err = KgInit(p_FmPcd);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ if(p_FmPcd->p_FmPcdPlcr)
+ {
+ err = PlcrInit(p_FmPcd);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ if(p_FmPcd->p_FmPcdPrs)
+ {
+ err = PrsInit(p_FmPcd);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ /* register to inter-core messaging mechanism */
+ memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
+ if(Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, FmPcdHandleIpcMsgCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ XX_Free(p_FmPcd->p_FmPcdDriverParam);
+ p_FmPcd->p_FmPcdDriverParam = NULL;
+
+ FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
+
+ return E_OK;
+}
+
+t_Error FM_PCD_Free(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
+ t_Error err = E_OK;
+
+ if(p_FmPcd->enabled)
+ FM_PCD_Disable(p_FmPcd);
+
+ if (p_FmPcd->h_Spinlock)
+ XX_FreeSpinlock(p_FmPcd->h_Spinlock);
+
+ if(p_FmPcd->p_FmPcdDriverParam)
+ {
+ XX_Free(p_FmPcd->p_FmPcdDriverParam);
+ p_FmPcd->p_FmPcdDriverParam = NULL;
+ }
+ if(p_FmPcd->p_FmPcdKg)
+ {
+ if((err = KgFree(p_FmPcd)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ XX_Free(p_FmPcd->p_FmPcdKg);
+ p_FmPcd->p_FmPcdKg = NULL;
+ }
+
+ if(p_FmPcd->p_FmPcdPlcr)
+ {
+ if((err = PlcrFree(p_FmPcd)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ XX_Free(p_FmPcd->p_FmPcdPlcr);
+ p_FmPcd->p_FmPcdPlcr = NULL;
+ }
+
+ if(p_FmPcd->p_FmPcdPrs)
+ {
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ PrsFree(p_FmPcd);
+ XX_Free(p_FmPcd->p_FmPcdPrs);
+ p_FmPcd->p_FmPcdPrs = NULL;
+ }
+
+ if (p_FmPcd->h_Hc)
+ {
+ FmHcFree(p_FmPcd->h_Hc);
+ p_FmPcd->h_Hc = NULL;
+ }
+
+ XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
+
+ FmUnregisterPcd(p_FmPcd->h_Fm);
+
+ XX_Free(p_FmPcd);
+ return E_OK;
+}
+
+t_Error FM_PCD_Enable(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ if(p_FmPcd->p_FmPcdKg)
+ KgEnable(p_FmPcd);
+
+ if(p_FmPcd->p_FmPcdPlcr)
+ PlcrEnable(p_FmPcd);
+
+ if(p_FmPcd->p_FmPcdPrs)
+ PrsEnable(p_FmPcd);
+
+ p_FmPcd->enabled = TRUE;
+ }
+ else
+ {
+ uint8_t enabled;
+ t_FmPcdIpcMsg msg;
+ t_FmPcdIpcReply reply;
+ uint32_t replyLength;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_PCD_MASTER_IS_ENABLED;
+ replyLength = sizeof(uint32_t) + sizeof(enabled);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t) + sizeof(enabled))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
+ if (!p_FmPcd->enabled)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
+ }
+
+ return E_OK;
+}
+
+t_Error FM_PCD_Disable(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_Error err = E_OK;
+ t_FmPcdIpcMsg msg;
+ t_FmPcdIpcReply reply;
+ uint32_t replyLength;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ if(p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Trying to disable a master partition PCD while guest partitions are still enabled."));
+
+ if(p_FmPcd->p_FmPcdKg)
+ KgDisable(p_FmPcd);
+
+ if(p_FmPcd->p_FmPcdPlcr)
+ PlcrDisable(p_FmPcd);
+
+ if(p_FmPcd->p_FmPcdPrs)
+ PrsDisable(p_FmPcd);
+
+ p_FmPcd->enabled = FALSE;
+
+ return E_OK;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_GUEST_DISABLE;
+ memset(&reply, 0, sizeof(reply));
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ return (t_Error)(reply.error);
+}
+
+t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t intFlags, specialUnits = 0;
+ uint8_t bitId = 0;
+ uint8_t i, j, k;
+ uint8_t netEnvCurrId;
+ uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
+ bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
+ uint8_t hdrNum;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
+
+ intFlags = FmPcdLock(p_FmPcd);
+
+ /* find a new netEnv */
+ for(i = 0;i<FM_MAX_NUM_OF_PORTS;i++)
+ if(!p_FmPcd->netEnvs[i].used)
+ break;
+
+ if(i== FM_MAX_NUM_OF_PORTS)
+ {
+ REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return NULL;
+ }
+
+ p_FmPcd->netEnvs[i].used = TRUE;
+
+ if (!TRY_LOCK(NULL, &p_FmPcd->netEnvs[i].lock))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return NULL;
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ netEnvCurrId = (uint8_t)i;
+
+ /* clear from previous use */
+ memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
+ memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_PRIVATE_HDRS * sizeof(t_FmPcdNetEnvAliases));
+ memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
+ p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
+
+ /* check that header with opt is not interchanged with the same header */
+ for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
+ {
+ for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
+ {
+ /* if an option exists, check that other headers are not the same header
+ without option */
+ if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
+ {
+ for (j=0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
+ if((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
+ !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
+ {
+ REPORT_ERROR(MINOR, E_FULL, ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
+ return NULL;
+ }
+ }
+ }
+ }
+
+ /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
+ /* check that header with opt is not interchanged with the same header */
+ for(i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
+ {
+ for(k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
+ {
+ /* Some headers pairs may not be defined on different units as the parser
+ doesn't distinguish */
+ if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
+ {
+ if (ipsecEspExists && (ipsecEspUnit != i))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
+ return NULL;
+ }
+ else
+ {
+ ipsecAhUnit = i;
+ ipsecAhExists = TRUE;
+ }
+ }
+ if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
+ {
+ if (ipsecAhExists && (ipsecAhUnit != i))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
+ return NULL;
+ }
+ else
+ {
+ ipsecEspUnit = i;
+ ipsecEspExists = TRUE;
+ }
+ }
+ if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
+ {
+ /* TODO - general coding. choose the free shim header */
+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
+ }
+ }
+ }
+
+ /* if private header (shim), check that no other headers specified */
+ for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
+ {
+ if(IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
+ if(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
+ return NULL;
+ }
+ }
+
+ for(i=0; i<p_NetEnvParams->numOfDistinctionUnits;i++)
+ {
+ if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
+ switch(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
+ {
+ case(HEADER_TYPE_USER_DEFINED_SHIM1):
+ if (shim1Selected)
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
+ return NULL;
+ }
+ shim1Selected = TRUE;
+ p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
+ break;
+ case(HEADER_TYPE_USER_DEFINED_SHIM2):
+ p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
+ }
+ else
+ {
+ p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
+
+ if(IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
+ p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
+ }
+ }
+
+ /* define a set of hardware parser LCV's according to the defined netenv */
+
+ /* set an array of LCV's for each header in the netEnv */
+ for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
+ {
+ /* private headers have no LCV in the hard parser */
+ if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
+ {
+ for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
+ {
+ GET_PRS_HDR_NUM(hdrNum, p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
+ if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
+ return NULL;
+ }
+ p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
+ }
+ }
+ }
+
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvCurrId].lock);
+
+ return UINT_TO_PTR((uint64_t)netEnvCurrId+1);
+}
+
+t_Error FM_PCD_DeleteNetEnvCharacteristics(t_Handle h_FmPcd, t_Handle h_NetEnv)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint8_t netEnvId = (uint8_t)(PTR_TO_UINT(h_NetEnv)-1);
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if (!TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->netEnvs[netEnvId].lock))
+ return ERROR_CODE(E_BUSY);
+ /* check that no port is bound to this netEnv */
+ if(p_FmPcd->netEnvs[netEnvId].owners)
+ {
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvId].lock);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
+ }
+ p_FmPcd->netEnvs[netEnvId].used= FALSE;
+ p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
+
+ memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
+ memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
+ memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
+
+ RELEASE_LOCK(p_FmPcd->netEnvs[netEnvId].lock);
+
+ return E_OK;
+}
+
+void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
+
+ FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
+}
+
+uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t replyLength, outCounter = 0;
+ t_FmPcdIpcMsg msg;
+ t_Error err;
+ t_FmPcdIpcReply reply;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_PCD_GET_COUNTER;
+ memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(uint32_t),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
+ return outCounter;
+ }
+
+ switch(counter)
+ {
+ case(e_FM_PCD_KG_COUNTERS_TOTAL):
+ if(!p_FmPcd->p_FmPcdKg)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters"));
+ return 0;
+ }
+ break;
+ case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
+ case(e_FM_PCD_PLCR_COUNTERS_RED):
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
+ case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
+ case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
+ if(!p_FmPcd->p_FmPcdPlcr)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters"));
+ return 0;
+ }
+ /* check that counters are enabled */
+ if(!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ return 0;
+ }
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
+ if(!p_FmPcd->p_FmPcdPrs)
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters"));
+ return 0;
+ }
+ break;
+ default:
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
+ return 0;
+ }
+ switch(counter)
+ {
+ case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pds);
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rrs);
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rrs);
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rrs);
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srrs);
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rres);
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rres);
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rres);
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srres);
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spcs);
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spscs);
+ case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->hxscs);
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrcs);
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrscs);
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwcs);
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwscs);
+ case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fcscs);
+ case(e_FM_PCD_KG_COUNTERS_TOTAL):
+ return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgtpc);
+
+ /*Policer statictics*/
+ case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
+ case(e_FM_PCD_PLCR_COUNTERS_RED):
+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
+ case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
+ case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
+
+ default:
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
+ return 0;
+ }
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdIpcMsg msg;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_DUMP_REGS;
+ return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ }
+ if (p_FmPcd->p_FmPcdKg)
+ return FM_PCD_KgDumpRegs(h_FmPcd);
+ if (p_FmPcd->p_FmPcdPlcr)
+ return FM_PCD_PlcrDumpRegs(h_FmPcd);
+ if (p_FmPcd->p_FmPcdPrs)
+ return FM_PCD_PrsDumpRegs(h_FmPcd);
+ return E_OK;
+}
+
+t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_STATE);
+
+ return FmHcDumpRegs(p_FmPcd->h_Hc);
+}
+
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t bitMask = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
+
+ GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_FmPcd->exceptions |= bitMask;
+ else
+ p_FmPcd->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t bitMask = 0, tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
+
+ GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
+
+ if(bitMask)
+ {
+ if (enable)
+ p_FmPcd->exceptions |= bitMask;
+ else
+ p_FmPcd->exceptions &= ~bitMask;
+
+ switch(exception)
+ {
+ case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
+ case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
+ if(!p_FmPcd->p_FmPcdKg)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
+ break;
+ case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
+ case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
+ case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
+ case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
+ if(!p_FmPcd->p_FmPcdPlcr)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
+ break;
+ case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
+ case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
+ if(!p_FmPcd->p_FmPcdPrs)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception"));
+
+ }
+
+ switch(exception)
+ {
+ case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer);
+ if(enable)
+ tmpReg |= FM_PCD_KG_DOUBLE_ECC;
+ else
+ tmpReg &= ~FM_PCD_KG_DOUBLE_ECC;
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer, tmpReg);
+ break;
+ case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer);
+ if(enable)
+ tmpReg |= FM_PCD_KG_KEYSIZE_OVERFLOW;
+ else
+ tmpReg &= ~FM_PCD_KG_KEYSIZE_OVERFLOW;
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgeeer, tmpReg);
+ break;
+ case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer);
+ if(enable)
+ tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
+ else
+ tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer, tmpReg);
+ break;
+ case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever);
+ if(enable)
+ tmpReg |= FM_PCD_PRS_SINGLE_ECC;
+ else
+ tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever, tmpReg);
+ break;
+ case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
+ if(enable)
+ tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
+ else
+ tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
+ break;
+ case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
+ if(enable)
+ tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
+ else
+ tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
+ break;
+ case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
+ if(enable)
+ tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
+ else
+ tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
+ break;
+ case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
+ if(enable)
+ tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
+ else
+ tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported exception"));
+ }
+ /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
+ Driver may disable them automatically, depending on driver's status */
+ if(enable && ( (exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
+ (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
+ (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
+ (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
+ FmEnableRamsEcc(p_FmPcd->h_Fm);
+ if(!enable && ( (exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
+ (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
+ (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
+ (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
+ FmDisableRamsEcc(p_FmPcd->h_Fm);
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
+
+ switch(exception)
+ {
+ case(e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
+ case(e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
+ if(!p_FmPcd->p_FmPcdKg)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
+ break;
+ case(e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
+ case(e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
+ case(e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
+ case(e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
+ if(!p_FmPcd->p_FmPcdPlcr)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
+ break;
+ case(e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
+ case(e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
+ if(!p_FmPcd->p_FmPcdPrs)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid interrupt requested"));
+
+ }
+ switch(exception)
+ {
+ case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr, FM_PCD_PRS_DOUBLE_ECC);
+ break;
+ case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr, FM_PCD_PRS_SINGLE_ECC);
+ break;
+ case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_KG_DOUBLE_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, FM_PCD_KG_DOUBLE_ECC);
+ break;
+ case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_KG_KEYSIZE_OVERFLOW))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgfeer, FM_PCD_KG_KEYSIZE_OVERFLOW);
+ break;
+ case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
+ break;
+ case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
+ break;
+ case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
+ break;
+ case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
+ }
+
+ return E_OK;
+}
+
+
+t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
+
+ switch(counter)
+ {
+ case(e_FM_PCD_KG_COUNTERS_TOTAL):
+ if(!p_FmPcd->p_FmPcdKg)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters - keygen is not working"));
+ break;
+ case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
+ case(e_FM_PCD_PLCR_COUNTERS_RED):
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
+ case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
+ case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
+ if(!p_FmPcd->p_FmPcdPlcr)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this counters - Policer is not working"));
+ if(!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
+ case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
+ if(!p_FmPcd->p_FmPcdPrs)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
+ }
+ switch(counter)
+ {
+ case(e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pds, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rrs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rrs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rrs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srrs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l2rres, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l3rres, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->l4rres, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->srres, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spcs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->spscs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->hxscs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrcs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mrscs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwcs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->mwscs, value);
+ break;
+ case(e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fcscs, value);
+ break;
+ case(e_FM_PCD_KG_COUNTERS_TOTAL):
+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->kgtpc,value);
+ break;
+
+ /*Policer counters*/
+ case(e_FM_PCD_PLCR_COUNTERS_YELLOW):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
+ break;
+ case(e_FM_PCD_PLCR_COUNTERS_RED):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
+ break;
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
+ break;
+ case(e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
+ break;
+ case(e_FM_PCD_PLCR_COUNTERS_TOTAL):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
+ break;
+ case(e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
+ }
+
+return E_OK;
+}
+
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h
new file mode 100644
index 0000000..55ae47a
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.h
@@ -0,0 +1,715 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_pcd.h
+
+ @Description FM PCD ...
+*//***************************************************************************/
+#ifndef __FM_PCD_H
+#define __FM_PCD_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+#include "list_ext.h"
+#include "fm_pcd_ext.h"
+
+
+#define __ERR_MODULE__ MODULE_FM_PCD
+
+
+/**************************************************************************//**
+ @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
+ @{
+*//***************************************************************************/
+
+/****************************/
+/* Network defines */
+/****************************/
+#define UDP_HEADER_SIZE 8
+
+#define ESP_SPI_OFFSET 0
+#define ESP_SPI_SIZE 4
+#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
+#define ESP_SEQ_NUM_SIZE 4
+
+/****************************/
+/* General defines */
+/****************************/
+#define ILLEGAL_CLS_PLAN 0xff
+#define ILLEGAL_NETENV 0xff
+/****************************/
+/* Error defines */
+/****************************/
+#define FM_PCD_EX_KG_DOUBLE_ECC 0x80000000
+#define FM_PCD_EX_KG_KEYSIZE_OVERFLOW 0x40000000
+
+#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
+#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
+#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
+#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
+
+#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
+#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
+
+#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
+switch(exception){ \
+ case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
+ bitMask = FM_PCD_EX_KG_DOUBLE_ECC; break; \
+ case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
+ bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
+ case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
+ bitMask = FM_PCD_EX_KG_KEYSIZE_OVERFLOW; break; \
+ case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
+ bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
+ case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
+ bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
+ case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
+ bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
+ case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
+ bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
+ case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
+ bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
+ default: bitMask = 0;break;}
+
+/***********************************************************************/
+/* SW parser L4 shells patch */
+/***********************************************************************/
+#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb
+#define SW_PRS_L4_PATCH \
+{ 0x31,0x92,0x02,0x1f,0x00,0x32,0x00,0x78, \
+ 0x00,0x34,0x32,0xf0,0x00,0x50,0x00,0x0c, \
+ 0x28,0x5e,0x83,0x8e,0x29,0x32,0xaf,0x8e, \
+ 0x31,0xb2,0x9f,0xff,0x00,0x06,0xaf,0xbf, \
+ 0x00,0x06,0x29,0x36,0x00,0x01,0x1b,0xff, \
+ 0x32,0xf0,0x00,0x50,0x00,0x08,0x28,0x5e, \
+ 0x08,0x99,0x00,0x00,0x9f,0x8e,0x31,0xb2, \
+ 0x9f,0xff,0x00,0x06,0x29,0x36,0x00,0x01, \
+ 0x1b,0xff,0x32,0xf0,0x00,0x50,0x00,0x04, \
+ 0x28,0x5e,0x8f,0x9e,0x29,0x32,0x31,0xb2, \
+ 0x8f,0xbf,0x00,0x06,0x29,0x36,0x00,0x01, \
+ 0x1b,0xff,0x32,0xf0,0x00,0x50,0x00,0x04, \
+ 0x28,0x5e,0x8f,0x9e,0x29,0x32,0x31,0xb2, \
+ 0x8f,0xbf,0x00,0x06,0x29,0x36,0x00,0x01, \
+ 0x1b,0xff,0x00,0x00,0x00,0x00,0x00,0x00};
+
+#define SW_PRS_L4_PATCH_SIZE 120
+#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */
+
+/****************************/
+/* Parser defines */
+/****************************/
+/* masks */
+#define PRS_ERR_CAP 0x80000000
+#define PRS_ERR_TYPE_DOUBLE 0x40000000
+#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
+#define PRS_ERR_ADDR_MASK 0x000001FF
+#define FM_PCD_PRS_RPIMAC_EN 0x00000001
+#define FM_PCD_PRS_SINGLE_ECC 0x00004000
+#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
+#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
+#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
+
+/* others */
+#define PRS_MAX_CYCLE_LIMIT 8191
+#define PRS_SW_DATA 0x00000800
+#define PRS_REGS_OFFSET 0x00000840
+
+#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
+ prsPortId = (uint8_t)(hardwarePortId & 0x0f)
+
+#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
+ bitMask = 0x80000000>>prsPortId
+
+/***********************************************************************/
+/* Keygen defines */
+/***********************************************************************/
+/* Masks */
+#define FM_PCD_KG_KGGCR_EN 0x80000000
+#define KG_SCH_GEN_VALID 0x80000000
+#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
+#define KG_ERR_CAP 0x80000000
+#define KG_ERR_TYPE_DOUBLE 0x40000000
+#define KG_ERR_ADDR_MASK 0x00000FFF
+#define FM_PCD_KG_DOUBLE_ECC 0x80000000
+#define FM_PCD_KG_KEYSIZE_OVERFLOW 0x40000000
+#define KG_SCH_MODE_EN 0x80000000
+
+/* shifts */
+#define FM_PCD_KG_PE_CPP_MASK_SHIFT 16
+#define FM_PCD_KG_KGAR_WSEL_SHIFT 8
+
+/* others */
+#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
+#define NO_VALIDATION 0x70
+#define KG_ACTION_REG_TO 1024
+#define KG_MAX_PROFILE 255
+#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
+
+typedef struct {
+ bool known;
+ uint8_t id;
+} t_FmPcdKgSchemesExtractsEntry;
+
+typedef struct {
+ t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
+} t_FmPcdKgSchemesExtracts;
+
+/***********************************************************************/
+/* Policer defines */
+/***********************************************************************/
+
+/* masks */
+#define FM_PCD_PLCR_PEMODE_PI 0x80000000
+#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
+#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
+#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
+#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
+#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
+#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
+#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
+#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
+#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
+#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
+#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
+#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
+#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
+#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
+#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
+#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
+#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
+#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
+#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
+#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
+#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
+#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
+#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
+#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
+#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
+#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
+#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
+#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
+
+#define FM_PCD_PLCR_NIA_VALID 0x80000000
+
+#define FM_PCD_PLCR_GCR_EN 0x80000000
+#define FM_PCD_PLCR_GCR_STEN 0x40000000
+#define FM_PCD_PLCR_GCR_DAR 0x20000000
+#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
+#define FM_PCD_PLCR_NIA_ABS 0x00000100
+
+#define FM_PCD_PLCR_GSR_BSY 0x80000000
+#define FM_PCD_PLCR_GSR_DQS 0x60000000
+#define FM_PCD_PLCR_GSR_RPB 0x20000000
+#define FM_PCD_PLCR_GSR_FQS 0x0C000000
+#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
+#define FM_PCD_PLCR_GSR_LPCA 0x00003000
+#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
+
+#define FM_PCD_PLCR_EVR_PSIC 0x80000000
+#define FM_PCD_PLCR_EVR_AAC 0x40000000
+
+#define FM_PCD_PLCR_PAR_PSI 0x20000000
+#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
+/* PWSEL Selctive select options */
+#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
+#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
+#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
+#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
+#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
+#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
+#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
+#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
+#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
+#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
+#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
+#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
+#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
+#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
+#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
+#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
+
+#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
+ 1-> 2^N specific locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
+ 2-> 2^(N-1) base locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
+ 4-> 2^(N-2) base locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
+ 8->2^(N-3) base locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
+ 16-> 2^(N-4) base locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
+ 32-> 2^(N-5) base locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
+ 64-> 2^(N-6) base locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
+ 128-> 2^(N-7) base locations. */
+#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
+ When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
+
+#define FM_PCD_PLCR_PMR_V 0x80000000
+#define PLCR_ERR_ECC_CAP 0x80000000
+#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
+#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
+#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
+
+#define PLCR_ERR_UNINIT_CAP 0x80000000
+#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
+#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
+#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
+
+/* shifts */
+#define PLCR_ERR_ECC_PNUM_SHIFT 4
+#define PLCR_ERR_UNINIT_PID_SHIFT 16
+
+#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
+
+/* others */
+#define WAIT_FOR_PLCR_EVR_AAC \
+{\
+ uint32_t count = 0; \
+ uint32_t tmpReg32; \
+ while (count < FM_PCD_PLCR_POLL) \
+ { \
+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->fmpl_evr);\
+ if (!( tmpReg32 & FM_PCD_PLCR_EVR_AAC)) break;\
+ count++;\
+ }\
+}
+
+#define WAIT_FOR_PLCR_PAR_GO \
+{\
+ uint32_t count = 0; \
+ uint32_t tmpReg32; \
+ while (count < FM_PCD_PLCR_POLL) \
+ { \
+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->fmpl_par);\
+ if (!( tmpReg32 & FM_PCD_PLCR_PAR_GO)) break;\
+ count++; \
+ }\
+}
+
+#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
+
+/****************************/
+/* Defaults */
+/****************************/
+#define DEFAULT_plcrAutoRefresh FALSE
+#define DEFAULT_prsMaxParseCycleLimit 0
+#define DEFAULT_fmPcdKgErrorExceptions (FM_PCD_EX_KG_DOUBLE_ECC | FM_PCD_EX_KG_KEYSIZE_OVERFLOW)
+#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
+#define DEFAULT_fmPcdPlcrExceptions 0
+#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
+
+#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
+#define DEFAULT_numOfUsedProfilesPerWindow 16
+#define DEFAULT_numOfSharedPlcrProfiles 4
+
+/***********************************************************************/
+/* Memory map */
+/***********************************************************************/
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct {
+ volatile uint32_t kgoe_sp;
+ volatile uint32_t kgoe_cpp;
+} _PackedType t_FmPcdKgPortConfigRegs;
+
+typedef _Packed struct {
+ volatile uint32_t kgcpe[8];
+} _PackedType t_FmPcdKgClsPlanRegs;
+
+typedef _Packed union {
+ t_FmPcdKgInterModuleSchemeRegs schemeRegs;
+ t_FmPcdKgPortConfigRegs portRegs;
+ t_FmPcdKgClsPlanRegs clsPlanRegs;
+} _PackedType u_FmPcdKgIndirectAccessRegs;
+
+typedef _Packed struct {
+ volatile uint32_t kggcr;
+ volatile uint32_t res0;
+ volatile uint32_t res1;
+ volatile uint32_t kgeer;
+ volatile uint32_t kgeeer;
+ volatile uint32_t res2;
+ volatile uint32_t res3;
+ volatile uint32_t kgseer;
+ volatile uint32_t kgseeer;
+ volatile uint32_t kggsr;
+ volatile uint32_t kgtpc;
+ volatile uint32_t kgserc;
+ volatile uint32_t res4[4];
+ volatile uint32_t kgfdor;
+ volatile uint32_t kggdv0r;
+ volatile uint32_t kggdv1r;
+ volatile uint32_t res5[5];
+ volatile uint32_t kgfer;
+ volatile uint32_t kgfeer;
+ volatile uint32_t res6[38];
+ u_FmPcdKgIndirectAccessRegs indirectAccessRegs;
+ volatile uint32_t res[42]; /*(0xfc-sizeof(u_FmPcdKgIndirectAccessRegs))/4 */
+ volatile uint32_t kgar;
+} _PackedType t_FmPcdKgRegs;
+
+typedef _Packed struct {
+/* General Configuration and Status Registers */
+ volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
+ volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
+ volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
+ volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
+ volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
+ volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
+ volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
+ volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
+/* Global Statistic Counters */
+ volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
+ volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
+ volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
+ volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
+ volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
+ volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
+ volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
+/* Profile RAM Access Registers */
+ volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
+ t_FmPcdPlcrInterModuleProfileRegs profileRegs;
+/* Error Capture Registers */
+ volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
+ volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
+ volatile uint32_t fmpl_res2; /* 0x108 Reserved */
+/* Debug Registers */
+ volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
+/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
+ volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
+ volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
+ (for port-ID 1-11, only for supported Port-ID registers) */
+} _PackedType t_FmPcdPlcrRegs;
+
+typedef _Packed struct {
+ volatile uint32_t rpclim;
+ volatile uint32_t rpimac;
+ volatile uint32_t pmeec;
+ volatile uint32_t res1[5];
+ volatile uint32_t pevr;
+ volatile uint32_t pever;
+ volatile uint32_t pevfr;
+ volatile uint32_t perr;
+ volatile uint32_t perer;
+ volatile uint32_t perfr;
+ volatile uint32_t res2[0xA];
+ volatile uint32_t ppsc;
+ volatile uint32_t res3;
+ volatile uint32_t pds;
+ volatile uint32_t l2rrs;
+ volatile uint32_t l3rrs;
+ volatile uint32_t l4rrs;
+ volatile uint32_t srrs;
+ volatile uint32_t l2rres;
+ volatile uint32_t l3rres;
+ volatile uint32_t l4rres;
+ volatile uint32_t srres;
+ volatile uint32_t spcs;
+ volatile uint32_t spscs;
+ volatile uint32_t hxscs;
+ volatile uint32_t mrcs;
+ volatile uint32_t mwcs;
+ volatile uint32_t mrscs;
+ volatile uint32_t mwscs;
+ volatile uint32_t fcscs;
+} _PackedType t_FmPcdPrsRegs;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/***********************************************************************/
+/* Driver's internal structures */
+/***********************************************************************/
+
+typedef struct {
+ t_Handle h_Manip;
+ bool keepRes;
+ e_FmPcdEngine nextEngine;
+ uint8_t parseCode;
+} t_FmPcdInfoForManip;
+
+/**************************************************************************//**
+ @Description A structure of parameters to communicate
+ between the port and PCD regarding the KG scheme.
+*//***************************************************************************/
+typedef struct {
+ uint8_t netEnvId; /* in */
+ uint8_t numOfDistinctionUnits; /* in */
+ uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
+ uint32_t vector; /* out */
+} t_NetEnvParams;
+
+typedef struct {
+ volatile bool lock;
+ bool used;
+ uint8_t owners;
+ uint8_t netEnvId;
+ uint8_t guestId;
+ uint8_t baseEntry;
+ uint16_t sizeOfGrp;
+ protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
+} t_FmPcdKgClsPlanGrp;
+
+typedef struct {
+ volatile bool lock;
+ bool valid;
+ uint8_t netEnvId;
+ uint8_t owners;
+ uint32_t matchVector;
+ uint32_t ccUnits;
+ bool nextRelativePlcrProfile;
+ uint16_t relativeProfileId;
+ uint16_t numOfProfiles;
+ t_FmPcdKgKeyOrder orderedArray;
+ e_FmPcdEngine nextEngine;
+ e_FmPcdDoneAction doneAction;
+ uint8_t pointedOwners;
+ uint32_t requiredAction;
+ bool extractedOrs;
+ uint8_t bitOffsetInPlcrProfile;
+ bool directPlcr;
+} t_FmPcdKgScheme;
+
+typedef struct {
+ bool allocated;
+ uint8_t ownerId; /* guestId for KG in multi-partition only,
+ portId for PLCR in any environment */
+} t_FmPcdAllocMng;
+
+typedef struct {
+ t_FmPcdKgRegs *p_FmPcdKgRegs;
+ uint32_t schemeExceptionsBitMask;
+ uint8_t numOfSchemes;
+ uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
+ t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
+ t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
+ uint8_t emptyClsPlanGrpId;
+ t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
+ t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
+} t_FmPcdKg;
+
+typedef struct {
+ uint16_t profilesBase;
+ uint16_t numOfProfiles;
+ t_Handle h_FmPort;
+} t_FmPcdPlcrMapParam;
+
+typedef struct {
+ bool valid;
+ volatile bool lock;
+ t_FmPcdAllocMng profilesMng;
+ uint8_t pointedOwners;
+ uint32_t requiredAction;
+ e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
+ u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
+
+ e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
+ u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
+
+ e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
+ u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
+} t_FmPcdPlcrProfile;
+
+typedef struct {
+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
+ t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
+ uint16_t numOfSharedProfiles;
+ uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
+ t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
+} t_FmPcdPlcr;
+
+typedef struct {
+ uint32_t *p_SwPrsCode;
+ uint32_t *p_CurrSwPrs;
+ uint8_t currLabel;
+ t_FmPcdPrsRegs *p_FmPcdPrsRegs;
+ t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
+ uint32_t fmPcdPrsPortIdStatistics;
+} t_FmPcdPrs;
+
+typedef struct {
+ struct {
+ e_NetHeaderType hdr;
+ protocolOpt_t opt; /* only one option !! */
+ } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
+} t_FmPcdIntDistinctionUnit;
+
+typedef struct {
+ e_NetHeaderType hdr;
+ e_NetHeaderType aliasHdr;
+} t_FmPcdNetEnvAliases;
+
+typedef struct {
+ volatile bool lock;
+ bool used;
+ uint8_t owners;
+ uint8_t clsPlanGrpId;
+ t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
+ uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
+ uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
+ uint32_t macsecVector;
+ t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_PRIVATE_HDRS];
+} t_FmPcdNetEnv;
+
+typedef struct {
+ bool plcrAutoRefresh;
+
+ uint16_t prsMaxParseCycleLimit;
+} t_FmPcdDriverParam;
+
+typedef struct {
+ t_Handle h_Fm;
+ t_Handle h_FmMuram;
+ uint64_t physicalMuramBase;
+ volatile bool lock;
+ t_Handle h_Spinlock;
+ t_Handle h_IpcSession; /* relevant for guest only */
+ bool enabled;
+ uint8_t guestId; /**< Guest Partition Id */
+ uint8_t numOfEnabledGuestPartitionsPcds;
+ char fmPcdModuleName[MODULE_NAME_SIZE];
+ char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
+ t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
+ t_FmPcdKg *p_FmPcdKg;
+ t_FmPcdPlcr *p_FmPcdPlcr;
+ t_FmPcdPrs *p_FmPcdPrs;
+
+ t_Handle h_Hc;
+
+ uint32_t exceptions;
+ t_FmPcdExceptionCallback *f_Exception;
+ t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
+ t_Handle h_App;
+
+ t_FmPcdDriverParam *p_FmPcdDriverParam;
+} t_FmPcd;
+
+
+/***********************************************************************/
+/* PCD internal routines */
+/***********************************************************************/
+
+/**************************************************************************//**
+
+ @Group FM_PCD_InterModule_grp FM PCD Inter-Module Unit
+
+ @Description FM PCD Inter Module functions -
+ These are not User API routines but routines that may be called
+ from other modules. This will be the case in a single core environment,
+ where instead of useing the XX messeging mechanism, the routines may be
+ called from other modules. In a multicore environment, the other modules may
+ be run by other cores and therefor these routines may not be called directly.
+
+ @{
+*//***************************************************************************/
+
+t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
+t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
+bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
+t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
+void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
+e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
+uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
+
+t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
+t_Error KgInit(t_FmPcd *p_FmPcd);
+t_Error KgFree(t_FmPcd *p_FmPcd);
+void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
+bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
+void KgEnable(t_FmPcd *p_FmPcd);
+void KgDisable(t_FmPcd *p_FmPcd);
+t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
+void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
+
+/* only for MULTI partittion */
+t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
+t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
+/* only for SINGLE partittion */
+t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
+
+t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
+t_Error PlcrInit(t_FmPcd *p_FmPcd);
+t_Error PlcrFree(t_FmPcd *p_FmPcd);
+void PlcrEnable(t_FmPcd *p_FmPcd);
+void PlcrDisable(t_FmPcd *p_FmPcd);
+t_Error PlcrFreeProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t num, uint16_t base);
+t_Error PlcrAllocProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t *p_Base);
+t_Error PlcrAllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds);
+void PlcrFreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds);
+
+t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
+t_Error PrsInit(t_FmPcd *p_FmPcd);
+void PrsEnable(t_FmPcd *p_FmPcd);
+void PrsDisable(t_FmPcd *p_FmPcd);
+void PrsFree(t_FmPcd *p_FmPcd );
+t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
+
+t_Handle FmPcdCcConfig(t_Handle h_FmPcd, t_FmPcdParams *p_FmPcdParams);
+t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
+uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
+uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
+uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
+
+void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
+t_Error FmPcdManipCheckParamsForCcNextEgine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
+void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew);
+void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
+uint32_t FmPcdManipCheckNia(t_Handle h_FmPcd, t_Handle h_Ad);
+void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
+t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
+
+static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ ASSERT_COND(p_FmPcd);
+ return p_FmPcd->h_FmMuram;
+}
+
+static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ ASSERT_COND(p_FmPcd);
+ return p_FmPcd->physicalMuramBase;
+}
+
+
+#endif /* __FM_PCD_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h
new file mode 100644
index 0000000..800a72b
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_pcd_ipc.h
@@ -0,0 +1,326 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_pcd_ipc.h
+
+ @Description FM PCD Inter-Partition prototypes, structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_PCD_IPC_H
+#define __FM_PCD_IPC_H
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/**************************************************************************//**
+ @Description Structure for getting a sw parser address according to a label
+ Fields commented 'IN' are passed by the port module to be used
+ by the FM module.
+ Fields commented 'OUT' will be filled by FM before returning to port.
+*//***************************************************************************/
+typedef _Packed struct t_FmPcdIpcSwPrsLable
+{
+ uint32_t enumHdr; /**< IN. The existance of this header will envoke
+ the sw parser code. */
+ uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
+ attachments for the same header, use this
+
+ index to distinguish between them. */
+} _PackedType t_FmPcdIpcSwPrsLable;
+
+/**************************************************************************//**
+ @Description Structure for port-PCD communication.
+ Fields commented 'IN' are passed by the port module to be used
+ by the FM module.
+ Fields commented 'OUT' will be filled by FM before returning to port.
+ Some fields are optional (depending on configuration) and
+ will be analized by the port and FM modules accordingly.
+*//***************************************************************************/
+typedef struct t_FmPcdIpcKgSchemesParams
+{
+ uint8_t guestId; /**< IN */
+ uint8_t numOfSchemes; /**< IN */
+ uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; /**< OUT */
+} _PackedType t_FmPcdIpcKgSchemesParams;
+
+typedef struct t_FmPcdIpcKgClsPlanParams
+{
+ uint8_t guestId; /**< IN */
+ uint16_t numOfClsPlanEntries; /**< IN */
+ uint8_t clsPlanBase; /**< IN in alloc only */
+} _PackedType t_FmPcdIpcKgClsPlanParams;
+
+typedef _Packed struct t_FmPcdIpcPlcrAllocParams
+{
+ uint16_t num;
+ uint8_t hardwarePortId;
+ uint16_t plcrProfilesBase;
+} _PackedType t_FmPcdIpcPlcrAllocParams;
+
+typedef _Packed struct t_FmPcdIpcSharedPlcrAllocParams
+{
+ uint16_t num; /**< IN */
+ //uint16_t profilesIds[FM_PCD_PLCR_NUM_ENTRIES]; /**< OUT */
+ uint32_t sharedProfilesMask[8];
+} _PackedType t_FmPcdIpcSharedPlcrAllocParams;
+
+typedef _Packed struct t_FmPcdIpcPrsIncludePort
+{
+ uint8_t hardwarePortId; /* IN */
+ bool include; /* IN */
+} _PackedType t_FmPcdIpcPrsIncludePort;
+
+
+#define FM_PCD_MAX_REPLY_SIZE 16
+#define FM_PCD_MAX_MSG_SIZE 36
+#define FM_PCD_MAX_REPLY_BODY_SIZE 36
+
+typedef _Packed struct
+{
+ uint32_t msgId;
+ uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
+} _PackedType t_FmPcdIpcMsg;
+
+typedef _Packed struct t_FmPcdIpcReply
+{
+ uint32_t error;
+ uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
+} _PackedType t_FmPcdIpcReply;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+
+/**************************************************************************//**
+ @Function FM_PCD_ALLOC_KG_SCHEMES
+
+ @Description Used by FM PCD front-end in order to allocate KG resources
+
+ @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
+*//***************************************************************************/
+#define FM_PCD_ALLOC_KG_SCHEMES 3
+
+/**************************************************************************//**
+ @Function FM_PCD_FREE_KG_SCHEMES
+
+ @Description Used by FM PCD front-end in order to Free KG resources
+
+ @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
+*//***************************************************************************/
+#define FM_PCD_FREE_KG_SCHEMES 4
+
+/**************************************************************************//**
+ @Function FM_PCD_ALLOC_PROFILES
+
+ @Description Used by FM PCD front-end in order to allocate Policer profiles
+
+ @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
+*//***************************************************************************/
+#define FM_PCD_ALLOC_PROFILES 5
+
+/**************************************************************************//**
+ @Function FM_PCD_FREE_PROFILES
+
+ @Description Used by FM PCD front-end in order to Free Policer profiles
+
+ @Param[in/out] t_FmPcdIpcPlcrAllocParams Pointer
+*//***************************************************************************/
+#define FM_PCD_FREE_PROFILES 6
+
+/**************************************************************************//**
+ @Function FM_PCD_GET_PHYS_MURAM_BASE
+
+ @Description Used by FM PCD front-end in order to get MURAM base address
+
+ @Param[in/out] t_FmPcdIcPhysAddr Pointer
+*//***************************************************************************/
+#define FM_PCD_GET_PHYS_MURAM_BASE 7
+
+/**************************************************************************//**
+ @Function FM_PCD_GET_SW_PRS_OFFSET
+
+ @Description Used by FM front-end to get the SW parser offset of the start of
+ code relevant to a given label.
+
+ @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
+*//***************************************************************************/
+#define FM_PCD_GET_SW_PRS_OFFSET 8
+
+/**************************************************************************//**
+ @Function FM_PCD_ALLOC_SHARED_PROFILES
+
+ @Description Used by FM PCD front-end in order to allocate shared profiles
+
+ @Param[in/out] t_FmPcdIpcSharedPlcrAllocParams Pointer
+*//***************************************************************************/
+#define FM_PCD_ALLOC_SHARED_PROFILES 9
+
+/**************************************************************************//**
+ @Function FM_PCD_FREE_SHARED_PROFILES
+
+ @Description Used by FM PCD front-end in order to free shared profiles
+
+ @Param[in/out] t_FmPcdIpcSharedPlcrAllocParams Pointer
+*//***************************************************************************/
+#define FM_PCD_FREE_SHARED_PROFILES 10
+
+/**************************************************************************//**
+ @Function FM_PCD_MASTER_IS_ENABLED
+
+ @Description Used by FM front-end in order to verify
+ PCD enablement.
+
+ @Param[in] bool Pointer
+*//***************************************************************************/
+#define FM_PCD_MASTER_IS_ENABLED 15
+
+/**************************************************************************//**
+ @Function FM_PCD_GUEST_DISABLE
+
+ @Description Used by FM front-end to inform back-end when
+ front-end PCD is disabled
+
+ @Param[in] None
+*//***************************************************************************/
+#define FM_PCD_GUEST_DISABLE 16
+
+/**************************************************************************//**
+ @Function FM_PCD_DUMP_REGS
+
+ @Description Used by FM front-end to dump all PCD registers
+
+ @Param[in] None
+*//***************************************************************************/
+#define FM_PCD_DUMP_REGS 17
+
+/**************************************************************************//**
+ @Function FM_PCD_KG_DUMP_REGS
+
+ @Description Used by FM front-end to dump KG registers
+
+ @Param[in] None
+*//***************************************************************************/
+#define FM_PCD_KG_DUMP_REGS 18
+
+/**************************************************************************//**
+ @Function FM_PCD_PLCR_DUMP_REGS
+
+ @Description Used by FM front-end to dump PLCR registers
+
+ @Param[in] None
+*//***************************************************************************/
+#define FM_PCD_PLCR_DUMP_REGS 19
+
+/**************************************************************************//**
+ @Function FM_PCD_PLCR_PROFILE_DUMP_REGS
+
+ @Description Used by FM front-end to dump PLCR specified profile registers
+
+ @Param[in] t_Handle Pointer
+*//***************************************************************************/
+#define FM_PCD_PLCR_PROFILE_DUMP_REGS 20
+
+/**************************************************************************//**
+ @Function FM_PCD_PRS_DUMP_REGS
+
+ @Description Used by FM front-end to dump PRS registers
+
+ @Param[in] None
+*//***************************************************************************/
+#define FM_PCD_PRS_DUMP_REGS 21
+
+/**************************************************************************//**
+ @Function FM_PCD_FREE_KG_CLSPLAN
+
+ @Description Used by FM PCD front-end in order to Free KG classification plan entries
+
+ @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
+*//***************************************************************************/
+#define FM_PCD_FREE_KG_CLSPLAN 22
+
+/**************************************************************************//**
+ @Function FM_PCD_ALLOC_KG_CLSPLAN
+
+ @Description Used by FM PCD front-end in order to allocate KG classification plan entries
+
+ @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
+*//***************************************************************************/
+#define FM_PCD_ALLOC_KG_CLSPLAN 23
+
+/**************************************************************************//**
+ @Function FM_PCD_MASTER_IS_ALIVE
+
+ @Description Used by FM front-end to check that back-end exists
+
+ @Param[in] None
+*//***************************************************************************/
+#define FM_PCD_MASTER_IS_ALIVE 24
+
+/**************************************************************************//**
+ @Function FM_PCD_GET_COUNTER
+
+ @Description Used by FM front-end to read PCD counters
+
+ @Param[in/out] t_FmPcdIpcGetCounter Pointer
+*//***************************************************************************/
+#define FM_PCD_GET_COUNTER 25
+
+/**************************************************************************//**
+ @Function FM_PCD_PRS_INC_PORT_STATS
+
+ @Description Used by FM front-end to set/clear statistics for port
+
+ @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
+*//***************************************************************************/
+#define FM_PCD_PRS_INC_PORT_STATS 26
+/** @} */ /* end of FM_PCD_IPC_grp group */
+/** @} */ /* end of FM_grp group */
+
+
+#endif /* __FM_PCD_IPC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c
new file mode 100644
index 0000000..b9f5128
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c
@@ -0,0 +1,1702 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_plcr.c
+
+ @Description FM PCD POLICER...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "debug_ext.h"
+#include "net_ext.h"
+#include "fm_ext.h"
+
+#include "fm_common.h"
+#include "fm_pcd.h"
+#include "fm_hc.h"
+#include "fm_pcd_ipc.h"
+
+
+static bool FmPcdPlcrIsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint16_t i;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
+
+ for(i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
+ if(p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
+ return TRUE;
+ return FALSE;
+}
+
+static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
+{
+ uint32_t nia;
+ uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_NextEngineParams->h_Profile)-1);
+ uint8_t relativeSchemeId, physicatSchemeId;
+
+ nia = FM_PCD_PLCR_NIA_VALID;
+
+ switch (nextEngine)
+ {
+ case e_FM_PCD_DONE :
+ switch (p_NextEngineParams->action)
+ {
+ case e_FM_PCD_DROP_FRAME :
+ nia |= (NIA_ENG_BMI | NIA_BMI_AC_DISCARD);
+ break;
+ case e_FM_PCD_ENQ_FRAME:
+ nia |= (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ break;
+ case e_FM_PCD_KG:
+ physicatSchemeId = (uint8_t)(PTR_TO_UINT(p_NextEngineParams->h_DirectScheme)-1);
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicatSchemeId);
+ if(relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
+ if (!FmPcdKgIsSchemeValidSw(p_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
+ if(!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
+ nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicatSchemeId;
+ break;
+ case e_FM_PCD_PLCR:
+ if(!FmPcdPlcrIsProfileShared(p_FmPcd, absoluteProfileId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
+ if(!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
+ nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ *nextAction = nia;
+
+ return E_OK;
+}
+
+static uint32_t FPP_Function(uint32_t fpp)
+{
+ if(fpp > 15)
+ return 15 - (0x1f - fpp);
+ else
+ return 16 + fpp;
+}
+
+static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
+ uint32_t rate,
+ uint64_t tsuInTenthNano,
+ uint32_t fppShift,
+ uint64_t *p_Integer,
+ uint64_t *p_Fraction)
+{
+ uint64_t tmp, div;
+
+ if(rateMode == e_FM_PCD_PLCR_BYTE_MODE)
+ {
+ /* now we calculate the initial integer for the bigger rate */
+ /* from Kbps to Bytes/TSU */
+ tmp = (uint64_t)rate;
+ tmp *= 1000; /* kb --> b */
+ tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
+
+ div = 1000000000; /* nano */
+ div *= 10; /* 10 nano */
+ div *= 8; /* bit to byte */
+ }
+ else
+ {
+ /* now we calculate the initial integer for the bigger rate */
+ /* from Kbps to Bytes/TSU */
+ tmp = (uint64_t)rate;
+ tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
+
+ div = 1000000000; /* nano */
+ div *= 10; /* 10 nano */
+ }
+ *p_Integer = (tmp<<fppShift)/div;
+
+ /* for calculating the fraction, we will recalculate cir and deduct the integer.
+ * For precision, we will multiply by 2^16. we do not divid back, since we write
+ * this value as fraction - see spec.
+ */
+ *p_Fraction = (((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div))/div;
+}
+
+/* .......... */
+
+static void calcRates(t_Handle h_FmPcd, t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
+ uint32_t *cir, uint32_t *cbs, uint32_t *pir_eir, uint32_t *pbs_ebs, uint32_t *fpp)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint64_t integer, fraction;
+ uint32_t temp, tsuInTenthNanos, bitFor1Micro;
+ uint8_t fppShift=0;
+
+ bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); /* TimeStamp per nano seconds units */
+ /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
+ tsuInTenthNanos = (uint32_t)(1000*10/(1<<bitFor1Micro));
+
+ /* we choose the faster rate to calibrate fpp */
+ if (p_NonPassthroughAlgParam->comittedInfoRate > p_NonPassthroughAlgParam->peakOrAccessiveInfoRate)
+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->comittedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
+ else
+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
+
+
+ /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
+ * the LSB bits are for the fraction */
+ temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
+ /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
+ * take max fpp=31.
+ * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
+ * limited by the 10G physical port.
+ */
+ if(temp != 0)
+ {
+ /* count zeroes left of the higher used bit (in order to shift the value such that
+ * unused bits may be used for fraction).
+ */
+ while ((temp & 0x80000000) == 0)
+ {
+ temp = temp << 1;
+ fppShift++;
+ }
+ if(fppShift > 15)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
+ return;
+ }
+ }
+ else
+ {
+ temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
+ if(!temp)
+ /* integer and fraction are 0, we set fpp to its max val */
+ fppShift = 31;
+ else
+ {
+ /* integer was 0 but fraction is not. fpp is 16 for the integer,
+ * + all left zeroes of the fraction. */
+ fppShift=16;
+ /* count zeroes left of the higher used bit (in order to shift the value such that
+ * unused bits may be used for fraction).
+ */
+ while ((temp & 0x8000) == 0)
+ {
+ temp = temp << 1;
+ fppShift++;
+ }
+ }
+ }
+
+ /*
+ * This means that the FM TS register will now be used so that 'count' bits are for
+ * fraction and the rest for integer */
+ /* now we re-calculate cir */
+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->comittedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
+ *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrAccessiveInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
+ *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
+
+ *cbs = p_NonPassthroughAlgParam->comittedBurstSize;
+ *pbs_ebs = p_NonPassthroughAlgParam->peakOrAccessiveBurstSize;
+
+ /* get fpp as it should be written to reg.*/
+ *fpp = FPP_Function(fppShift);
+
+}
+
+static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
+{
+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
+
+ while(GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
+
+}
+
+/*********************************************/
+/*............Policer Exception..............*/
+/*********************************************/
+static void PcdPlcrException(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint32_t event, mask, force;
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
+ mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
+
+ event &= mask;
+
+ /* clear the forced events */
+ force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
+ if(force & event)
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
+
+
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
+
+ if(event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
+ if(event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
+
+}
+
+/* ..... */
+
+static void PcdPlcrErrorException(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint32_t event, force, captureReg, mask;
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
+ mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
+
+ event &= mask;
+
+ /* clear the forced events */
+ force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
+ if(force & event)
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
+
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
+
+ if(event & FM_PCD_PLCR_DOUBLE_ECC)
+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
+ if(event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
+ {
+ captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
+ /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
+ p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
+ p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
+ p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
+ p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
+ }
+}
+
+void FmPcdPlcrUpatePointedOwner(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool add)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
+
+ if(add)
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners++;
+ else
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners--;
+}
+
+uint32_t FmPcdPlcrGetPointedOwners(t_Handle h_FmPcd, uint16_t absoluteProfileId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
+
+ return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].pointedOwners;
+}
+uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
+
+ return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
+}
+
+t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdIpcPlcrAllocParams ipcPlcrParams;
+ t_Error err = E_OK;
+ uint16_t base;
+ uint16_t swPortIndex = 0;
+ t_FmPcdIpcMsg msg;
+ uint32_t replyLength;
+ t_FmPcdIpcReply reply;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+
+ if(!numOfProfiles)
+ return E_OK;
+
+ memset(&ipcPlcrParams, 0, sizeof(ipcPlcrParams));
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ /* Alloc resources using IPC messaging */
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ ipcPlcrParams.num = numOfProfiles;
+ ipcPlcrParams.hardwarePortId = hardwarePortId;
+ msg.msgId = FM_PCD_ALLOC_PROFILES;
+ memcpy(msg.msgBody, &ipcPlcrParams, sizeof(ipcPlcrParams));
+ replyLength = sizeof(uint32_t) + sizeof(uint16_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(ipcPlcrParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ if (replyLength != sizeof(uint32_t) + sizeof(uint16_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ if((t_Error)reply.error != E_OK)
+ RETURN_ERROR(MAJOR, (t_Error)reply.error, ("PLCR profiles allocation failed"));
+
+ memcpy((uint8_t*)&base, reply.replyBody, sizeof(uint16_t));
+ }
+ else /* master */
+ {
+ err = PlcrAllocProfiles(p_FmPcd, hardwarePortId, numOfProfiles, &base);
+ if(err)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ }
+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
+
+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = base;
+
+ return E_OK;
+}
+
+t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdIpcPlcrAllocParams ipcPlcrParams;
+ t_Error err = E_OK;
+ uint16_t swPortIndex = 0;
+ t_FmPcdIpcMsg msg;
+ uint32_t replyLength;
+ t_FmPcdIpcReply reply;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+
+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ /* Alloc resources using IPC messaging */
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ ipcPlcrParams.num = p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
+ ipcPlcrParams.hardwarePortId = hardwarePortId;
+ ipcPlcrParams.plcrProfilesBase = p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
+ msg.msgId = FM_PCD_FREE_PROFILES;
+ memcpy(msg.msgBody, &ipcPlcrParams, sizeof(ipcPlcrParams));
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(ipcPlcrParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ if ((t_Error)reply.error != E_OK)
+ RETURN_ERROR(MINOR, (t_Error)reply.error, ("PLCR Free Profiles failed"));
+ }
+ else /* master */
+ {
+ err = PlcrFreeProfiles(p_FmPcd, hardwarePortId, p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles, p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase);
+ if(err)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ }
+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
+
+ return E_OK;
+}
+
+bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
+
+ return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
+}
+
+t_Error PlcrAllocProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t *p_Base)
+{
+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+ uint32_t profilesFound, log2Num, tmpReg32;
+ uint32_t intFlags;
+ uint16_t first, i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ if(!numOfProfiles)
+ return E_OK;
+
+ ASSERT_COND(hardwarePortId);
+
+ if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
+
+ if (!POWER_OF_2(numOfProfiles))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
+
+ intFlags = FmPcdLock(p_FmPcd);
+
+ if(GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("The requesting port has already an allocated profiles window."));
+ }
+
+ first = 0;
+ profilesFound = 0;
+ for(i=0;i<FM_PCD_PLCR_NUM_ENTRIES;)
+ {
+ if(!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
+ {
+ profilesFound++;
+ i++;
+ if(profilesFound == numOfProfiles)
+ break;
+ }
+ else
+ {
+ profilesFound = 0;
+ /* advance i to the next aligned address */
+ first = i = (uint8_t)(first + numOfProfiles);
+ }
+ }
+ if(profilesFound == numOfProfiles)
+ {
+ for(i = first; i<first + numOfProfiles; i++)
+ {
+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
+ }
+ }
+ else
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
+ }
+
+ /**********************FMPL_PMRx******************/
+ LOG2((uint64_t)numOfProfiles, log2Num);
+ tmpReg32 = first;
+ tmpReg32 |= log2Num << 16;
+ tmpReg32 |= FM_PCD_PLCR_PMR_V;
+ WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
+
+ *p_Base = first;
+
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+}
+
+t_Error PlcrAllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
+{
+ uint32_t profilesFound;
+ uint16_t i, k=0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ if(!numOfProfiles)
+ return E_OK;
+
+ if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
+
+ profilesFound = 0;
+ for(i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
+ {
+ if(!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
+ {
+ profilesFound++;
+ profilesIds[k] = i;
+ k++;
+ if(profilesFound == numOfProfiles)
+ break;
+ }
+ }
+ if(profilesFound != numOfProfiles)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
+ for(i = 0;i<k;i++)
+ {
+ p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
+ p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
+ }
+
+ return E_OK;
+}
+
+t_Error PlcrFreeProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles, uint16_t base)
+{
+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+ uint16_t i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
+ WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
+
+ for(i = base; i<base+numOfProfiles;i++)
+ {
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
+
+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = 0;
+ }
+
+ return E_OK;
+}
+
+void PlcrFreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
+{
+ uint16_t i;
+
+ SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
+
+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
+ for(i=0;i<numOfProfiles; i++)
+ {
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
+ p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
+ }
+}
+
+void PlcrEnable(t_FmPcd *p_FmPcd)
+{
+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+
+ WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
+}
+
+void PlcrDisable(t_FmPcd *p_FmPcd)
+{
+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+
+ WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
+}
+
+t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
+
+ if(!FmIsMaster(p_FmPcd->h_Fm))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
+
+ tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
+ if(enable)
+ tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
+ else
+ tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
+
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
+ return E_OK;
+}
+
+t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
+
+ if(!FmIsMaster(p_FmPcd->h_Fm))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
+
+ p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
+
+ return E_OK;
+}
+
+
+t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Profile, t_FmPcdPlcrInterModuleProfileRegs *p_PlcrRegs)
+{
+
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_Error err = E_OK;
+ uint32_t pemode, gnia, ynia, rnia;
+
+/* Set G, Y, R Nia */
+ err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnGreen, &(p_Profile->paramsOnGreen), &gnia);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnYellow, &(p_Profile->paramsOnYellow), &ynia);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ err = SetProfileNia(p_FmPcd, p_Profile->nextEngineOnRed, &(p_Profile->paramsOnRed), &rnia);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+
+/* Mode fmpl_pemode */
+ pemode = FM_PCD_PLCR_PEMODE_PI;
+
+ switch (p_Profile->algSelection)
+ {
+ case e_FM_PCD_PLCR_PASS_THROUGH:
+ p_PlcrRegs->fmpl_pecir = 0;
+ p_PlcrRegs->fmpl_pecbs = 0;
+ p_PlcrRegs->fmpl_pepepir_eir = 0;
+ p_PlcrRegs->fmpl_pepbs_ebs = 0;
+ p_PlcrRegs->fmpl_pelts = 0;
+ p_PlcrRegs->fmpl_pects = 0;
+ p_PlcrRegs->fmpl_pepts_ets = 0;
+ pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
+ switch (p_Profile->colorMode)
+ {
+ case e_FM_PCD_PLCR_COLOR_BLIND:
+ pemode |= FM_PCD_PLCR_PEMODE_CBLND;
+ switch (p_Profile->color.dfltColor)
+ {
+ case e_FM_PCD_PLCR_GREEN:
+ pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
+ break;
+ case e_FM_PCD_PLCR_YELLOW:
+ pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
+ break;
+ case e_FM_PCD_PLCR_RED:
+ pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
+ break;
+ case e_FM_PCD_PLCR_OVERRIDE:
+ pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ break;
+ case e_FM_PCD_PLCR_COLOR_AWARE:
+ pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ break;
+
+ case e_FM_PCD_PLCR_RFC_2698:
+ /* Select algorithm MODE[ALG] = "01" */
+ pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
+ if (p_Profile->nonPassthroughAlgParams.comittedInfoRate > p_Profile->nonPassthroughAlgParams.peakOrAccessiveInfoRate)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than comittedInfoRate."));
+ goto cont_rfc;
+ case e_FM_PCD_PLCR_RFC_4115:
+ /* Select algorithm MODE[ALG] = "10" */
+ pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
+cont_rfc:
+ /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
+ switch (p_Profile->colorMode)
+ {
+ case e_FM_PCD_PLCR_COLOR_BLIND:
+ pemode |= FM_PCD_PLCR_PEMODE_CBLND;
+ break;
+ case e_FM_PCD_PLCR_COLOR_AWARE:
+ pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
+ /*In color aware more select override color interpretation (MODE[OVCLR]) */
+ switch (p_Profile->color.override)
+ {
+ case e_FM_PCD_PLCR_GREEN:
+ pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
+ break;
+ case e_FM_PCD_PLCR_YELLOW:
+ pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
+ break;
+ case e_FM_PCD_PLCR_RED:
+ pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
+ break;
+ case e_FM_PCD_PLCR_OVERRIDE:
+ pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
+ switch (p_Profile->nonPassthroughAlgParams.rateMode)
+ {
+ case e_FM_PCD_PLCR_BYTE_MODE :
+ pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
+ switch (p_Profile->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
+ {
+ case e_FM_PCD_PLCR_L2_FRM_LEN:
+ pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
+ break;
+ case e_FM_PCD_PLCR_L3_FRM_LEN:
+ pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
+ break;
+ case e_FM_PCD_PLCR_L4_FRM_LEN:
+ pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
+ break;
+ case e_FM_PCD_PLCR_FULL_FRM_LEN:
+ pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ switch (p_Profile->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
+ {
+ case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
+ pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
+ break;
+ case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
+ pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ break;
+ case e_FM_PCD_PLCR_PACKET_MODE :
+ pemode |= FM_PCD_PLCR_PEMODE_PKT;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
+ mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
+ mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
+
+ /* Configure Traffic Parameters*/
+ {
+ uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
+
+ calcRates(h_FmPcd, &p_Profile->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
+
+ /* Set Committed Information Rate (CIR) */
+ p_PlcrRegs->fmpl_pecir = cir;
+ /* Set Committed Burst Size (CBS). */
+ p_PlcrRegs->fmpl_pecbs = cbs;
+ /* Set Peak Information Rate (PIR_EIR used as PIR) */
+ p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
+ /* Set Peak Burst Size (PBS_EBS used as PBS) */
+ p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
+
+ /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
+ /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
+ p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
+ /* Committed Rate Token Bucket Size (CTS) */
+ p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
+
+ /* Set the FPP based on calculation */
+ pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
+ }
+ break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ p_PlcrRegs->fmpl_pemode = pemode;
+
+ p_PlcrRegs->fmpl_pegnia = gnia;
+ p_PlcrRegs->fmpl_peynia = ynia;
+ p_PlcrRegs->fmpl_pernia = rnia;
+
+ /* Zero Counters */
+ p_PlcrRegs->fmpl_pegpc = 0;
+ p_PlcrRegs->fmpl_peypc = 0;
+ p_PlcrRegs->fmpl_perpc = 0;
+ p_PlcrRegs->fmpl_perypc = 0;
+ p_PlcrRegs->fmpl_perrpc = 0;
+
+ return E_OK;
+}
+
+void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
+}
+
+void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
+}
+
+t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
+{
+ t_FmPcdPlcr *p_FmPcdPlcr;
+ /*uint8_t i=0;*/
+
+ UNUSED(p_FmPcd);
+ UNUSED(p_FmPcdParams);
+
+ p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
+ if (!p_FmPcdPlcr)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
+ return NULL;
+ }
+ memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
+ if(p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
+ p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
+ p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
+ }
+
+ p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
+
+ return p_FmPcdPlcr;
+}
+
+t_Error PlcrInit(t_FmPcd *p_FmPcd)
+{
+ t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
+ uint32_t tmpReg32 = 0;
+ t_Error err = E_OK;
+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+ t_FmPcdIpcMsg msg;
+ uint32_t replyLength;
+ t_FmPcdIpcReply reply;
+
+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
+ (p_FmPcdPlcr->numOfSharedProfiles))
+ {
+ int i, j, index = 0;
+ uint32_t walking1Mask = 0x80000000;
+ uint32_t sharedProfilesMask[FM_PCD_PLCR_NUM_ENTRIES/32];
+
+ memset(sharedProfilesMask, 0, FM_PCD_PLCR_NUM_ENTRIES/32 * sizeof(uint32_t));
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_ALLOC_SHARED_PROFILES;
+ memcpy(msg.msgBody, (uint8_t *)&p_FmPcdPlcr->numOfSharedProfiles, sizeof(uint16_t));
+ replyLength = sizeof(uint32_t) + sizeof(sharedProfilesMask);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+ sizeof(p_FmPcdPlcr->numOfSharedProfiles),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(sharedProfilesMask)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ memcpy(sharedProfilesMask, reply.replyBody, sizeof(sharedProfilesMask));
+ /* translate 8 regs of 32 bits masks into an array of up to 256 indexes. */
+ for(i = 0; i<FM_PCD_PLCR_NUM_ENTRIES/32 ; i++)
+ {
+ if(sharedProfilesMask[i])
+ {
+ for(j = 0 ; j<32 ; j++)
+ {
+ if(sharedProfilesMask[i] & walking1Mask)
+ p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[index++] = (uint16_t)(i*32+j);
+ walking1Mask >>= 1;
+ }
+ walking1Mask = 0x80000000;
+ }
+ }
+ return (t_Error)reply.error;
+ }
+
+ if(p_FmPcdPlcr->numOfSharedProfiles)
+ {
+ err = PlcrAllocSharedProfiles(p_FmPcd, p_FmPcdPlcr->numOfSharedProfiles, p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
+ if(err)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ }
+
+ /**********************FMPL_GCR******************/
+ tmpReg32 = 0;
+ tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
+ if(p_Param->plcrAutoRefresh)
+ tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
+ tmpReg32 |= NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
+
+ WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
+ /**********************FMPL_GCR******************/
+
+ /**********************FMPL_EEVR******************/
+ WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
+ /**********************FMPL_EEVR******************/
+ /**********************FMPL_EIER******************/
+ tmpReg32 = 0;
+ if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
+ {
+ FmEnableRamsEcc(p_FmPcd->h_Fm);
+ tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
+ }
+ if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
+ tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
+ WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
+ /**********************FMPL_EIER******************/
+
+ /**********************FMPL_EVR******************/
+ WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
+ /**********************FMPL_EVR******************/
+ /**********************FMPL_IER******************/
+ tmpReg32 = 0;
+ if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
+ tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
+ if(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE )
+ tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
+ WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
+ /**********************FMPL_IER******************/
+
+ /* register even if no interrupts enabled, to allow future enablement */
+ FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR, PcdPlcrErrorException, p_FmPcd);
+ FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL, PcdPlcrException, p_FmPcd);
+
+ /* driver initializes one DFLT profile at the last entry*/
+ /**********************FMPL_DPMR******************/
+ tmpReg32 = 0;
+ WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
+ p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
+
+ return E_OK;
+}
+
+t_Error PlcrFree(t_FmPcd *p_FmPcd)
+{
+ t_Error err;
+ t_FmPcdIpcSharedPlcrAllocParams ipcSharedPlcrParams;
+ t_FmPcdIpcMsg msg;
+
+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
+
+ if(p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
+ {
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ int i;
+ memset(ipcSharedPlcrParams.sharedProfilesMask, 0, sizeof(ipcSharedPlcrParams.sharedProfilesMask));
+ /* Free resources using IPC messaging */
+ ipcSharedPlcrParams.num = p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;
+
+ /* translate the allocated profile id's to a 32bit * 8regs mask */
+ for(i = 0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
+ ipcSharedPlcrParams.sharedProfilesMask[p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i]/32] |= (0x80000000 >> (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] % 32));
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_FREE_SHARED_PROFILES;
+ memcpy(msg.msgBody, &ipcSharedPlcrParams, sizeof(ipcSharedPlcrParams));
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(ipcSharedPlcrParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ }
+ /* else
+ PlcrFreeSharedProfiles(p_FmPcd, p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles, p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);*/
+ }
+ return E_OK;
+}
+
+t_Error FmPcdPlcrGetAbsoluteProfileId(t_Handle h_FmPcd,
+ e_FmPcdProfileTypeSelection profileType,
+ t_Handle h_FmPort,
+ uint16_t relativeProfile,
+ uint16_t *p_AbsoluteId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
+ uint8_t i;
+
+ switch (profileType)
+ {
+ case e_FM_PCD_PLCR_PORT_PRIVATE:
+ /* get port PCD id from port handle */
+ for(i=0;i<FM_MAX_NUM_OF_PORTS;i++)
+ if(p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
+ break;
+ if (i == FM_MAX_NUM_OF_PORTS)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
+
+ if(!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
+ if(relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
+ *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
+ break;
+ case e_FM_PCD_PLCR_SHARED:
+ if(relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
+ *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
+ }
+ return E_OK;
+}
+
+uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint16_t swPortIndex = 0;
+
+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
+
+ return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
+}
+
+uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint16_t swPortIndex = 0;
+
+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
+
+ return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
+
+}
+uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
+{
+ return (uint32_t)(FM_PCD_PLCR_PAR_GO |
+ ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
+}
+
+uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
+{
+ return (uint32_t)(FM_PCD_PLCR_PAR_GO |
+ ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
+ FM_PCD_PLCR_PAR_PWSEL_MASK);
+}
+
+bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
+{
+
+ if(profileModeReg & FM_PCD_PLCR_PEMODE_PI)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
+{
+ return (uint32_t)(FM_PCD_PLCR_PAR_GO |
+ FM_PCD_PLCR_PAR_R |
+ ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
+ FM_PCD_PLCR_PAR_PWSEL_MASK);
+}
+
+uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
+{
+ switch(counter)
+ {
+ case(e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
+ return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
+ case(e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
+ return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
+ case(e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
+ return FM_PCD_PLCR_PAR_PWSEL_PERPC;
+ case(e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
+ return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
+ case(e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
+ return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ return 0;
+ }
+}
+
+uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
+{
+
+ uint32_t tmpReg32 = 0;
+
+ if(green)
+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
+ if(yellow)
+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
+ if(red)
+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
+
+ return tmpReg32;
+}
+
+void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
+
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = requiredAction;
+}
+
+t_Error FmPcdPlcrProfileTryLock(t_Handle h_FmPcd, uint16_t profileId, bool intr)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ bool ans;
+ if (intr)
+ ans = TRY_LOCK(NULL, &p_FmPcd->p_FmPcdPlcr->profiles[profileId].lock);
+ else
+ ans = TRY_LOCK(p_FmPcd->h_Spinlock, &p_FmPcd->p_FmPcdPlcr->profiles[profileId].lock);
+ if (ans)
+ return E_OK;
+ return ERROR_CODE(E_BUSY);
+}
+
+void FmPcdPlcrReleaseProfileLock(t_Handle h_FmPcd, uint16_t profileId)
+{
+ RELEASE_LOCK(((t_FmPcd*)h_FmPcd)->p_FmPcdPlcr->profiles[profileId].lock);
+}
+
+/**************************************************/
+/*............Policer API.........................*/
+/**************************************************/
+
+t_Handle FM_PCD_PlcrSetProfile(t_Handle h_FmPcd,
+ t_FmPcdPlcrProfileParams *p_Profile)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
+ t_FmPcdPlcrInterModuleProfileRegs plcrProfileReg;
+ uint32_t intFlags;
+ uint16_t absoluteProfileId;
+ t_Error err = E_OK;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, p_Profile);
+
+ p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+ SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
+
+ if (p_Profile->modify)
+ {
+ absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_Profile->id.h_Profile)-1);
+ if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
+ return NULL;
+ }
+ if (FmPcdPlcrProfileTryLock(p_FmPcd, absoluteProfileId, FALSE))
+ return NULL;
+ }
+ else
+ {
+ intFlags = FmPcdLock(p_FmPcd);
+ err = FmPcdPlcrGetAbsoluteProfileId(h_FmPcd,
+ p_Profile->id.newParams.profileType,
+ p_Profile->id.newParams.h_FmPort,
+ p_Profile->id.newParams.relativeProfileId,
+ &absoluteProfileId);
+ if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
+ return NULL;
+ }
+ if(err)
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+ err = FmPcdPlcrProfileTryLock(p_FmPcd, absoluteProfileId, TRUE);
+ FmPcdUnlock(p_FmPcd, intFlags);
+ if (err)
+ return NULL;
+ }
+
+ /* if no override, check first that this profile is unused */
+ if(!p_Profile->modify)
+ {
+ /* read specified profile into profile registers */
+ tmpReg32 = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
+ intFlags = FmPcdLock(p_FmPcd);
+ WritePar(p_FmPcd, tmpReg32);
+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode);
+ FmPcdUnlock(p_FmPcd, intFlags);
+ if (tmpReg32 & FM_PCD_PLCR_PEMODE_PI)
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock);
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
+ return NULL;
+ }
+ }
+
+ memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrInterModuleProfileRegs));
+
+ err = FmPcdPlcrBuildProfile(h_FmPcd, p_Profile, &plcrProfileReg);
+ if(err)
+ {
+ RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnGreen = p_Profile->nextEngineOnGreen;
+ memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnGreen, &(p_Profile->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
+
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnYellow = p_Profile->nextEngineOnYellow;
+ memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnYellow, &(p_Profile->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
+
+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].nextEngineOnRed = p_Profile->nextEngineOnRed;
+ memcpy(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].paramsOnRed, &(p_Profile->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
+
+ intFlags = FmPcdLock(p_FmPcd);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
+
+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
+ WritePar(p_FmPcd, tmpReg32);
+
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ if (!p_Profile->modify)
+ FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
+
+ RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].lock);
+
+ return UINT_TO_PTR((uint64_t)absoluteProfileId+1);
+}
+
+t_Error FM_PCD_PlcrDeleteProfile(t_Handle h_FmPcd, t_Handle h_Profile)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+ uint32_t tmpReg32, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((profileIndx < FM_PCD_PLCR_NUM_ENTRIES), E_INVALID_SELECTION);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
+
+ FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
+
+ intFlags = FmPcdLock(p_FmPcd);
+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
+
+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
+ WritePar(p_FmPcd, tmpReg32);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+}
+
+/* ......... */
+/***************************************************/
+/*............Policer Profile Counter..............*/
+/***************************************************/
+uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
+ uint32_t intFlags, counterVal = 0;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, 0);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
+
+ p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+ SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
+
+ if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
+ return 0;
+ }
+ intFlags = FmPcdLock(p_FmPcd);
+ WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
+
+ if(!FmPcdPlcrHwProfileIsValid(GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode)))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized profile"));
+ FmPcdUnlock(p_FmPcd, intFlags);
+ return 0;
+ }
+
+ switch (counter)
+ {
+ case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
+ counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
+ break;
+ case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
+ break;
+ default:
+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ break;
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return counterVal;
+}
+
+
+t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
+ uint32_t tmpReg32, intFlags;
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
+
+ if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
+
+ if (FmPcdPlcrProfileTryLock(p_FmPcd, profileIndx, FALSE))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("Lock on PP FAILED"));
+
+ intFlags = FmPcdLock(p_FmPcd);
+ WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
+
+ if(!FmPcdPlcrHwProfileIsValid(GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode)))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].lock);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
+ }
+
+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].valid);
+
+ if(!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].pointedOwners ||
+ !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
+ {
+ if(requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
+ {
+ if((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
+ (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
+ (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
+ }
+
+ if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
+ {
+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
+ if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
+ }
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
+ WritePar(p_FmPcd, tmpReg32);
+ }
+
+ if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
+ {
+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
+ if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
+ }
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
+ WritePar(p_FmPcd, tmpReg32);
+ }
+
+ if(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
+ {
+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
+ if(!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
+ {
+ FmPcdUnlock(p_FmPcd, intFlags);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
+ }
+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
+ WritePar(p_FmPcd, tmpReg32);
+ }
+ }
+ }
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].pointedOwners += 1;
+ p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction |= requiredAction;
+
+ RELEASE_LOCK(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].lock);
+
+ return E_OK;
+}
+
+t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
+ uint32_t tmpReg32, intFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
+
+ if (p_FmPcd->h_Hc)
+ return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
+
+ p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
+ SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
+
+ intFlags = FmPcdLock(p_FmPcd);
+ switch (counter)
+ {
+ case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
+ break;
+ case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
+ break;
+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
+ }
+
+ /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
+ * Profile Number, PWSEL=0xFFFF (select all words).
+ */
+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
+ tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
+ WritePar(p_FmPcd, tmpReg32);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+}
+
+t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
+
+ p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
+
+ return E_OK;
+}
+
+
+/* ... */
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ int i = 0;
+ t_FmPcdIpcMsg msg;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_PLCR_DUMP_REGS;
+ return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ }
+ else
+ {
+ DUMP_SUBTITLE(("\n"));
+ DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FmPcdPlcrRegs Regs"));
+
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gcr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_gsr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_evr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ier);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ifr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eevr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eier);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_eifr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rpcnt);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_ypcnt);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rrpcnt);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_rypcnt);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_tpcnt);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_flmcnt);
+
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_serc);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_upcr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,fmpl_dpmr);
+
+
+ DUMP_TITLE(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr, ("fmpl_pmr"));
+ DUMP_SUBSTRUCT_ARRAY(i, 63)
+ {
+ DUMP_MEMORY(&p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i], sizeof(uint32_t));
+ }
+
+ return E_OK;
+ }
+}
+
+t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_FmPcd, t_Handle h_Profile)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdPlcrInterModuleProfileRegs *p_ProfilesRegs;
+ uint32_t tmpReg, intFlags;
+ uint16_t profileIndx = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+ t_FmPcdIpcMsg msg;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_PLCR_PROFILE_DUMP_REGS;
+ memcpy(msg.msgBody, (uint8_t *)&h_Profile, sizeof(uint32_t));
+ return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(uint32_t),
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ }
+ else
+ {
+ DUMP_SUBTITLE(("\n"));
+ DUMP_TITLE(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, ("FmPcdPlcrRegs Profile Regs"));
+
+ p_ProfilesRegs = &p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
+
+ tmpReg = FmPcdPlcrBuildReadPlcrActionReg((uint16_t)profileIndx);
+ intFlags = FmPcdLock(p_FmPcd);
+ WritePar(p_FmPcd, tmpReg);
+
+ DUMP_TITLE(p_ProfilesRegs, ("Profile %d regs", profileIndx));
+
+ DUMP_VAR(p_ProfilesRegs, fmpl_pemode);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pegnia);
+ DUMP_VAR(p_ProfilesRegs, fmpl_peynia);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pernia);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pecir);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pecbs);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pepepir_eir);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pepbs_ebs);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pelts);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pects);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pepts_ets);
+ DUMP_VAR(p_ProfilesRegs, fmpl_pegpc);
+ DUMP_VAR(p_ProfilesRegs, fmpl_peypc);
+ DUMP_VAR(p_ProfilesRegs, fmpl_perpc);
+ DUMP_VAR(p_ProfilesRegs, fmpl_perypc);
+ DUMP_VAR(p_ProfilesRegs, fmpl_perrpc);
+ FmPcdUnlock(p_FmPcd, intFlags);
+
+ return E_OK;
+ }
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c
new file mode 100644
index 0000000..2191c12
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c
@@ -0,0 +1,517 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_pcd.c
+
+ @Description FM PCD ...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "error_ext.h"
+#include "string_ext.h"
+#include "debug_ext.h"
+#include "net_ext.h"
+
+#include "fm_common.h"
+#include "fm_pcd.h"
+#include "fm_pcd_ipc.h"
+
+
+t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
+{
+ t_FmPcdPrs *p_FmPcdPrs;
+ uintptr_t baseAddr;
+
+ UNUSED(p_FmPcd);
+ UNUSED(p_FmPcdParams);
+
+ p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
+ if (!p_FmPcdPrs)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
+ return NULL;
+ }
+ memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
+
+ if (p_FmPcd->guestId == NCSW_MASTER_ID)
+ {
+ baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
+ p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
+ p_FmPcdPrs->p_FmPcdPrsRegs = (t_FmPcdPrsRegs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
+ }
+
+ p_FmPcdPrs->fmPcdPrsPortIdStatistics = 0;
+ p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = DEFAULT_prsMaxParseCycleLimit;
+ p_FmPcd->exceptions |= (DEFAULT_fmPcdPrsErrorExceptions | DEFAULT_fmPcdPrsExceptions);
+
+ return p_FmPcdPrs;
+}
+
+static void PcdPrsErrorException(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint32_t event, mask, force;
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+ event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr);
+ mask = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perer);
+
+ event &= mask;
+
+ /* clear the forced events */
+ force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr);
+ if(force & event)
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perfr, force & ~event);
+
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->perr, event);
+
+ DBG(TRACE, ("parser error - 0x%08x\n",event));
+
+ if(event & FM_PCD_PRS_DOUBLE_ECC)
+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
+}
+
+static void PcdPrsException(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ uint32_t event, force;
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+ event = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr);
+ event &= GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pever);
+
+ ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
+
+ DBG(TRACE, ("parser event - 0x%08x\n",event));
+
+ /* clear the forced events */
+ force = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr);
+ if(force & event)
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevfr, force & ~event);
+
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->pevr, event);
+
+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
+}
+
+static uint32_t GetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ int i;
+ t_FmPcdPrsLabelParams *p_Label;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+ ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
+
+ for (i=0; i < p_FmPcd->p_FmPcdPrs->currLabel; i++)
+ {
+ p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
+
+ if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
+ return p_Label->instructionOffset;
+ }
+
+ REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
+ return (uint32_t)ILLEGAL_BASE;
+}
+
+t_Error PrsInit(t_FmPcd *p_FmPcd)
+{
+ t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
+ t_FmPcdPrsRegs *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
+ uint32_t tmpReg;
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ return E_OK;
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+
+#ifdef FM_PRS_MEM_ERRATA_FMAN_SW003
+ {
+ uint32_t i;
+ uint32_t regsToGlobalOffset = 0x840;
+ uint32_t firstPortToGlobalOffset = 0x45800;
+ uint64_t globalAddr = PTR_TO_UINT(p_Regs) - regsToGlobalOffset;
+ uint32_t firstPortAddr = (uint32_t)(globalAddr - (uint64_t)firstPortToGlobalOffset);
+ uint32_t portSize = 0x1000;
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ /* clear all parser memory */
+ IOMemSet32(UINT_TO_PTR(globalAddr), 0x00000000, 0x800);
+ for(i = 0;i<16;i++)
+ IOMemSet32(UINT_TO_PTR(firstPortAddr+i*portSize), (uint8_t)0x00000000, (uint32_t)0x80);
+ }
+ }
+#endif /* FM_PRS_MEM_ERRATA_FMAN_SW003 */
+
+ /**********************RPCLIM******************/
+ WRITE_UINT32(p_Regs->rpclim, (uint32_t)p_Param->prsMaxParseCycleLimit);
+ /**********************FMPL_RPCLIM******************/
+
+ /* register even if no interrupts enabled, to allow future enablement */
+ FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
+
+ /* register even if no interrupts enabled, to allow future enablement */
+ FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
+
+ /**********************PEVR******************/
+ WRITE_UINT32(p_Regs->pevr, (FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS) );
+ /**********************PEVR******************/
+
+ /**********************PEVER******************/
+ if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
+ {
+ FmEnableRamsEcc(p_FmPcd->h_Fm);
+ WRITE_UINT32(p_Regs->pever, FM_PCD_PRS_SINGLE_ECC);
+ }
+ else
+ WRITE_UINT32(p_Regs->pever, 0);
+ /**********************PEVER******************/
+
+ /**********************PERR******************/
+ WRITE_UINT32(p_Regs->perr, FM_PCD_PRS_DOUBLE_ECC);
+
+ /**********************PERR******************/
+
+ /**********************PERER******************/
+ tmpReg = 0;
+ if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
+ {
+ FmEnableRamsEcc(p_FmPcd->h_Fm);
+ tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
+ }
+ WRITE_UINT32(p_Regs->perer, tmpReg);
+ /**********************PERER******************/
+
+ /**********************PPCS******************/
+ WRITE_UINT32(p_Regs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
+ /**********************PPCS******************/
+
+#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb
+ {
+ uint32_t i, j;
+ t_FmRevisionInfo revInfo;
+ uint8_t swPrsL4Patch[] = SW_PRS_L4_PATCH;
+
+ FM_GetRevision(p_FmPcd->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ /* load sw parser L4 patch */
+ for(i=0;i<sizeof(swPrsL4Patch)/4;i++)
+ {
+ tmpReg = 0;
+ for(j =0;j<4;j++)
+ {
+ tmpReg <<= 8;
+ tmpReg |= swPrsL4Patch[i*4+j];
+
+ }
+ WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+ FM_PCD_PRS_SW_OFFSET/4 + i), tmpReg);
+ }
+ p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = FM_PCD_PRS_SW_OFFSET/4 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode+sizeof(swPrsL4Patch)/4;
+ }
+ }
+#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */
+
+ return E_OK;
+}
+
+void PrsFree(t_FmPcd *p_FmPcd )
+{
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
+ /* register even if no interrupts enabled, to allow future enablement */
+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
+}
+
+void PrsEnable(t_FmPcd *p_FmPcd )
+{
+ t_FmPcdPrsRegs *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+ WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) | FM_PCD_PRS_RPIMAC_EN);
+}
+
+void PrsDisable(t_FmPcd *p_FmPcd )
+{
+ t_FmPcdPrsRegs *p_Regs = p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+ WRITE_UINT32(p_Regs->rpimac, GET_UINT32(p_Regs->rpimac) & ~FM_PCD_PRS_RPIMAC_EN);
+}
+
+t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
+{
+ uint32_t bitMask = 0;
+ uint8_t prsPortId;
+
+ SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
+
+ GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
+ GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
+
+ if(include)
+ p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
+ else
+ p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
+
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
+
+ return E_OK;
+}
+
+t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_FmPcdIpcPrsIncludePort prsIncludePortParams;
+ t_FmPcdIpcMsg msg;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ prsIncludePortParams.hardwarePortId = hardwarePortId;
+ prsIncludePortParams.include = include;
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
+ memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(prsIncludePortParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ return E_OK;
+ }
+ return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
+}
+
+uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
+ t_Error err = E_OK;
+ t_FmPcdIpcSwPrsLable labelParams;
+ t_FmPcdIpcMsg msg;
+ uint32_t prsOffset = 0;
+ t_FmPcdIpcReply reply;
+ uint32_t replyLength;
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ memset(&reply, 0, sizeof(reply));
+ memset(&msg, 0, sizeof(msg));
+ labelParams.enumHdr = (uint32_t)hdr;
+ labelParams.indexPerHdr = indexPerHdr;
+ msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
+ memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(labelParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(replyLength != sizeof(uint32_t) + sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
+ return prsOffset;
+ }
+
+ return GetSwPrsOffset(h_FmPcd, hdr, indexPerHdr);
+}
+
+void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
+ return;
+ }
+ if(enable)
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, FM_PCD_PRS_PPSC_ALL_PORTS);
+ else
+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->ppsc, 0);
+
+}
+
+t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ uint32_t *p_LoadTarget, tmpReg;
+ int i, j;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_PrsLoadSw - guest mode!"));
+
+ if(!p_SwPrs->override)
+ {
+ if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
+ }
+ if(p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
+ if(p_SwPrs->size % 4)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size must be divisible by 4"));
+
+ /* save sw parser labels */
+ if(p_SwPrs->override)
+ p_FmPcd->p_FmPcdPrs->currLabel = 0;
+ if(p_FmPcd->p_FmPcdPrs->currLabel+ p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
+ memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel], p_SwPrs->labelsTable, p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
+ p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
+ /* load sw parser code */
+ p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
+ for(i=0;i<p_SwPrs->size/4;i++)
+ {
+ tmpReg = 0;
+ for(j =0;j<4;j++)
+ {
+ tmpReg <<= 8;
+ tmpReg |= *(p_SwPrs->p_Code+i*4+j);
+ }
+ WRITE_UINT32(*(p_LoadTarget + i), tmpReg);
+ }
+ p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + p_SwPrs->size/4;
+
+ /* copy data parameters */
+ for(i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
+ WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
+
+
+ /* Clear last 4 bytes */
+ WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
+
+ return E_OK;
+}
+
+t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
+
+ p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
+
+ return E_OK;
+}
+
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ t_FmPcdIpcMsg msg;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
+
+ if(p_FmPcd->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_PCD_PRS_DUMP_REGS;
+ return XX_IpcSendMessage(p_FmPcd->h_IpcSession,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ }
+ DUMP_SUBTITLE(("\n"));
+ DUMP_TITLE(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs, ("FmPcdPrsRegs Regs"));
+
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpclim);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,rpimac);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pmeec);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pever);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pevfr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perer);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,perfr);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,ppsc);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,pds);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rrs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rrs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rrs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srrs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l2rres);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l3rres);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,l4rres);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,srres);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spcs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,spscs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,hxscs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrcs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwcs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mrscs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,mwscs);
+ DUMP_VAR(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs,fcscs);
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c
new file mode 100644
index 0000000..1274358
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.c
@@ -0,0 +1,5060 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_port.c
+
+ @Description FM driver routines implementation.
+*//***************************************************************************/
+#include "error_ext.h"
+#include "std_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "debug_ext.h"
+#include "fm_pcd_ext.h"
+
+#include "fm_port.h"
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+
+static t_Error CheckInitParameters(t_FmPort *p_FmPort)
+{
+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
+ t_Error ans = E_OK;
+ uint32_t unusedMask;
+ uint8_t i;
+ uint8_t j;
+ bool found;
+
+ if (p_FmPort->imEn)
+ {
+ if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
+ return ERROR_CODE(ans);
+ }
+ else
+ {
+ /****************************************/
+ /* Rx only */
+ /****************************************/
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ /* external buffer pools */
+ if(!p_Params->extBufPools.numOfPoolsUsed)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
+
+ if(p_Params->extBufPools.numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
+
+ for(i=0;i<p_Params->extBufPools.numOfPoolsUsed;i++)
+ {
+ if(p_Params->extBufPools.extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
+ if(!p_Params->extBufPools.extBufPool[i].size)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
+ }
+
+ /* backup BM pools indication is valid only for some chip deriviatives
+ (limited by the config routine) */
+ if(p_Params->p_BackupBmPools)
+ {
+ if(p_Params->p_BackupBmPools->numOfBackupPools >= p_Params->extBufPools.numOfPoolsUsed)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
+ found = FALSE;
+ for(i = 0;i<p_Params->p_BackupBmPools->numOfBackupPools;i++)
+ for(j=0;j<p_Params->extBufPools.numOfPoolsUsed;j++)
+ if(p_Params->p_BackupBmPools->poolIds[i] == p_Params->extBufPools.extBufPool[j].id)
+ found = TRUE;
+ if (!found)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
+ }
+
+ /* up to extBufPools.numOfPoolsUsed pools may be defined */
+ if(p_Params->bufPoolDepletion.numberOfPoolsModeEnable)
+ {
+ if((p_Params->bufPoolDepletion.numOfPools > p_Params->extBufPools.numOfPoolsUsed))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools can't be larger than %d and can't be larger than numOfPoolsUsed", FM_PORT_MAX_NUM_OF_EXT_POOLS));
+
+ if(!p_Params->bufPoolDepletion.numOfPools)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when numberOfPoolsModeEnable=TRUE"));
+ }
+ /* Check that part of IC that needs copying is small enough to enter start margin */
+ if(p_Params->intContext.size + p_Params->intContext.extBufOffset > p_Params->bufMargins.startMargins)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size is larger than start margins"));
+
+ if(p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
+#ifdef FM_PARTITION_ARRAY
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ if(p_Params->liodnOffset >= MAX_LIODN_OFFSET)
+ {
+ p_Params->liodnOffset = (uint16_t)(p_Params->liodnOffset & (MAX_LIODN_OFFSET-1));
+ DBG(WARNING, ("liodnOffset number is out of rev1 range - MSB bits cleard."));
+ }
+ }
+ }
+#endif /* FM_PARTITION_ARRAY */
+ }
+
+ /****************************************/
+ /* Non Rx ports */
+ /****************************************/
+ else
+ {
+ if(p_Params->deqSubPortal >= MAX_QMI_DEQ_SUBPORTAL)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" deqSubPortal has to be in the range of 0 - %d", MAX_QMI_DEQ_SUBPORTAL));
+
+ /* to protect HW internal-context from overwrite */
+ if((p_Params->intContext.size) && (p_Params->intContext.intContextOffset < MIN_TX_INT_OFFSET))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
+ }
+
+ /****************************************/
+ /* Rx Or Offline Parsing */
+ /****************************************/
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
+ {
+
+ if(!p_Params->dfltFqid)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dfltFqid must be between 1 and 2^24-1"));
+#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
+ if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
+#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
+ }
+
+ /****************************************/
+ /* All ports */
+ /****************************************/
+ /* common BMI registers values */
+ /* Check that Queue Id is not larger than 2^24, and is not 0 */
+ if((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("errFqid must be between 1 and 2^24-1"));
+ if(p_Params->dfltFqid & ~0x00FFFFFF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dfltFqid must be between 1 and 2^24-1"));
+ }
+
+ /****************************************/
+ /* Rx only */
+ /****************************************/
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ /* Check that divisible by 256 and not larger than 256 */
+ if(p_Params->rxFifoPriElevationLevel % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
+ if(!p_Params->rxFifoPriElevationLevel || (p_Params->rxFifoPriElevationLevel > BMI_MAX_FIFO_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoPriElevationLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE));
+ if(p_Params->rxFifoThreshold % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
+ if(!p_Params->rxFifoThreshold ||(p_Params->rxFifoThreshold > BMI_MAX_FIFO_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rxFifoThreshold has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE));
+
+ /* Check that not larger than 16 */
+ if(p_Params->cutBytesFromEnd > FRAME_END_DATA_SIZE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
+
+ /* Check the margin definition */
+ if(p_Params->bufMargins.startMargins > MAX_EXT_BUFFER_OFFSET)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
+ if(p_Params->bufMargins.endMargins > MAX_EXT_BUFFER_OFFSET)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
+
+ /* extra FIFO size (allowed only to Rx ports) */
+ if(p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
+
+ if(p_Params->bufPoolDepletion.numberOfPoolsModeEnable &&
+ !p_Params->bufPoolDepletion.numOfPools)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when numberOfPoolsModeEnable=TRUE"));
+#ifdef FM_CSI_CFED_LIMIT
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+
+ if (revInfo.majorRev == 4)
+ {
+ /* Check that not larger than 16 */
+ if(p_Params->cutBytesFromEnd + p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
+ }
+ }
+#endif /* FM_CSI_CFED_LIMIT */
+
+ }
+
+ /****************************************/
+ /* Non Rx ports */
+ /****************************************/
+ else
+ /* extra FIFO size (allowed only to Rx ports) */
+ if(p_FmPort->fifoBufs.extra)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" No fifoBufs.extra for non Rx ports"));
+
+ /****************************************/
+ /* Rx & Tx */
+ /****************************************/
+ if((p_FmPort->portType == e_FM_PORT_TYPE_TX) || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ /* Check that not larger than 16 */
+ if(p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
+ }
+
+ /****************************************/
+ /* Tx only */
+ /****************************************/
+ if((p_FmPort->portType == e_FM_PORT_TYPE_TX) || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
+ {
+ /* Check that divisible by 256 and not larger than 256 */
+ if(p_Params->txFifoMinFillLevel % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
+ if(p_Params->txFifoMinFillLevel > (BMI_MAX_FIFO_SIZE - 256))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoMinFillLevel has to be in the range of 0 - %d", BMI_MAX_FIFO_SIZE));
+ if(p_Params->txFifoLowComfLevel % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
+ if(!p_Params->txFifoLowComfLevel || (p_Params->txFifoLowComfLevel > BMI_MAX_FIFO_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoLowComfLevel has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE));
+
+ /* Check that not larger than 8 */
+ if((!p_FmPort->txFifoDeqPipelineDepth) ||( p_FmPort->txFifoDeqPipelineDepth > MAX_FIFO_PIPELINE_DEPTH))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
+ if(p_FmPort->portType == e_FM_PORT_TYPE_TX)
+ if(p_FmPort->txFifoDeqPipelineDepth > 2)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("txFifoDeqPipelineDepth for !G can't be larger than 2"));
+ }
+ else
+ /****************************************/
+ /* Non Tx Ports */
+ /****************************************/
+ {
+ /* If discard override was selected , no frames may be discarded. */
+ if(p_Params->frmDiscardOverride && p_Params->errorsToDiscard)
+ RETURN_ERROR(MAJOR, E_CONFLICT, ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
+ }
+
+ /****************************************/
+ /* Rx and Offline parsing */
+ /****************************************/
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
+ {
+ if(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ unusedMask = BMI_STATUS_OP_MASK_UNUSED;
+ else
+ unusedMask = BMI_STATUS_RX_MASK_UNUSED;
+
+ /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
+ if(p_Params->errorsToDiscard & unusedMask)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("errorsToDiscard contains undefined bits"));
+ }
+
+ /****************************************/
+ /* All ports */
+ /****************************************/
+
+ /* Check that divisible by 16 and not larger than 240 */
+ if(p_Params->intContext.intContextOffset >MAX_INT_OFFSET)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
+ if(p_Params->intContext.intContextOffset % OFFSET_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
+
+ /* check that ic size+ic internal offset, does not exceed ic block size */
+ if(p_Params->intContext.size + p_Params->intContext.intContextOffset > MAX_IC_SIZE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
+ /* Check that divisible by 16 and not larger than 256 */
+ if(p_Params->intContext.size % OFFSET_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
+
+ /* Check that divisible by 16 and not larger than 4K */
+ if(p_Params->intContext.extBufOffset > MAX_EXT_OFFSET)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
+ if(p_Params->intContext.extBufOffset % OFFSET_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
+
+ /* common BMI registers values */
+ if((!p_FmPort->tasks.num) || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
+ if(p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
+ if((!p_FmPort->openDmas.num) || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
+ if(p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
+ if(!p_FmPort->fifoBufs.num || (p_FmPort->fifoBufs.num > BMI_MAX_FIFO_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.num has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE));
+ if(p_FmPort->fifoBufs.num % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
+
+ return E_OK;
+}
+
+static void FmPortDriverParamFree(t_FmPort *p_FmPort)
+{
+ if(p_FmPort->p_FmPortDriverParam)
+ {
+ XX_Free(p_FmPort->p_FmPortDriverParam);
+ p_FmPort->p_FmPortDriverParam = NULL;
+ }
+}
+
+static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
+{
+ t_FmPortExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
+ t_FmPortBufPoolDepletion *p_BufPoolDepletion = &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
+ volatile uint32_t *p_ExtBufRegs;
+ volatile uint32_t *p_BufPoolDepletionReg;
+ bool rxPort;
+ bool found;
+ uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
+ uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
+ uint8_t count = 0;
+ uint8_t numOfPools;
+ uint16_t bufSize = 0, largestBufSize = 0;
+ int i=0, j=0, k=0;
+ uint32_t tmpReg, vector, minFifoSizeRequired=0;
+
+ memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
+ memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
+ memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmPortExtPools));
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi;
+ p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_mpd;
+ rxPort = TRUE;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_ExtBufRegs = p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi;
+ p_BufPoolDepletionReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ompd;
+ rxPort = FALSE;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for port type"));
+ }
+
+ /* First we copy the external buffers pools information to an ordered local array */
+ for(i=0;i<p_ExtBufPools->numOfPoolsUsed;i++)
+ {
+ /* get pool size */
+ bufSize = p_ExtBufPools->extBufPool[i].size;
+
+ /* keep sizes in an array according to poolId for direct access */
+ sizesArray[p_ExtBufPools->extBufPool[i].id] = bufSize;
+
+ /* save poolId in an ordered array according to size */
+ for (j=0;j<=i;j++)
+ {
+ /* this is the next free place in the array */
+ if (j==i)
+ orderedArray[i] = p_ExtBufPools->extBufPool[i].id;
+ else
+ {
+ /* find the right place for this poolId */
+ if(bufSize < sizesArray[orderedArray[j]])
+ {
+ /* move the poolIds one place ahead to make room for this poolId */
+ for(k=i;k>j;k--)
+ orderedArray[k] = orderedArray[k-1];
+
+ /* now k==j, this is the place for the new size */
+ orderedArray[k] = p_ExtBufPools->extBufPool[i].id;
+ break;
+ }
+ }
+ }
+ }
+
+ /* build the register value */
+
+ for(i=0;i<p_ExtBufPools->numOfPoolsUsed;i++)
+ {
+ tmpReg = BMI_EXT_BUF_POOL_VALID | BMI_EXT_BUF_POOL_EN_COUNTER;
+ tmpReg |= ((uint32_t)orderedArray[i] << BMI_EXT_BUF_POOL_ID_SHIFT);
+ tmpReg |= sizesArray[orderedArray[i]];
+ /* functionality available only for some deriviatives (limited by config) */
+ if(p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
+ for(j=0;j<p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;j++)
+ if(orderedArray[i] == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
+ {
+ tmpReg |= BMI_EXT_BUF_POOL_BACKUP;
+ break;
+ }
+ WRITE_UINT32(*(p_ExtBufRegs+i), tmpReg);
+ }
+
+ if(p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
+ XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
+
+ numOfPools = (uint8_t)(rxPort ? FM_PORT_MAX_NUM_OF_EXT_POOLS:FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS);
+
+ /* clear unused pools */
+ for(i=p_ExtBufPools->numOfPoolsUsed;i<numOfPools;i++)
+ WRITE_UINT32(*(p_ExtBufRegs+i), 0);
+
+ p_FmPort->rxPoolsParams.largestBufSize = largestBufSize = sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed-1]];
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+#ifdef FM_FIFO_ALLOCATION_OLD_ALG
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+
+ if(revInfo.majorRev != 4)
+ {
+ minFifoSizeRequired = (uint32_t)(((largestBufSize % BMI_FIFO_UNITS) ?
+ ((largestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
+ largestBufSize) +
+ (7*BMI_FIFO_UNITS));
+ }
+ else
+#endif /* FM_FIFO_ALLOCATION_OLD_ALG */
+ {
+ p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
+ if(p_ExtBufPools->numOfPoolsUsed == 1)
+ minFifoSizeRequired = 8*BMI_FIFO_UNITS;
+ else
+ {
+ uint16_t secondLargestBufSize = sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed-2]];
+ p_FmPort->rxPoolsParams.secondLargestBufSize = secondLargestBufSize;
+ minFifoSizeRequired = (uint32_t)(((secondLargestBufSize % BMI_FIFO_UNITS) ?
+ ((secondLargestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
+ secondLargestBufSize) +
+ (7*BMI_FIFO_UNITS));
+ }
+ }
+ if(p_FmPort->fifoBufs.num < minFifoSizeRequired)
+ {
+ p_FmPort->fifoBufs.num = minFifoSizeRequired;
+ DBG(INFO, ("FIFO size for Rx port enlarged to %d",minFifoSizeRequired));
+ }
+ }
+
+ /* check if pool size is not too big */
+ /* This is a definition problem in which if the fifo for the RX port
+ is lower than the largest pool size the hardware will allocate scatter gather
+ buffers even though the frame size can fit in a single buffer. */
+ if (largestBufSize > p_FmPort->fifoBufs.num)
+ DBG(WARNING, ("Frame larger than port Fifo size (%u) will be split to more than a single buffer (S/G) even if shorter than largest buffer size (%u)",
+ p_FmPort->fifoBufs.num, largestBufSize));
+
+ /* pool depletion */
+ tmpReg = 0;
+ if(p_BufPoolDepletion->numberOfPoolsModeEnable)
+ {
+ /* calculate vector for number of pools depletion */
+ found = FALSE;
+ vector = 0;
+ count = 0;
+ for(i=0;i<BM_MAX_NUM_OF_POOLS;i++)
+ {
+ if(p_BufPoolDepletion->poolsToConsider[i])
+ {
+ for(j=0;j<p_ExtBufPools->numOfPoolsUsed;j++)
+ {
+ if (i == orderedArray[j])
+ {
+ vector |= 0x80000000 >> j;
+ found = TRUE;
+ count++;
+ break;
+ }
+ }
+ if (!found)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
+ else
+ found = FALSE;
+ }
+ }
+ if (count < p_BufPoolDepletion->numOfPools)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
+
+ /* configure num of pools and vector for number of pools mode */
+ tmpReg |= (((uint32_t)p_BufPoolDepletion->numOfPools - 1) << BMI_POOL_DEP_NUM_OF_POOLS_SHIFT);
+ tmpReg |= vector;
+ }
+
+ if(p_BufPoolDepletion->singlePoolModeEnable)
+ {
+ /* calculate vector for number of pools depletion */
+ found = FALSE;
+ vector = 0;
+ count = 0;
+ for(i=0;i<BM_MAX_NUM_OF_POOLS;i++)
+ {
+ if(p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
+ {
+ for(j=0;j<p_ExtBufPools->numOfPoolsUsed;j++)
+ {
+ if (i == orderedArray[j])
+ {
+ vector |= 0x00000080 >> j;
+ found = TRUE;
+ count++;
+ break;
+ }
+ }
+ if (!found)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
+ else
+ found = FALSE;
+ }
+ }
+ if (!count)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
+
+ /* configure num of pools and vector for number of pools mode */
+ tmpReg |= vector;
+ }
+
+ WRITE_UINT32(*p_BufPoolDepletionReg, tmpReg);
+
+ return E_OK;
+}
+
+static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
+{
+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
+ return E_OK;
+}
+
+static t_Error BmiRxPortInit(t_FmPort *p_FmPort)
+{
+ t_FmPortRxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs;
+ uint32_t tmpReg;
+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
+ uint32_t errorsToEnq = 0;
+ t_FmPortPerformanceCnt performanceContersParams;
+ t_Error err;
+
+ /* check that port is not busy */
+ if (GET_UINT32(p_Regs->fmbm_rcfg) & BMI_PORT_CFG_EN)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,
+ ("Port(%d,%d) is already enabled",p_FmPort->portType, p_FmPort->portId));
+
+ /* Set Config register */
+ tmpReg = 0;
+ if (p_FmPort->imEn)
+ tmpReg |= BMI_PORT_CFG_IM;
+ /* No discard - all error frames go to error queue */
+ else if (p_Params->frmDiscardOverride)
+ tmpReg |= BMI_PORT_CFG_FDOVR;
+
+ WRITE_UINT32(p_Regs->fmbm_rcfg, tmpReg);
+
+ /* Configure dma attributes */
+ tmpReg = 0;
+ tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT;
+ if(p_Params->dmaWriteOptimize)
+ tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
+
+ WRITE_UINT32(p_Regs->fmbm_rda, tmpReg);
+
+ /* Configure Rx Fifo params */
+ tmpReg = 0;
+ tmpReg |= ((p_Params->rxFifoPriElevationLevel/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_PRI_ELEVATION_SHIFT);
+ tmpReg |= ((p_Params->rxFifoThreshold/BMI_FIFO_UNITS - 1) << BMI_RX_FIFO_THRESHOLD_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_rfp, tmpReg);
+
+ {
+#ifdef FM_NO_THRESHOLD_REG
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if (revInfo.majorRev > 1)
+#endif /* FM_NO_THRESHOLD_REG */
+ /* always allow access to the extra resources */
+ WRITE_UINT32(p_Regs->fmbm_reth, BMI_RX_FIFO_THRESHOLD_BC);
+ }
+
+ /* frame end parameters */
+ tmpReg = 0;
+ tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_RX_FRAME_END_CS_IGNORE_SHIFT);
+ tmpReg |= ((uint32_t)p_Params->cutBytesFromEnd<< BMI_RX_FRAME_END_CUT_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_rfed, tmpReg);
+
+ /* IC parameters */
+ tmpReg = 0;
+ tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT);
+ tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT);
+ tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_ricp, tmpReg);
+
+ if (!p_FmPort->imEn)
+ {
+ /* check if the largest external buffer pool is large enough */
+ if(p_Params->bufMargins.startMargins + MIN_EXT_BUF_SIZE + p_Params->bufMargins.endMargins > p_FmPort->rxPoolsParams.largestBufSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)",
+ p_Params->bufMargins.startMargins, p_Params->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize));
+
+ /* buffer margins */
+ tmpReg = 0;
+ tmpReg |= (((uint32_t)p_Params->bufMargins.startMargins) << BMI_EXT_BUF_MARG_START_SHIFT);
+ tmpReg |= (((uint32_t)p_Params->bufMargins.endMargins) << BMI_EXT_BUF_MARG_END_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_rebm, tmpReg);
+ }
+
+
+ if(p_FmPort->internalBufferOffset)
+ {
+ tmpReg = (uint32_t)((p_FmPort->internalBufferOffset % OFFSET_UNITS) ?
+ (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1):
+ (p_FmPort->internalBufferOffset/OFFSET_UNITS));
+ p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS);
+ WRITE_UINT32(p_Regs->fmbm_rim, tmpReg << BMI_IM_FOF_SHIFT);
+ }
+
+ /* NIA */
+ if (p_FmPort->imEn)
+ WRITE_UINT32(p_Regs->fmbm_rfne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX);
+ else
+ {
+ tmpReg = 0;
+ if (p_Params->forwardReuseIntContext)
+ tmpReg |= BMI_PORT_RFNE_FRWD_RPD;
+ /* L3/L4 checksum verify is enabled by default. */
+ /*tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C;*/
+ WRITE_UINT32(p_Regs->fmbm_rfne, tmpReg | NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME);
+ }
+ WRITE_UINT32(p_Regs->fmbm_rfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
+
+ /* command attribute */
+ tmpReg = BMI_CMD_RX_MR_DEF;
+ if (!p_FmPort->imEn)
+ {
+ tmpReg |= BMI_CMD_ATTR_ORDER;
+ if(p_Params->syncReq)
+ tmpReg |= BMI_CMD_ATTR_SYNC;
+ tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT);
+ }
+
+ WRITE_UINT32(p_Regs->fmbm_rfca, tmpReg);
+
+ /* default queues */
+ if (!p_FmPort->imEn)
+ {
+ WRITE_UINT32(p_Regs->fmbm_rfqid, p_Params->dfltFqid);
+ WRITE_UINT32(p_Regs->fmbm_refqid, p_Params->errFqid);
+ }
+
+ /* set counters */
+ WRITE_UINT32(p_Regs->fmbm_rstc, BMI_COUNTERS_EN);
+
+ performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
+ performanceContersParams.queueCompVal = 1;
+ performanceContersParams.dmaCompVal =(uint8_t) p_FmPort->openDmas.num;
+ performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num;
+ if((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ WRITE_UINT32(p_Regs->fmbm_rpc, BMI_COUNTERS_EN);
+
+ /* error/status mask - check that if discard OV is set, no
+ discard is required for specific errors.*/
+ WRITE_UINT32(p_Regs->fmbm_rfsdm, p_Params->errorsToDiscard);
+
+ errorsToEnq = (RX_ERRS_TO_ENQ & ~p_Params->errorsToDiscard);
+ WRITE_UINT32(p_Regs->fmbm_rfsem, errorsToEnq);
+
+#ifdef FM_BMI_TO_RISC_ENQ_ERRATA_FMANc
+ if((GET_UINT32(p_Regs->fmbm_rfene) && NIA_ENG_MASK)== NIA_ENG_FM_CTL)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("NIA not supported at this stage"));
+#endif /* FM_BMI_TO_RISC_ENQ_ERRATA_FMANc */
+
+ return E_OK;
+}
+
+static t_Error BmiTxPortInit(t_FmPort *p_FmPort)
+{
+ t_FmPortTxBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs;
+ uint32_t tmpReg;
+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
+ /*uint32_t rateCountUnit;*/
+ t_FmPortPerformanceCnt performanceContersParams;
+
+ /* check that port is not busy */
+ if (GET_UINT32(p_Regs->fmbm_tcfg) & BMI_PORT_CFG_EN)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled"));
+
+ tmpReg = 0;
+ if (p_FmPort->imEn)
+ tmpReg |= BMI_PORT_CFG_IM;
+
+ WRITE_UINT32(p_Regs->fmbm_tcfg, tmpReg);
+
+ /* Configure dma attributes */
+ tmpReg = 0;
+ tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT;
+
+ WRITE_UINT32(p_Regs->fmbm_tda, tmpReg);
+
+ /* Configure Tx Fifo params */
+ tmpReg = 0;
+ tmpReg |= ((p_Params->txFifoMinFillLevel/BMI_FIFO_UNITS) << BMI_TX_FIFO_MIN_FILL_SHIFT);
+ tmpReg |= (((uint32_t)p_FmPort->txFifoDeqPipelineDepth - 1) << BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT);
+ tmpReg |= ((p_Params->txFifoLowComfLevel/BMI_FIFO_UNITS - 1) << BMI_TX_LOW_COMF_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_tfp, tmpReg);
+
+ /* frame end parameters */
+ tmpReg = 0;
+ tmpReg |= ((uint32_t)p_Params->cheksumLastBytesIgnore << BMI_TX_FRAME_END_CS_IGNORE_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_tfed, tmpReg);
+
+ if (!p_FmPort->imEn)
+ {
+ /* IC parameters */
+ tmpReg = 0;
+ tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT);
+ tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT);
+ tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_ticp, tmpReg);
+ }
+
+ /* NIA */
+ if (p_FmPort->imEn)
+ {
+ WRITE_UINT32(p_Regs->fmbm_tfne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX);
+ WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX);
+ }
+ else
+ {
+ WRITE_UINT32(p_Regs->fmbm_tfne, NIA_ENG_QMI_DEQ);
+ WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
+ /* The line bellow is a trick so the FM will not release the buffer
+ to BM nor will try to enq the frame to QM */
+ if(!p_Params->dfltFqid && p_Params->dontReleaseBuf)
+ {
+ /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
+ * act acording to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
+ * buffers to BM regardless of fmbm_tfene
+ */
+ WRITE_UINT32(p_Regs->fmbm_tcfqid, 0xFFFFFF);
+ WRITE_UINT32(p_Regs->fmbm_tfene, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
+ }
+ }
+
+ /* command attribute */
+ tmpReg = BMI_CMD_TX_MR_DEF;
+ if (p_FmPort->imEn)
+ tmpReg |= BMI_CMD_MR_DEAS;
+ else
+ {
+ tmpReg |= BMI_CMD_ATTR_ORDER;
+ /* if we set syncReq, we may get stuck when HC command is running */
+ /*if(p_Params->syncReq)
+ tmpReg |= BMI_CMD_ATTR_SYNC;*/
+ tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT);
+ }
+
+ WRITE_UINT32(p_Regs->fmbm_tfca, tmpReg);
+
+ /* default queues */
+ if (!p_FmPort->imEn)
+ {
+ if(p_Params->dfltFqid || !p_Params->dontReleaseBuf)
+ WRITE_UINT32(p_Regs->fmbm_tcfqid, p_Params->dfltFqid);
+ WRITE_UINT32(p_Regs->fmbm_tfeqid, p_Params->errFqid);
+ }
+
+ /* statistics & performance counters */
+ WRITE_UINT32(p_Regs->fmbm_tstc, BMI_COUNTERS_EN);
+
+ performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
+ performanceContersParams.queueCompVal = 1;
+ performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
+ performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num;
+ FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams);
+
+ WRITE_UINT32(p_Regs->fmbm_tpc, BMI_COUNTERS_EN);
+
+ return E_OK;
+}
+
+static t_Error BmiOhPortInit(t_FmPort *p_FmPort)
+{
+ t_FmPortOhBmiRegs *p_Regs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs;
+ uint32_t tmpReg, errorsToEnq = 0;
+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
+ t_FmPortPerformanceCnt performanceContersParams;
+ t_Error err;
+
+ /* check that port is not busy */
+ if (GET_UINT32(p_Regs->fmbm_ocfg) & BMI_PORT_CFG_EN)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled"));
+
+ /* Configure dma attributes */
+ tmpReg = 0;
+ tmpReg |= (uint32_t)p_Params->dmaSwapData << BMI_DMA_ATTR_SWP_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaIntContextCacheAttr << BMI_DMA_ATTR_IC_CACHE_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaHeaderCacheAttr << BMI_DMA_ATTR_HDR_CACHE_SHIFT;
+ tmpReg |= (uint32_t)p_Params->dmaScatterGatherCacheAttr << BMI_DMA_ATTR_SG_CACHE_SHIFT;
+ if(p_Params->dmaWriteOptimize)
+ tmpReg |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
+
+ WRITE_UINT32(p_Regs->fmbm_oda, tmpReg);
+
+ /* IC parameters */
+ tmpReg = 0;
+ tmpReg |= (((uint32_t)p_Params->intContext.extBufOffset/OFFSET_UNITS) << BMI_IC_TO_EXT_SHIFT);
+ tmpReg |= (((uint32_t)p_Params->intContext.intContextOffset/OFFSET_UNITS) << BMI_IC_FROM_INT_SHIFT);
+ tmpReg |= (((uint32_t)p_Params->intContext.size/OFFSET_UNITS) << BMI_IC_SIZE_SHIFT);
+
+ WRITE_UINT32(p_Regs->fmbm_oicp, tmpReg);
+
+ /* NIA */
+ WRITE_UINT32(p_Regs->fmbm_ofdne, NIA_ENG_QMI_DEQ);
+
+ if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ);
+ else
+ WRITE_UINT32(p_Regs->fmbm_ofene, NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
+
+ /* command attribute */
+ if (p_FmPort->portType==e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ tmpReg = BMI_CMD_MR_DEAS | BMI_CMD_MR_MA;
+ else
+ tmpReg = BMI_CMD_ATTR_ORDER | BMI_CMD_MR_DEAS | BMI_CMD_MR_MA;
+
+ if(p_Params->syncReq)
+ tmpReg |= BMI_CMD_ATTR_SYNC;
+ tmpReg |= ((uint32_t)p_Params->color << BMI_CMD_ATTR_COLOR_SHIFT);
+ WRITE_UINT32(p_Regs->fmbm_ofca, tmpReg);
+
+ /* No discard - all error frames go to error queue */
+ if (p_Params->frmDiscardOverride)
+ tmpReg = BMI_PORT_CFG_FDOVR;
+ else
+ tmpReg = 0;
+ WRITE_UINT32(p_Regs->fmbm_ocfg, tmpReg);
+
+ if(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ {
+ WRITE_UINT32(p_Regs->fmbm_ofsdm, p_Params->errorsToDiscard);
+
+ errorsToEnq = (OP_ERRS_TO_ENQ & ~p_Params->errorsToDiscard);
+ WRITE_UINT32(p_Regs->fmbm_ofsem, errorsToEnq);
+
+ /* NIA */
+ WRITE_UINT32(p_Regs->fmbm_ofne, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME);
+ {
+#ifdef FM_NO_OP_OBSERVED_POOLS
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 4) && (p_Params->enBufPoolDepletion))
+#endif /* FM_NO_OP_OBSERVED_POOLS */
+ {
+ /* define external buffer pools */
+ err = SetExtBufferPools(p_FmPort);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+ }
+ else
+ /* NIA */
+ WRITE_UINT32(p_Regs->fmbm_ofne, NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC);
+
+ /* default queues */
+ WRITE_UINT32(p_Regs->fmbm_ofqid, p_Params->dfltFqid);
+ WRITE_UINT32(p_Regs->fmbm_oefqid, p_Params->errFqid);
+
+ if(p_FmPort->internalBufferOffset)
+ {
+ tmpReg = (uint32_t)((p_FmPort->internalBufferOffset % OFFSET_UNITS) ?
+ (p_FmPort->internalBufferOffset/OFFSET_UNITS + 1):
+ (p_FmPort->internalBufferOffset/OFFSET_UNITS));
+ p_FmPort->internalBufferOffset = (uint8_t)(tmpReg * OFFSET_UNITS);
+ WRITE_UINT32(p_Regs->fmbm_oim, tmpReg << BMI_IM_FOF_SHIFT);
+ }
+ /* statistics & performance counters */
+ WRITE_UINT32(p_Regs->fmbm_ostc, BMI_COUNTERS_EN);
+
+ performanceContersParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
+ performanceContersParams.queueCompVal = 0;
+ performanceContersParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
+ performanceContersParams.fifoCompVal = p_FmPort->fifoBufs.num;
+ FM_PORT_SetPerformanceCountersParams(p_FmPort, &performanceContersParams);
+
+ WRITE_UINT32(p_Regs->fmbm_opc, BMI_COUNTERS_EN);
+
+ return E_OK;
+}
+
+static t_Error QmiInit(t_FmPort *p_FmPort)
+{
+ t_FmPortDriverParam *p_Params = NULL;
+ uint32_t tmpReg;
+
+ p_Params = p_FmPort->p_FmPortDriverParam;
+
+ /* check that port is not busy */
+ if(((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_RX)) &&
+ (GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is already enabled"));
+
+ /* enable & clear counters */
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, QMI_PORT_CFG_EN_COUNTERS);
+
+ /* The following is done for non-Rx ports only */
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ {
+ if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_TX))
+ {
+ /* define dequeue NIA */
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX);
+ /* define enqueue NIA */
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
+ }
+ else /* for HC & OP */
+ {
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH);
+ /* define enqueue NIA */
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
+ }
+
+ /* configure dequeue */
+ tmpReg = 0;
+ if(p_Params->deqHighPriority)
+ tmpReg |= QMI_DEQ_CFG_PRI;
+
+ switch(p_Params->deqType)
+ {
+ case(e_FM_PORT_DEQ_TYPE1):
+ tmpReg |= QMI_DEQ_CFG_TYPE1;
+ break;
+ case(e_FM_PORT_DEQ_TYPE2):
+ tmpReg |= QMI_DEQ_CFG_TYPE2;
+ break;
+ case(e_FM_PORT_DEQ_TYPE3):
+ tmpReg |= QMI_DEQ_CFG_TYPE3;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue type"));
+ }
+
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ switch(p_Params->deqPrefetchOption)
+ {
+ case(e_FM_PORT_DEQ_NO_PREFETCH):
+ /* Do nothing - QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_1_FRAME = 0 */
+ break;
+ case(e_FM_PORT_DEQ_PARTIAL_PREFETCH):
+ tmpReg |= QMI_DEQ_CFG_PREFETCH_WAITING_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES;
+ break;
+ case(e_FM_PORT_DEQ_FULL_PREFETCH):
+ tmpReg |= QMI_DEQ_CFG_PREFETCH_NO_TNUM | QMI_DEQ_CFG_PREFETCH_3_FRAMES;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid dequeue prefetch option"));
+ }
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+ tmpReg |= p_Params->deqByteCnt;
+ tmpReg |= (uint32_t)p_Params->deqSubPortal << QMI_DEQ_CFG_SUBPORTAL_SHIFT;
+
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndc, tmpReg);
+ }
+ else /* rx port */
+ /* define enqueue NIA */
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
+
+ return E_OK;
+}
+
+static t_Error BmiRxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr)
+{
+ t_FmPortRxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs;
+
+ /* check that counters are enabled */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_CYCLE):
+ case(e_FM_PORT_COUNTERS_TASK_UTIL):
+ case(e_FM_PORT_COUNTERS_QUEUE_UTIL):
+ case(e_FM_PORT_COUNTERS_DMA_UTIL):
+ case(e_FM_PORT_COUNTERS_FIFO_UTIL):
+ case(e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
+ /* performance counters - may be read when disabled */
+ break;
+ case(e_FM_PORT_COUNTERS_FRAME):
+ case(e_FM_PORT_COUNTERS_DISCARD_FRAME):
+ case(e_FM_PORT_COUNTERS_RX_BAD_FRAME):
+ case(e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
+ case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
+ case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
+ case(e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
+ case(e_FM_PORT_COUNTERS_DEALLOC_BUF):
+ if(!(GET_UINT32(p_BmiRegs->fmbm_rstc) & BMI_COUNTERS_EN))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports"));
+ }
+
+ /* Set counter */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_CYCLE):
+ *p_Ptr = &p_BmiRegs->fmbm_rccn;
+ break;
+ case(e_FM_PORT_COUNTERS_TASK_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_rtuc;
+ break;
+ case(e_FM_PORT_COUNTERS_QUEUE_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_rrquc;
+ break;
+ case(e_FM_PORT_COUNTERS_DMA_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_rduc;
+ break;
+ case(e_FM_PORT_COUNTERS_FIFO_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_rfuc;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
+ *p_Ptr = &p_BmiRegs->fmbm_rpac;
+ break;
+ case(e_FM_PORT_COUNTERS_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_rfrc;
+ break;
+ case(e_FM_PORT_COUNTERS_DISCARD_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_rfcd;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_BAD_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_rfbc;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_rlfc;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_rffc;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
+#ifdef FM_PORT_COUNTERS_ERRATA_FMANg
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Requested counter is not available in rev1"));
+ }
+#endif /* FM_PORT_COUNTERS_ERRATA_FMANg */
+ *p_Ptr = &p_BmiRegs->fmbm_rfldec;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
+ *p_Ptr = &p_BmiRegs->fmbm_rodc;
+ break;
+ case(e_FM_PORT_COUNTERS_DEALLOC_BUF):
+ *p_Ptr = &p_BmiRegs->fmbm_rbdc;
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports"));
+ }
+
+ return E_OK;
+}
+
+static t_Error BmiTxPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr)
+{
+ t_FmPortTxBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs;
+
+ /* check that counters are enabled */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_CYCLE):
+ case(e_FM_PORT_COUNTERS_TASK_UTIL):
+ case(e_FM_PORT_COUNTERS_QUEUE_UTIL):
+ case(e_FM_PORT_COUNTERS_DMA_UTIL):
+ case(e_FM_PORT_COUNTERS_FIFO_UTIL):
+ /* performance counters - may be read when disabled */
+ break;
+ case(e_FM_PORT_COUNTERS_FRAME):
+ case(e_FM_PORT_COUNTERS_DISCARD_FRAME):
+ case(e_FM_PORT_COUNTERS_LENGTH_ERR):
+ case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
+ case(e_FM_PORT_COUNTERS_DEALLOC_BUF):
+ if(!(GET_UINT32(p_BmiRegs->fmbm_tstc) & BMI_COUNTERS_EN))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports"));
+ }
+
+ /* Set counter */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_CYCLE):
+ *p_Ptr = &p_BmiRegs->fmbm_tccn;
+ break;
+ case(e_FM_PORT_COUNTERS_TASK_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_ttuc;
+ break;
+ case(e_FM_PORT_COUNTERS_QUEUE_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_ttcquc;
+ break;
+ case(e_FM_PORT_COUNTERS_DMA_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_tduc;
+ break;
+ case(e_FM_PORT_COUNTERS_FIFO_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_tfuc;
+ break;
+ case(e_FM_PORT_COUNTERS_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_tfrc;
+ break;
+ case(e_FM_PORT_COUNTERS_DISCARD_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_tfdc;
+ break;
+ case(e_FM_PORT_COUNTERS_LENGTH_ERR):
+ *p_Ptr = &p_BmiRegs->fmbm_tfledc;
+ break;
+ case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
+ *p_Ptr = &p_BmiRegs->fmbm_tfufdc;
+ break;
+ case(e_FM_PORT_COUNTERS_DEALLOC_BUF):
+ *p_Ptr = &p_BmiRegs->fmbm_tbdc;
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Tx ports"));
+ }
+
+ return E_OK;
+}
+
+static t_Error BmiOhPortCheckAndGetCounterPtr(t_FmPort *p_FmPort, e_FmPortCounters counter, volatile uint32_t **p_Ptr)
+{
+ t_FmPortOhBmiRegs *p_BmiRegs = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs;
+
+ /* check that counters are enabled */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_CYCLE):
+ case(e_FM_PORT_COUNTERS_TASK_UTIL):
+ case(e_FM_PORT_COUNTERS_DMA_UTIL):
+ case(e_FM_PORT_COUNTERS_FIFO_UTIL):
+ /* performance counters - may be read when disabled */
+ break;
+ case(e_FM_PORT_COUNTERS_FRAME):
+ case(e_FM_PORT_COUNTERS_DISCARD_FRAME):
+ case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
+ case(e_FM_PORT_COUNTERS_WRED_DISCARD):
+ case(e_FM_PORT_COUNTERS_LENGTH_ERR):
+ case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
+ case(e_FM_PORT_COUNTERS_DEALLOC_BUF):
+ if(!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ break;
+ case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME): /* only valid for offline parsing */
+ if(p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Host Command ports"));
+ if(!(GET_UINT32(p_BmiRegs->fmbm_ostc) & BMI_COUNTERS_EN))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for O/H ports"));
+ }
+
+ /* Set counter */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_CYCLE):
+ *p_Ptr = &p_BmiRegs->fmbm_occn;
+ break;
+ case(e_FM_PORT_COUNTERS_TASK_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_otuc;
+ break;
+ case(e_FM_PORT_COUNTERS_DMA_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_oduc;
+ break;
+ case(e_FM_PORT_COUNTERS_FIFO_UTIL):
+ *p_Ptr = &p_BmiRegs->fmbm_ofuc;
+ break;
+ case(e_FM_PORT_COUNTERS_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_ofrc;
+ break;
+ case(e_FM_PORT_COUNTERS_DISCARD_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_ofdc;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
+ *p_Ptr = &p_BmiRegs->fmbm_offc;
+ break;
+ case(e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
+#ifdef FM_PORT_COUNTERS_ERRATA_FMANg
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Requested counter is not available in rev1"));
+ }
+#endif /* FM_PORT_COUNTERS_ERRATA_FMANg */
+ *p_Ptr = &p_BmiRegs->fmbm_ofldec;
+ break;
+ case(e_FM_PORT_COUNTERS_WRED_DISCARD):
+ *p_Ptr = &p_BmiRegs->fmbm_ofwdc;
+ break;
+ case(e_FM_PORT_COUNTERS_LENGTH_ERR):
+ *p_Ptr = &p_BmiRegs->fmbm_ofledc;
+ break;
+ case(e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
+ *p_Ptr = &p_BmiRegs->fmbm_ofufdc;
+ break;
+ case(e_FM_PORT_COUNTERS_DEALLOC_BUF):
+ *p_Ptr = &p_BmiRegs->fmbm_obdc;
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for O/H ports"));
+ }
+
+ return E_OK;
+}
+
+static t_Error AdditionalPrsParams(t_FmPort *p_FmPort, t_FmPcdPrsAdditionalHdrParams *p_HdrParams, uint32_t *p_SoftSeqAttachReg)
+{
+ uint8_t hdrNum, Ipv4HdrNum;
+ u_FmPcdHdrPrsOpts *p_prsOpts;
+ uint32_t tmpReg = 0, tmpPrsOffset;
+
+ if(IS_PRIVATE_HEADER(p_HdrParams->hdr) || IS_SPECIAL_HEADER(p_HdrParams->hdr))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("No additional parameters for private or special headers."));
+
+ if(p_HdrParams->errDisable)
+ tmpReg |= PRS_HDR_ERROR_DIS;
+
+ /* Set parser options */
+ if(p_HdrParams->usePrsOpts)
+ {
+ p_prsOpts = &p_HdrParams->prsOpts;
+ switch(p_HdrParams->hdr)
+ {
+ case(HEADER_TYPE_MPLS):
+ if(p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
+ tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
+ GET_PRS_HDR_NUM(hdrNum, p_prsOpts->mplsPrsOptions.nextParse);
+ if(hdrNum == ILLEGAL_HDR_NUM)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
+ GET_PRS_HDR_NUM(Ipv4HdrNum, HEADER_TYPE_IPv4);
+ if(hdrNum < Ipv4HdrNum)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("Header must be equal or higher than IPv4"));
+ tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE) << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
+ break;
+ case(HEADER_TYPE_PPPoE):
+ if(p_prsOpts->pppoePrsOptions.enableMTUCheck)
+ {
+#ifdef FM_PPPOE_NO_MTU_CHECK
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Invalid parser option"));
+ else
+#endif /* FM_PPPOE_NO_MTU_CHECK */
+ tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
+ }
+ break;
+ case(HEADER_TYPE_IPv6):
+ if(p_prsOpts->ipv6PrsOptions.routingHdrDisable)
+ tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_DIS;
+ break;
+ case(HEADER_TYPE_TCP):
+ if(p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
+ tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
+ break;
+ case(HEADER_TYPE_UDP):
+ if(p_prsOpts->udpPrsOptions.padIgnoreChecksum)
+ tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
+ }
+ }
+
+ /* set software parsing (address is devided in 2 since parser uses 2 byte access. */
+ if(p_HdrParams->swPrsEnable)
+ {
+ tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr, p_HdrParams->indexPerHdr);
+ if(tmpPrsOffset == ILLEGAL_BASE)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+ tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
+ }
+ *p_SoftSeqAttachReg = tmpReg;
+
+ return E_OK;
+}
+
+static uint32_t GetPortSchemeBindParams(t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t walking1Mask = 0x80000000, tmp;
+ uint8_t idx = 0;
+
+ p_SchemeBind->netEnvId = p_FmPort->netEnvId;
+ p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
+ p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
+ p_SchemeBind->numOfSchemes = 0;
+ tmp = p_FmPort->schemesPerPortVector;
+ if(tmp)
+ {
+ while (tmp)
+ {
+ if(tmp & walking1Mask)
+ {
+ p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = FmPcdKgGetSchemeSwId(p_FmPort->h_FmPcd, idx);
+ p_SchemeBind->numOfSchemes++;
+ tmp &= ~walking1Mask;
+ }
+ walking1Mask >>= 1;
+ idx++;
+ }
+ }
+
+ return tmp;
+}
+
+static t_Error BuildBufferStructure(t_FmPort *p_FmPort)
+{
+ uint32_t tmp;
+
+ ASSERT_COND(p_FmPort);
+
+ /* Align start of internal context data to 16 byte */
+ p_FmPort->p_FmPortDriverParam->intContext.extBufOffset =
+ (uint16_t)((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize & (OFFSET_UNITS-1)) ?
+ ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize);
+
+ /* Translate margin and intContext params to FM parameters */
+#ifdef FM_INCORRECT_CS_ERRATA_FMAN18
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ uint8_t mod = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign % 256;
+ if(mod)
+ {
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign += (256-mod);
+ DBG(WARNING,("dataAlign modified to next 256 to conform with FMAN18 errata\n"));
+ }
+ }
+ }
+#endif /* FM_INCORRECT_CS_ERRATA_FMAN18 */
+
+ /* Initialize with illegal value. Later we'll set legal values. */
+ p_FmPort->bufferOffsets.prsResultOffset = (uint32_t)ILLEGAL_BASE;
+ p_FmPort->bufferOffsets.timeStampOffset = (uint32_t)ILLEGAL_BASE;
+ p_FmPort->bufferOffsets.hashResultOffset= (uint32_t)ILLEGAL_BASE;
+ p_FmPort->bufferOffsets.pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
+#ifdef DEBUG
+ p_FmPort->bufferOffsets.debugOffset = (uint32_t)ILLEGAL_BASE;
+#endif /* DEBUG */
+
+ /* Internally the driver supports 4 options
+ 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
+ relate to it as 1).
+ 2. All IC context (from AD) except debug.
+ 3. Debug information only.
+ 4. All IC context (from AD) including debug.
+ Note, that if user asks for prsResult/timestamp/hashResult and Debug, we give them (4) */
+
+ /* This 'if' covers options 2 & 4. We copy from beginning of context with or without debug. */
+ /* If passAllOtherPCDInfo explicitly requested, or passDebugInfo+prs/ts --> we also take passAllOtherPCDInfo */
+ if ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo)
+#ifdef DEBUG
+ || (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo &&
+ (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ||
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp ||
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult))
+#endif /* DEBUG */
+ )
+ {
+#ifdef DEBUG
+ if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo)
+ {
+ p_FmPort->p_FmPortDriverParam->intContext.size = 240;
+ p_FmPort->bufferOffsets.debugOffset =
+ (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 128);
+ }
+ else
+#endif /* DEBUG */
+ p_FmPort->p_FmPortDriverParam->intContext.size = 128; /* must be aligned to 16 */
+ /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
+ p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = 16;
+
+ if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo)
+ p_FmPort->bufferOffsets.pcdInfoOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset;
+ if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult)
+ p_FmPort->bufferOffsets.prsResultOffset =
+ (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 16);
+ if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp)
+ p_FmPort->bufferOffsets.timeStampOffset =
+ (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 48);
+ if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult)
+ p_FmPort->bufferOffsets.hashResultOffset =
+ (uint32_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 56);
+ }
+ else
+ {
+#ifdef DEBUG
+ if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo)
+ {
+ /* This case covers option 3 */
+ p_FmPort->p_FmPortDriverParam->intContext.size = 112;
+ p_FmPort->p_FmPortDriverParam->intContext.intContextOffset = 144;
+ p_FmPort->bufferOffsets.debugOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset;
+ }
+ else
+#endif /* DEBUG */
+ {
+ /* This case covers the options under 1 */
+ /* Copy size must be in 16-byte granularity. */
+ p_FmPort->p_FmPortDriverParam->intContext.size =
+ (uint16_t)((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 32 : 0) +
+ ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp ||
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) ? 16 : 0));
+
+ /* Align start of internal context data to 16 byte */
+ p_FmPort->p_FmPortDriverParam->intContext.intContextOffset =
+ (uint8_t)(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ? 32 :
+ ((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp ||
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult) ? 64 : 0));
+
+ if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult)
+ p_FmPort->bufferOffsets.prsResultOffset = p_FmPort->p_FmPortDriverParam->intContext.extBufOffset;
+ if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp)
+ p_FmPort->bufferOffsets.timeStampOffset = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ?
+ (p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + sizeof(t_FmPrsResult)) :
+ p_FmPort->p_FmPortDriverParam->intContext.extBufOffset;
+ if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passHashResult)
+ /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
+ p_FmPort->bufferOffsets.hashResultOffset = p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult ?
+ (p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + sizeof(t_FmPrsResult) + 8) :
+ p_FmPort->p_FmPortDriverParam->intContext.extBufOffset + 8;
+ }
+ }
+
+ p_FmPort->p_FmPortDriverParam->bufMargins.startMargins =
+ (uint16_t)(p_FmPort->p_FmPortDriverParam->intContext.extBufOffset +
+ p_FmPort->p_FmPortDriverParam->intContext.size);
+#ifdef FM_CAPWAP_SUPPORT
+ /* save extra space for manip in both external and internal buffers */
+ if(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace)
+ {
+ if((p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE) >= 256)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + 32 can not be equal or larger to 256"));
+ p_FmPort->bufferOffsets.manipOffset = p_FmPort->p_FmPortDriverParam->bufMargins.startMargins;
+ p_FmPort->p_FmPortDriverParam->bufMargins.startMargins += (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE);
+ p_FmPort->p_FmPortDriverParam->internalBufferOffset =
+ (uint8_t)(p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace + FRAG_EXTRA_SPACE);
+ }
+#endif /* FM_CAPWAP_SUPPORT */
+
+ /* align data start */
+ tmp = (uint32_t)(p_FmPort->p_FmPortDriverParam->bufMargins.startMargins %
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign);
+ if (tmp)
+ p_FmPort->p_FmPortDriverParam->bufMargins.startMargins += (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign-tmp);
+ p_FmPort->bufferOffsets.dataOffset = p_FmPort->p_FmPortDriverParam->bufMargins.startMargins;
+ p_FmPort->internalBufferOffset = p_FmPort->p_FmPortDriverParam->internalBufferOffset;
+
+ return E_OK;
+}
+
+static t_Error SetPcd(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err = E_OK;
+ uint32_t tmpReg;
+ volatile uint32_t *p_BmiNia=NULL;
+ volatile uint32_t *p_BmiPrsNia=NULL;
+ volatile uint32_t *p_BmiPrsStartOffset=NULL;
+ volatile uint32_t *p_BmiInitPrsResult=NULL;
+ volatile uint32_t *p_BmiCcBase=NULL;
+ uint8_t hdrNum, L3HdrNum, greHdrNum;
+ int i;
+ bool isEmptyClsPlanGrp;
+ uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
+ uint16_t absoluteProfileId;
+ uint8_t physicalSchemeId;
+ uint32_t ccTreePhysOffset;
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only"));
+
+ if ((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))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+
+ p_FmPort->netEnvId = (uint8_t)(PTR_TO_UINT(p_PcdParams->h_NetEnv)-1);
+
+ p_FmPort->pcdEngines = 0;
+
+ /* initialize p_FmPort->pcdEngines field in port's structure */
+ switch(p_PcdParams->pcdSupport)
+ {
+ case(e_FM_PORT_PCD_SUPPORT_NONE):
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
+ case(e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
+ p_FmPort->pcdEngines |= FM_PCD_PRS;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
+ if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required"));
+ p_FmPort->pcdEngines |= FM_PCD_PLCR;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
+ p_FmPort->pcdEngines |= FM_PCD_PRS;
+ p_FmPort->pcdEngines |= FM_PCD_PLCR;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
+ p_FmPort->pcdEngines |= FM_PCD_PRS;
+ p_FmPort->pcdEngines |= FM_PCD_KG;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
+ p_FmPort->pcdEngines |= FM_PCD_PRS;
+ p_FmPort->pcdEngines |= FM_PCD_CC;
+ p_FmPort->pcdEngines |= FM_PCD_KG;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
+ p_FmPort->pcdEngines |= FM_PCD_PRS;
+ p_FmPort->pcdEngines |= FM_PCD_KG;
+ p_FmPort->pcdEngines |= FM_PCD_CC;
+ p_FmPort->pcdEngines |= FM_PCD_PLCR;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
+ p_FmPort->pcdEngines |= FM_PCD_PRS;
+ p_FmPort->pcdEngines |= FM_PCD_KG;
+ p_FmPort->pcdEngines |= FM_PCD_PLCR;
+ break;
+
+#ifdef FM_CAPWAP_SUPPORT
+ case(e_FM_PORT_PCD_SUPPORT_CC_ONLY):
+ if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required"));
+ p_FmPort->pcdEngines |= FM_PCD_CC;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
+ if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required"));
+ p_FmPort->pcdEngines |= FM_PCD_CC;
+ p_FmPort->pcdEngines |= FM_PCD_KG;
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
+ if (CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser support is required"));
+ p_FmPort->pcdEngines |= FM_PCD_CC;
+ p_FmPort->pcdEngines |= FM_PCD_KG;
+ p_FmPort->pcdEngines |= FM_PCD_PLCR;
+ break;
+#endif /* FM_CAPWAP_SUPPORT */
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
+ }
+
+ if((p_FmPort->pcdEngines & FM_PCD_PRS) && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams > FM_PCD_PRS_NUM_OF_HDRS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
+
+ /* check that parameters exist for each and only each defined engine */
+ if((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams) ||
+ (!!(p_FmPort->pcdEngines & FM_PCD_KG) != !!p_PcdParams->p_KgParams) ||
+ (!!(p_FmPort->pcdEngines & FM_PCD_CC) != !!p_PcdParams->p_CcParams))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("PCD initialization structure is not consistant with pcdSupport"));
+
+ /* get PCD registers pointers */
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne;
+ p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne;
+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso;
+ p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[0];
+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne;
+ p_BmiPrsNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne;
+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso;
+ p_BmiInitPrsResult = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[0];
+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_occb;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ if(p_FmPort->pcdEngines & FM_PCD_KG)
+ {
+
+ if(p_PcdParams->p_KgParams->numOfSchemes == 0)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("For ports using Keygen, at lease one scheme must be bound. "));
+ /* for each scheme */
+ for(i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
+ {
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_Schemes[i])-1);
+ /* build vector */
+ p_FmPort->schemesPerPortVector |= 1 << (31 - (uint32_t)physicalSchemeId);
+ }
+
+ err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
+ p_FmPort->hardwarePortId,
+ p_FmPort->netEnvId,
+ p_FmPort->optArray,
+ &p_FmPort->clsPlanGrpId,
+ &isEmptyClsPlanGrp);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
+
+ p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
+ }
+
+ /* set PCD port parameter */
+ if(p_FmPort->pcdEngines & FM_PCD_CC)
+ {
+ err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams->p_CcParams->h_CcTree, &ccTreePhysOffset, h_FmPort);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
+ p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
+ }
+
+ /***************************/
+ /* configure NIA after BMI */
+ /***************************/
+ if (!CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia))
+ /* rfne may contain FDCS bits, so first we read them. */
+ p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
+
+ /* If policer is used directly after BMI or PRS */
+ if((p_FmPort->pcdEngines & FM_PCD_PLCR) &&
+ ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY) ||
+ (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
+ {
+ absoluteProfileId = (uint16_t)(PTR_TO_UINT(p_PcdParams->p_PlcrParams->h_Profile)-1);
+
+ if(!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Private port profile not valid."));
+
+ tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
+
+ if(p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
+ {
+ /* update BMI HPNIA */
+ WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
+ }
+ else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
+ /* update BMI NIA */
+ p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
+ }
+
+#ifdef FM_CAPWAP_SUPPORT
+ /* if CC is used directly after BMI */
+ if((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) ||
+ (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) ||
+ (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR))
+ {
+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
+ p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
+ /* check that prs start offset == RIM[FOF] */
+ }
+#endif /* FM_CAPWAP_SUPPORT */
+
+ if (p_FmPort->pcdEngines & FM_PCD_PRS)
+ {
+ ASSERT_COND(p_PcdParams->p_PrsParams);
+ /* if PRS is used it is always first */
+ GET_PRS_HDR_NUM(hdrNum, p_PcdParams->p_PrsParams->firstPrsHdr);
+ if (hdrNum == ILLEGAL_HDR_NUM)
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
+ if (!CHECK_FM_CTL_AC_POST_FETCH_PCD(p_FmPort->savedBmiNia))
+ p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
+ /* set after parser NIA */
+ tmpReg = 0;
+ switch(p_PcdParams->pcdSupport)
+ {
+ case(e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
+ WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME);
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
+ tmpReg = NIA_KG_CC_EN;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
+ if(p_PcdParams->p_KgParams->directScheme)
+ {
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_DirectScheme)-1);
+ /* check that this scheme was bound to this port */
+ for(i=0 ; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
+ if(p_PcdParams->p_KgParams->h_DirectScheme == p_PcdParams->p_KgParams->h_Schemes[i])
+ break;
+ if(i == p_PcdParams->p_KgParams->numOfSchemes)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Direct scheme is not one of the port selected schemes."));
+ tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
+ }
+ WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
+ break;
+ case(e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
+ }
+
+ /* set start parsing offset */
+ /* WRITE_UINT32(*p_BmiPrsStartOffset, p_PcdParams->p_PrsParams->parsingOffset); */
+
+ /************************************/
+ /* Parser port parameters */
+ /************************************/
+ /* stop before configuring */
+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
+ /* wait for parser to be in idle state */
+ while(GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) ;
+
+ /* set soft seq attachment register */
+ memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
+
+ /* set protocol options */
+ for(i=0;p_FmPort->optArray[i];i++)
+ switch(p_FmPort->optArray[i])
+ {
+ case(ETH_BROADCAST):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_BC_SHIFT;
+ break;
+ case(ETH_MULTICAST):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_ETH)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_ETH_MC_SHIFT;
+ break;
+ case(VLAN_STACKED):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_VLAN)
+ tmpHxs[hdrNum] |= (i+1)<< PRS_HDR_VLAN_STACKED_SHIFT;
+ break;
+ case(MPLS_STACKED):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_MPLS_STACKED_SHIFT;
+ break;
+ case(IPV4_BROADCAST_1):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_BC_SHIFT;
+ break;
+ case(IPV4_MULTICAST_1):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_1_MC_SHIFT;
+ break;
+ case(IPV4_UNICAST_2):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_UC_SHIFT;
+ break;
+ case(IPV4_MULTICAST_BROADCAST_2):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv4)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
+ break;
+ case(IPV6_MULTICAST_1):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_1_MC_SHIFT;
+ break;
+ case(IPV6_UNICAST_2):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_2_UC_SHIFT;
+ break;
+ case(IPV6_MULTICAST_2):
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPv6)
+ tmpHxs[hdrNum] |= (i+1) << PRS_HDR_IPV6_2_MC_SHIFT;
+ break;
+ }
+
+ if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP))
+ {
+ p_PcdParams->p_PrsParams->additionalParams
+ [p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr = HEADER_TYPE_UDP;
+ p_PcdParams->p_PrsParams->additionalParams
+ [p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable = TRUE;
+ p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
+ }
+
+ /* set MPLS default next header - HW reset workaround */
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_MPLS)
+ tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
+ GET_PRS_HDR_NUM(L3HdrNum, HEADER_TYPE_USER_DEFINED_L3);
+ tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
+
+ /* for GRE, disable errors */
+ GET_PRS_HDR_NUM(greHdrNum, HEADER_TYPE_GRE);
+ tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
+
+ /* config additional params for specific headers */
+ for(i=0 ; i<p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams ; i++)
+ {
+ GET_PRS_HDR_NUM(hdrNum, p_PcdParams->p_PrsParams->additionalParams[i].hdr);
+ if(hdrNum== ILLEGAL_HDR_NUM)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
+ if(hdrNum==NO_HDR_NUM)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Private headers may not use additional parameters"));
+
+ err = AdditionalPrsParams(p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i], &tmpReg);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
+
+ tmpHxs[hdrNum] |= tmpReg;
+ }
+#ifdef FM_PRS_L4_SHELL_ERRATA_FMANb
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ /* link to sw parser code for L4 shells - only if no other code is applied. */
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_SCTP)
+ if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | SCTP_SW_PATCH_START);
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_DCCP)
+ if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | DCCP_SW_PATCH_START);
+ GET_PRS_HDR_NUM(hdrNum, HEADER_TYPE_IPSEC_AH)
+ if(!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | IPSEC_SW_PATCH_START);
+ }
+ }
+#endif /* FM_PRS_L4_SHELL_ERRATA_FMANb */
+
+ for(i=0 ; i<FM_PCD_PRS_NUM_OF_HDRS ; i++)
+ {
+ /* For all header set LCV as taken from netEnv*/
+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv, FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
+ /* set HXS register according to default+Additional params+protocol options */
+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach, tmpHxs[i]);
+ }
+
+ /* set tpid. */
+ tmpReg = PRS_TPID_DFLT;
+ if(p_PcdParams->p_PrsParams->setVlanTpid1)
+ {
+ tmpReg &= PRS_TPID2_MASK;
+ tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1 << PRS_PCTPID_SHIFT;
+ }
+ if(p_PcdParams->p_PrsParams->setVlanTpid2)
+ {
+ tmpReg &= PRS_TPID1_MASK;
+ tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
+ }
+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
+
+ /* enable parser */
+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
+
+ if(p_PcdParams->p_PrsParams->prsResultPrivateInfo)
+ p_FmPort->privateInfo = p_PcdParams->p_PrsParams->prsResultPrivateInfo;
+
+ } /* end parser */
+ else
+ p_FmPort->privateInfo = 0;
+
+ WRITE_UINT32(*p_BmiPrsStartOffset, GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
+
+ /* set initial parser result - used for all engines */
+ for (i=0;i<FM_PORT_PRS_RESULT_NUM_OF_WORDS;i++)
+ {
+ if (!i)
+ WRITE_UINT32(*(p_BmiInitPrsResult), (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT)
+ | BMI_PRS_RESULT_HIGH));
+ else
+ if (i< FM_PORT_PRS_RESULT_NUM_OF_WORDS/2)
+ WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
+ else
+ WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
+ }
+
+ return E_OK;
+}
+
+static t_Error DeletePcd(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err = E_OK;
+ volatile uint32_t *p_BmiNia=NULL;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only"));
+
+ if ((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))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+
+ if(!p_FmPort->pcdEngines)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
+
+ /* get PCD registers pointers */
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ if((GET_UINT32(*p_BmiNia) & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("port has to be detached previousely"));
+
+ /* "cut" PCD out of the port's flow - go to BMI */
+ /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
+
+ if(p_FmPort->pcdEngines | FM_PCD_PRS)
+ {
+ /* stop parser */
+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
+ /* wait for parser to be in idle state */
+ while(GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) ;
+ }
+
+ if(p_FmPort->pcdEngines & FM_PCD_KG)
+ {
+ err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, p_FmPort->clsPlanGrpId);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ p_FmPort->useClsPlan = FALSE;
+ }
+
+ if(p_FmPort->pcdEngines & FM_PCD_CC)
+ {
+ /* unbind - we need to get the treeId too */
+ err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ p_FmPort->pcdEngines = 0;
+
+ return E_OK;
+}
+
+
+/********************************************/
+/* Inter-module API */
+/********************************************/
+void FmPortSetMacsecLcv(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiCfgReg = NULL;
+ uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
+ uint32_t lcv, walking1Mask = 0x80000000;
+ uint8_t cnt = 0;
+
+ SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Rx ports only"));
+ return;
+ }
+
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg;
+ /* get LCV for MACSEC */
+ if ((p_FmPort->h_FmPcd) && ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))!= 0))
+ {
+ while(!(lcv & walking1Mask))
+ {
+ cnt++;
+ walking1Mask >>= 1;
+ }
+
+ macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
+ }
+
+ WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
+}
+
+void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiCfgReg = NULL;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
+ return;
+ }
+
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfca;
+ tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
+ tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
+ tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT) & BMI_CMD_ATTR_MACCMD_SC_MASK);
+
+ WRITE_UINT32(*p_BmiCfgReg, tmpReg);
+}
+
+uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
+{
+ return ((t_FmPort*)h_FmPort)->netEnvId;
+}
+
+uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
+{
+ return ((t_FmPort*)h_FmPort)->hardwarePortId;
+}
+
+uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
+{
+ return ((t_FmPort*)h_FmPort)->pcdEngines;
+}
+
+t_Error FmPortAttachPCD(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiNia=NULL;
+
+/*TODO - to take care about the chnges that were made in the port because of the previously assigned tree.
+pndn, pnen ... maybe were changed because of the Tree requirement*/
+
+ /* get PCD registers pointers */
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+ }
+
+ if(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
+ if(FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1)!= E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+
+ /* check that current NIA is BMI to BMI */
+ if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state."));
+
+ WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
+
+ if(p_FmPort->requiredAction & UPDATE_NIA_PNEN)
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, p_FmPort->savedQmiPnen);
+
+ if(p_FmPort->requiredAction & UPDATE_NIA_PNDN)
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, p_FmPort->savedNonRxQmiRegsPndn);
+
+
+ return E_OK;
+}
+
+t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_CcParams)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ int tmpInt;
+ volatile uint32_t *p_BmiPrsStartOffset = NULL;
+
+ /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
+
+ if((p_CcParams->getCcParams.type & OFFSET_OF_PR) && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
+ {
+ p_CcParams->getCcParams.prOffset = (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
+ p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
+ }
+ if(p_CcParams->getCcParams.type & HW_PORT_ID)
+ {
+ p_CcParams->getCcParams.hardwarePortId = (uint8_t)p_FmPort->hardwarePortId;
+ p_CcParams->getCcParams.type &= ~HW_PORT_ID;
+ }
+ if((p_CcParams->getCcParams.type & OFFSET_OF_DATA) && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
+ {
+ p_CcParams->getCcParams.dataOffset = (uint16_t)p_FmPort->bufferOffsets.dataOffset;
+ p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
+ }
+ if(p_CcParams->getCcParams.type & NUM_OF_TASKS)
+ {
+ p_CcParams->getCcParams.numOfTasks = p_FmPort->numOfTasks;
+ p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
+ }
+ if(p_CcParams->getCcParams.type & BUFFER_POOL_ID_FOR_MANIP)
+ {
+ if(p_CcParams->getCcParams.poolIndex < p_FmPort->extBufPools.numOfPoolsUsed)
+ {
+ p_CcParams->getCcParams.poolIdForManip = p_FmPort->extBufPools.extBufPool[p_CcParams->getCcParams.poolIndex].id;
+ p_CcParams->getCcParams.type &= ~BUFFER_POOL_ID_FOR_MANIP;
+ }
+ }
+
+ if((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
+ {
+ p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
+ }
+
+ if((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
+ {
+ p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
+ p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
+ }
+ else if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
+ {
+ if(p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("pnen was defined previously different"));
+ }
+
+ if((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
+ {
+ p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
+ p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
+ }
+ else if(p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
+ {
+ if(p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("pndn was defined previously different"));
+ }
+
+
+ if((p_CcParams->setCcParams.type & UPDATE_PSO) && !(p_FmPort->requiredAction & UPDATE_PSO))
+ {
+ /* get PCD registers pointers */
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+ /* set start parsing offset */
+ tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)+ p_CcParams->setCcParams.psoSize;
+ if(tmpInt>0)
+ WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
+
+ p_FmPort->requiredAction |= UPDATE_PSO;
+ p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
+
+ }
+ else if (p_CcParams->setCcParams.type & UPDATE_PSO)
+ {
+ if(p_FmPort->savedPrsStartOffset != p_CcParams->setCcParams.psoSize)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("parser start offset was defoned previousley different"));
+ }
+ return E_OK;
+}
+/********************************** End of inter-module routines ********************************/
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
+{
+ t_FmPort *p_FmPort;
+ uintptr_t baseAddr = p_FmPortParams->baseAddr;
+
+ /* Allocate FM structure */
+ p_FmPort = (t_FmPort *) XX_Malloc(sizeof(t_FmPort));
+ if (!p_FmPort)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
+ return NULL;
+ }
+ memset(p_FmPort, 0, sizeof(t_FmPort));
+
+ /* Allocate the FM driver's parameters structure */
+ p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(sizeof(t_FmPortDriverParam));
+ if (!p_FmPort->p_FmPortDriverParam)
+ {
+ XX_Free(p_FmPort);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
+ return NULL;
+ }
+ memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
+
+ /* Initialize FM port parameters which will be kept by the driver */
+ p_FmPort->portType = p_FmPortParams->portType;
+ p_FmPort->portId = p_FmPortParams->portId;
+ p_FmPort->pcdEngines = FM_PCD_NONE;
+ p_FmPort->f_Exception = p_FmPortParams->f_Exception;
+ p_FmPort->h_App = p_FmPortParams->h_App;
+ p_FmPort->h_Fm = p_FmPortParams->h_Fm;
+
+ /* calculate global portId number */
+ SW_PORT_ID_TO_HW_PORT_ID(p_FmPort->hardwarePortId, p_FmPort->portType, p_FmPortParams->portId);
+
+ /* Initialize FM port parameters for initialization phase only */
+ p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize = DEFAULT_PORT_bufferPrefixContent_privDataSize;
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult= DEFAULT_PORT_bufferPrefixContent_passPrsResult;
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp= DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo
+ = DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
+#ifdef DEBUG
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passDebugInfo= DEFAULT_PORT_bufferPrefixContent_debugInfo;
+#endif /* DEBUG */
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = DEFAULT_PORT_bufferPrefixContent_dataAlign;
+ p_FmPort->p_FmPortDriverParam->dmaSwapData = DEFAULT_PORT_dmaSwapData;
+ p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = DEFAULT_PORT_dmaIntContextCacheAttr;
+ p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = DEFAULT_PORT_dmaHeaderCacheAttr;
+ p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = DEFAULT_PORT_dmaScatterGatherCacheAttr;
+ p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
+ p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
+
+ /* resource distribution. */
+ p_FmPort->fifoBufs.num = DEFAULT_PORT_sizeOfFifo(p_FmPort->portType);
+ p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraSizeOfFifo(p_FmPort->portType);
+ p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
+ p_FmPort->openDmas.extra = DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
+ p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
+ p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
+ p_FmPort->numOfTasks = (uint8_t)p_FmPort->tasks.num;
+#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ p_FmPort->fifoBufs.extra = 0;
+ p_FmPort->openDmas.extra = 0;
+ p_FmPort->tasks.extra = 0;
+ }
+ }
+#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */
+
+ p_FmPort->p_FmPortDriverParam->color = DEFAULT_PORT_color;
+#ifdef FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) &&
+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
+ p_FmPort->p_FmPortDriverParam->color = e_FM_PORT_COLOR_OVERRIDE;
+ }
+#endif /* FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 */
+
+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReqForHc;
+ else
+ p_FmPort->p_FmPortDriverParam->syncReq = DEFAULT_PORT_syncReq;
+
+#ifdef FM_PORT_SYNC_ERRATA_FMAN6
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
+ p_FmPort->p_FmPortDriverParam->syncReq = FALSE;
+ }
+#endif /* FM_PORT_SYNC_ERRATA_FMAN6 */
+
+ /* Port type specific initialization: */
+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
+ p_FmPort->p_FmPortDriverParam->frmDiscardOverride = DEFAULT_PORT_frmDiscardOverride;
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX):
+ case(e_FM_PORT_TYPE_RX_10G):
+ /* Initialize FM port parameters for initialization phase only */
+ p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = DEFAULT_PORT_cutBytesFromEnd;
+ p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
+ p_FmPort->p_FmPortDriverParam->frmDiscardOverride = DEFAULT_PORT_frmDiscardOverride;
+ p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = DEFAULT_PORT_rxFifoPriElevationLevel;
+ p_FmPort->p_FmPortDriverParam->rxFifoThreshold = DEFAULT_PORT_rxFifoThreshold;
+ p_FmPort->p_FmPortDriverParam->bufMargins.endMargins = DEFAULT_PORT_BufMargins_endMargins;
+ p_FmPort->p_FmPortDriverParam->errorsToDiscard = DEFAULT_PORT_errorsToDiscard;
+ p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_PORT_cheksumLastBytesIgnore;
+ p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = DEFAULT_PORT_forwardIntContextReuse;
+ break;
+
+ case(e_FM_PORT_TYPE_TX):
+ p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_1G;
+ p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
+ case(e_FM_PORT_TYPE_TX_10G):
+ if(p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
+ p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_10G;
+ p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_PORT_cheksumLastBytesIgnore;
+ p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = DEFAULT_PORT_txFifoMinFillLevel;
+ p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = DEFAULT_PORT_txFifoLowComfLevel;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ p_FmPort->p_FmPortDriverParam->deqHighPriority = DEFAULT_PORT_deqHighPriority;
+ p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ p_FmPort->p_FmPortDriverParam->deqPrefetchOption = DEFAULT_PORT_deqPrefetchOption;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+ p_FmPort->p_FmPortDriverParam->deqByteCnt = DEFAULT_PORT_deqByteCnt;
+
+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ p_FmPort->p_FmPortDriverParam->errorsToDiscard = DEFAULT_PORT_errorsToDiscard;
+ break;
+
+ default:
+ XX_Free(p_FmPort->p_FmPortDriverParam);
+ XX_Free(p_FmPort);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ return NULL;
+ }
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ p_FmPort->p_FmPortDriverParam->deqPrefetchOption = DEFAULT_PORT_deqPrefetchOption_HC;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
+ p_FmPort->txFifoDeqPipelineDepth = OH_PIPELINE_DEPTH;
+
+ p_FmPort->imEn = p_FmPortParams->independentModeEnable;
+
+ if (p_FmPort->imEn)
+ {
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
+ p_FmPort->txFifoDeqPipelineDepth = DEFAULT_PORT_txFifoDeqPipelineDepth_IM;
+ FmPortConfigIM(p_FmPort, p_FmPortParams);
+ }
+ else
+ {
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX):
+ case(e_FM_PORT_TYPE_RX_10G):
+ /* Initialize FM port parameters for initialization phase only */
+ memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
+ &p_FmPortParams->specificParams.rxParams.extBufPools,
+ sizeof(t_FmPortExtPools));
+ p_FmPort->p_FmPortDriverParam->errFqid = p_FmPortParams->specificParams.rxParams.errFqid;
+ p_FmPort->p_FmPortDriverParam->dfltFqid = p_FmPortParams->specificParams.rxParams.dfltFqid;
+ p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.rxParams.liodnOffset;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+#ifdef FM_OP_PARTITION_ERRATA_FMANx8
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.nonRxParams.opLiodnOffset;
+ }
+#endif /* FM_OP_PARTITION_ERRATA_FMANx8 */
+ case(e_FM_PORT_TYPE_TX):
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ p_FmPort->p_FmPortDriverParam->errFqid = p_FmPortParams->specificParams.nonRxParams.errFqid;
+ p_FmPort->p_FmPortDriverParam->deqSubPortal =
+ (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel & QMI_DEQ_CFG_SUBPORTAL_MASK);
+ p_FmPort->p_FmPortDriverParam->dfltFqid = p_FmPortParams->specificParams.nonRxParams.dfltFqid;
+ break;
+ default:
+ XX_Free(p_FmPort->p_FmPortDriverParam);
+ XX_Free(p_FmPort);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ return NULL;
+ }
+ }
+
+ memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
+ if(Sprint (p_FmPort->name, "FM-%d-port-%s-%d",
+ FmGetId(p_FmPort->h_Fm),
+ ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ?
+ "OH" : (p_FmPort->portType == e_FM_PORT_TYPE_RX ?
+ "1g-RX" : (p_FmPort->portType == e_FM_PORT_TYPE_TX ?
+ "1g-TX" : (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G ?
+ "10g-RX" : "10g-TX")))),
+ p_FmPort->portId) == 0)
+ {
+ XX_Free(p_FmPort->p_FmPortDriverParam);
+ XX_Free(p_FmPort);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ return NULL;
+ }
+
+ p_FmPort->h_Spinlock = XX_InitSpinlock();
+ if (!p_FmPort->h_Spinlock)
+ {
+ XX_Free(p_FmPort->p_FmPortDriverParam);
+ XX_Free(p_FmPort);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ return NULL;
+ }
+
+ return p_FmPort;
+}
+
+/**************************************************************************//**
+ @Function FM_PORT_Init
+
+ @Description Initializes the FM module
+
+ @Param[in] h_FmPort - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PORT_Init(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_FmPortDriverParam *p_Params;
+ t_Error err = E_OK;
+ t_FmInterModulePortInitParams fmParams;
+ uint32_t minFifoSizeRequired = 0;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if ((err = BuildBufferStructure(p_FmPort)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
+
+ p_Params = p_FmPort->p_FmPortDriverParam;
+
+ /* set memory map pointers */
+ p_FmPort->p_FmPortQmiRegs = (t_FmPortQmiRegs *)UINT_TO_PTR(p_Params->baseAddr + QMI_PORT_REGS_OFFSET);
+ p_FmPort->p_FmPortBmiRegs = (u_FmPortBmiRegs *)UINT_TO_PTR(p_Params->baseAddr + BMI_PORT_REGS_OFFSET);
+ p_FmPort->p_FmPortPrsRegs = (t_FmPortPrsRegs *)UINT_TO_PTR(p_Params->baseAddr + PRS_PORT_REGS_OFFSET);
+
+ /* For O/H ports, check fifo size and update if necessary */
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
+ {
+ minFifoSizeRequired = (uint32_t)((p_FmPort->txFifoDeqPipelineDepth+4)*BMI_FIFO_UNITS);
+ if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
+ {
+ p_FmPort->fifoBufs.num = minFifoSizeRequired;
+ DBG(WARNING, ("FIFO size enlarged to %d due to txFifoDeqPipelineDepth size", minFifoSizeRequired));
+ }
+ }
+
+ /* For Rx Ports, call the external Buffer routine which also checks fifo
+ size and updates it if necessary */
+ if(((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ && !p_FmPort->imEn)
+ {
+ /* define external buffer pools and pool depletion*/
+ err = SetExtBufferPools(p_FmPort);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ /************************************************************/
+ /* Call FM module routine for communicating parameters */
+ /************************************************************/
+ memset(&fmParams, 0, sizeof(fmParams));
+ fmParams.hardwarePortId = p_FmPort->hardwarePortId;
+ fmParams.portType = (e_FmPortType)p_FmPort->portType;
+ fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
+ fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
+ fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
+ fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
+ fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
+ fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
+ fmParams.independentMode = p_FmPort->imEn;
+ fmParams.liodnOffset = p_Params->liodnOffset;
+ fmParams.liodnBase = p_Params->liodnBase;
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ fmParams.deqPipelineDepth = p_FmPort->txFifoDeqPipelineDepth;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ }
+
+ err = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ p_FmPort->tasks.num = fmParams.numOfTasks;
+ p_FmPort->tasks.extra = fmParams.numOfExtraTasks;
+ p_FmPort->openDmas.num = fmParams.numOfOpenDmas;
+ p_FmPort->openDmas.extra = fmParams.numOfExtraOpenDmas;
+ p_FmPort->fifoBufs.num = fmParams.sizeOfFifo;
+ p_FmPort->fifoBufs.extra = fmParams.extraSizeOfFifo;
+
+ /* get params for use in init */
+ p_Params->fmMuramPhysBaseAddr =
+ (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low) |
+ ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
+
+ /**********************/
+ /* Init BMI Registers */
+ /**********************/
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ err = BmiRxPortInit(p_FmPort);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ err = BmiTxPortInit(p_FmPort);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ err = BmiOhPortInit(p_FmPort);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ }
+
+ /**********************/
+ /* Init QMI Registers */
+ /**********************/
+ if (!p_FmPort->imEn && ((err = QmiInit(p_FmPort)) != E_OK))
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ FmPortDriverParamFree(p_FmPort);
+
+ return E_OK;
+}
+
+/**************************************************************************//**
+ @Function FM_PORT_Free
+
+ @Description Frees all resources that were assigned to FM module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmPort - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PORT_Free(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_FmInterModulePortFreeParams fmParams;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+
+ if(p_FmPort->pcdEngines)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
+
+ if (p_FmPort->enabled)
+ {
+ if (FM_PORT_Disable(p_FmPort) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
+ }
+
+ FmPortDriverParamFree(p_FmPort);
+
+ if (p_FmPort->imEn)
+ FmPortImFree(p_FmPort);
+
+ fmParams.hardwarePortId = p_FmPort->hardwarePortId;
+ fmParams.portType = (e_FmPortType)p_FmPort->portType;
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ fmParams.deqPipelineDepth = p_FmPort->txFifoDeqPipelineDepth;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+ FmFreePortParams(p_FmPort->h_Fm, &fmParams);
+
+ if (p_FmPort->h_Spinlock)
+ XX_FreeSpinlock(p_FmPort->h_Spinlock);
+
+ XX_Free(p_FmPort);
+
+ return E_OK;
+}
+
+
+/*************************************************/
+/* API Advanced Init unit functions */
+/*************************************************/
+
+t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
+
+ p_FmPort->p_FmPortDriverParam->deqHighPriority = highPri;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports"));
+
+ p_FmPort->p_FmPortDriverParam->deqType = deqType;
+
+ return E_OK;
+}
+
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports"));
+ p_FmPort->p_FmPortDriverParam->deqPrefetchOption = deqPrefetchOption;
+ return E_OK;
+}
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmPortBackupBmPools *p_BackupBmPools)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+#ifdef FM_NO_BACKUP_POOLS
+ t_FmRevisionInfo revInfo;
+#endif /* FM_NO_BACKUP_POOLS */
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+#ifdef FM_NO_BACKUP_POOLS
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigBackupPools"));
+#endif /* FM_NO_BACKUP_POOLS */
+
+ p_FmPort->p_FmPortDriverParam->p_BackupBmPools = (t_FmPortBackupBmPools *)XX_Malloc(sizeof(t_FmPortBackupBmPools));
+ if(!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
+ memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmPortBackupBmPools));
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Rx ports"));
+
+ p_FmPort->p_FmPortDriverParam->deqByteCnt = deqByteCnt;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort, t_FmPortBufferPrefixContent *p_FmPortBufferPrefixContent)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent, p_FmPortBufferPrefixContent, sizeof(t_FmPortBufferPrefixContent));
+ /* if dataAlign was not initialized by user, we return to driver's deafult */
+ if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = DEFAULT_PORT_bufferPrefixContent_dataAlign;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx & Tx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = cheksumLastBytesIgnore;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = cutBytesFromEnd;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmPortBufPoolDepletion *p_BufPoolDepletion)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
+ memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmPortBufPoolDepletion));
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort, t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for OP ports only"));
+
+ p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
+ memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, &p_FmPortObservedBufPoolDepletion->poolDepletionParams, sizeof(t_FmPortBufPoolDepletion));
+ memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, &p_FmPortObservedBufPoolDepletion->poolsParams, sizeof(t_FmPortExtPools));
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmPortExtPools *p_FmPortExtPools)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for OP ports only"));
+
+ memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmPortExtPools, sizeof(t_FmPortExtPools));
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->rxFifoThreshold = fifoThreshold;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = priElevationLevel;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = minFillLevel;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigTxFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_TX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only"));
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for IM ports!"));
+
+ p_FmPort->txFifoDeqPipelineDepth = deqPipelineDepth;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = fifoLowComfLevel;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+#ifdef FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigDfltColor!"));
+ }
+#endif /* FM_OP_PORT_QMAN_REJECT_ERRATA_FMAN21 */
+ p_FmPort->p_FmPortDriverParam->color = color;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+#ifdef FM_PORT_SYNC_ERRATA_FMAN6
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("port-sync!"));
+ }
+#endif /* FM_PORT_SYNC_ERRATA_FMAN6 */
+
+ p_FmPort->p_FmPortDriverParam->syncReq = syncReq;
+
+ return E_OK;
+}
+
+
+t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) && (p_FmPort->portType == e_FM_PORT_TYPE_TX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("not available for Tx ports"));
+
+ p_FmPort->p_FmPortDriverParam->frmDiscardOverride = override;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+ if((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))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+
+ p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmPortDmaSwap swapData)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->p_FmPortDriverParam->dmaSwapData = swapData;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmPortDmaCache intContextCacheAttr)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = intContextCacheAttr;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmPortDmaCache headerCacheAttr)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = headerCacheAttr;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmPortDmaCache scatterGatherCacheAttr)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Not available for Tx ports"));
+
+ p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = optimize;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool forwardReuse)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+ p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
+
+ return E_OK;
+}
+
+
+/****************************************************/
+/* PCD Advaced config API */
+/****************************************************/
+
+/****************************************************/
+/* API Run-time Control unit functions */
+/****************************************************/
+
+t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) &&
+ (p_NumOfOpenDmas->extra))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources"));
+ }
+#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */
+
+ if((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
+ if(p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
+ err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId, (uint8_t)p_NumOfOpenDmas->num, (uint8_t)p_NumOfOpenDmas->extra, FALSE);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
+
+ return E_OK;
+}
+
+t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for host command port where number is always 1"));
+
+#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) &&
+ (p_NumOfTasks->extra))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources"));
+ }
+#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */
+
+ if((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
+ if(p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
+
+ err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId, (uint8_t)p_NumOfTasks->num, (uint8_t)p_NumOfTasks->extra, FALSE);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ /* update driver's struct */
+ memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
+ return E_OK;
+}
+
+t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err;
+ t_FmInterModulePortRxPoolsParams rxPoolsParams;
+ uint32_t minFifoSizeRequired;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+#ifdef FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0) &&
+ (p_SizeOfFifo->extra))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("excessive resources"));
+ }
+#endif /* FM_PORT_EXCESSIVE_BUDGET_ERRATA_FMANx16 */
+ if(!p_SizeOfFifo->num || (p_SizeOfFifo->num > BMI_MAX_FIFO_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-num has to be in the range of 256 - %d", BMI_MAX_FIFO_SIZE));
+ if(p_SizeOfFifo->num % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ /* extra FIFO size (allowed only to Rx ports) */
+ if(p_SizeOfFifo->extra % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
+ }
+ else
+ if(p_SizeOfFifo->extra)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" No SizeOfFifo-extra for non Rx ports"));
+
+ /* For O/H ports, check fifo size and update if necessary */
+ if((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
+ {
+ minFifoSizeRequired = (uint32_t)((p_FmPort->txFifoDeqPipelineDepth+4)*BMI_FIFO_UNITS);
+ if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
+ {
+ p_FmPort->fifoBufs.num = minFifoSizeRequired;
+ DBG(INFO, ("FIFO size enlarged to %d", minFifoSizeRequired));
+ }
+ }
+ memcpy(&rxPoolsParams, &p_FmPort->rxPoolsParams, sizeof(rxPoolsParams));
+ err = FmSetSizeOfFifo(p_FmPort->h_Fm,
+ p_FmPort->hardwarePortId,
+ p_FmPort->portType,
+ p_FmPort->imEn,
+ &p_SizeOfFifo->num,
+ p_SizeOfFifo->extra,
+ p_FmPort->txFifoDeqPipelineDepth,
+ &rxPoolsParams,
+ FALSE);
+ if(err)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ /* update driver's structure AFTER the FM routine, as it may change by the FM. */
+ memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
+
+ return E_OK;
+}
+
+uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0);
+
+ return p_FmPort->bufferOffsets.dataOffset;
+}
+
+uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0);
+
+ if(p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
+ return NULL;
+
+ return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
+}
+
+#ifdef DEBUG
+uint8_t * FM_PORT_GetBufferDebugInfo(t_Handle h_FmPort, char *p_Data)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0);
+
+ if(p_FmPort->bufferOffsets.debugOffset == ILLEGAL_BASE)
+ return NULL;
+
+ return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.debugOffset);
+}
+#endif /* DEBUG */
+
+t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, NULL);
+
+ if(p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
+ return NULL;
+
+ return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
+}
+
+uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, NULL);
+
+ if(p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
+ return NULL;
+
+ return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
+}
+
+uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, 0);
+
+ if(p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
+ return NULL;
+
+ return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
+}
+
+t_Error FM_PORT_Disable(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiCfgReg = NULL;
+ volatile uint32_t *p_BmiStatusReg = NULL;
+ bool rxPort = FALSE;
+ int tries;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg;
+ p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rst;
+ rxPort = TRUE;
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg;
+ p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tst;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg;
+ p_BmiStatusReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ost;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+ /* check if port is already disabled */
+ if(!(GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN))
+ {
+ if (!rxPort && !p_FmPort->imEn)
+ {
+ if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN))
+ /* port is disabled */
+ return E_OK;
+ else
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Inconsistency: Port's QMI is enabled but BMI disabled"));
+ }
+ /* port is disabled */
+ return E_OK;
+ }
+
+ /* Disable QMI */
+ if (!rxPort && !p_FmPort->imEn)
+ {
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc,
+ GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & ~QMI_PORT_CFG_EN);
+ /* wait for QMI to finish Handling dequeue tnums */
+ tries=1000;
+ while ((GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pns) & QMI_PORT_STATUS_DEQ_FD_BSY) &&
+ --tries)
+ XX_UDelay(1);
+ if (!tries)
+ RETURN_ERROR(MINOR, E_BUSY, ("%s: can't disable!", p_FmPort->name));
+ }
+
+ /* Disable BMI */
+ WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) & ~BMI_PORT_CFG_EN);
+
+ if (p_FmPort->imEn)
+ FmPortImDisable(p_FmPort);
+
+ tries=5000;
+ while ((GET_UINT32(*p_BmiStatusReg) & BMI_PORT_STATUS_BSY) &&
+ --tries)
+ XX_UDelay(1);
+
+ if (!tries)
+ RETURN_ERROR(MINOR, E_BUSY, ("%s: can't disable!", p_FmPort->name));
+
+ p_FmPort->enabled = 0;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_Enable(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiCfgReg = NULL;
+ bool rxPort = FALSE;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg;
+ rxPort = TRUE;
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ p_BmiCfgReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocfg;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ /* check if port is already enabled */
+ if(GET_UINT32(*p_BmiCfgReg) & BMI_PORT_CFG_EN)
+ {
+ if (!rxPort && !p_FmPort->imEn)
+ {
+ if(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc)& QMI_PORT_CFG_EN)
+ /* port is enabled */
+ return E_OK;
+ else
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Inconsistency: Port's BMI is enabled but QMI disabled"));
+ }
+ /* port is enabled */
+ return E_OK;
+ }
+
+ if (p_FmPort->imEn)
+ FmPortImEnable(p_FmPort);
+
+ /* Enable QMI */
+ if (!rxPort && !p_FmPort->imEn)
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc,
+ GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) | QMI_PORT_CFG_EN);
+
+ /* Enable BMI */
+ WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | BMI_PORT_CFG_EN);
+
+ p_FmPort->enabled = 1;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t tmpRateLimit, tmpRateLimitScale;
+ volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg;
+ uint8_t factor, countUnitBit;
+ uint16_t baseGran;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if((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_HOST_COMMAND))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx and Offline parsing ports only"));
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt;
+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts;
+ baseGran = 16000;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt;
+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts;
+ baseGran = 10000;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
+ /* normally, we use 1 usec as the reference count */
+ factor = 1;
+ /* if ratelimit is too small for a 1usec factor, multiply the factor */
+ while (p_RateLimit->rateLimit < baseGran/factor)
+ {
+ if (countUnitBit==31)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
+
+ countUnitBit++;
+ factor <<= 1;
+ }
+ /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
+ if (p_RateLimit->rateLimit > ((uint32_t)baseGran * (1<<10) * (uint32_t)factor))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
+
+ tmpRateLimit = (uint32_t)(p_RateLimit->rateLimit*factor/baseGran - 1);
+
+ if(!p_RateLimit->maxBurstSize || (p_RateLimit->maxBurstSize > MAX_BURST_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxBurstSize must be between 1K and %dk", MAX_BURST_SIZE));
+
+ tmpRateLimitScale = ((31 - (uint32_t)countUnitBit) << BMI_COUNT_RATE_UNIT_SHIFT) | BMI_RATE_LIMIT_EN;
+
+ if(p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
+ tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT;
+ else
+ {
+#ifndef FM_NO_ADVANCED_RATE_LIMITER
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if (revInfo.majorRev == 4)
+ {
+ switch(p_RateLimit->rateLimitDivider)
+ {
+ case(e_FM_PORT_DUAL_RATE_LIMITER_NONE):
+ break;
+ case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2):
+ tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_2;
+ break;
+ case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4):
+ tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_4;
+ break;
+ case(e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8):
+ tmpRateLimitScale |= BMI_RATE_LIMIT_SCALE_BY_8;
+ break;
+ default:
+ break;
+ }
+ tmpRateLimit |= BMI_RATE_LIMIT_BURST_SIZE_GRAN;
+ }
+ else
+#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
+ {
+ if(p_RateLimit->rateLimitDivider != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_PORT_ConfigDualRateLimitScaleDown"));
+
+ if(p_RateLimit->maxBurstSize % 1000)
+ {
+ p_RateLimit->maxBurstSize = (uint16_t)((p_RateLimit->maxBurstSize/1000)+1);
+ DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
+ }
+ else
+ p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize/1000);
+ }
+ tmpRateLimit |= (uint32_t)(p_RateLimit->maxBurstSize - 1) << BMI_MAX_BURST_SHIFT;
+
+ }
+ WRITE_UINT32(*p_RateLimitScaleReg, tmpRateLimitScale);
+ WRITE_UINT32(*p_RateLimitReg, tmpRateLimit);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_RateLimitReg, *p_RateLimitScaleReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if((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_HOST_COMMAND))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Tx and Offline parsing ports only"));
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmt;
+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_trlmts;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_RateLimitReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmt;
+ p_RateLimitScaleReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_orlmts;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ WRITE_UINT32(*p_RateLimitScaleReg, 0);
+ WRITE_UINT32(*p_RateLimitReg, 0);
+
+ return E_OK;
+}
+
+
+t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ tmpReg = GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc);
+ if(enable)
+ tmpReg |= QMI_PORT_CFG_EN_COUNTERS ;
+ else
+ tmpReg &= ~QMI_PORT_CFG_EN_COUNTERS;
+
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc, tmpReg);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiPcReg = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpc;
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpc;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ p_BmiPcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opc;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ if(enable)
+ WRITE_UINT32(*p_BmiPcReg, BMI_COUNTERS_EN);
+ else
+ WRITE_UINT32(*p_BmiPcReg, 0);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t tmpReg;
+ volatile uint32_t *p_BmiPcpReg = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpcp;
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpcp;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ p_BmiPcpReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opcp;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ /* check parameters */
+ if (!p_FmPortPerformanceCnt->taskCompVal ||
+ (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("performanceCnt.taskCompVal has to be in the range of 1 - %d (current value)!",
+ p_FmPort->tasks.num));
+ if (!p_FmPortPerformanceCnt->dmaCompVal ||
+ (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("performanceCnt.dmaCompVal has to be in the range of 1 - %d (current value)!",
+ p_FmPort->openDmas.num));
+ if (!p_FmPortPerformanceCnt->fifoCompVal ||
+ (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("performanceCnt.fifoCompVal has to be in the range of 256 - %d (current value)!",
+ p_FmPort->fifoBufs.num));
+ if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("performanceCnt.fifoCompVal has to be divisible by %d",
+ BMI_FIFO_UNITS));
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ if (!p_FmPortPerformanceCnt->queueCompVal ||
+ (p_FmPortPerformanceCnt->queueCompVal > MAX_PERFORMANCE_RX_QUEUE_COMP))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d",
+ MAX_PERFORMANCE_RX_QUEUE_COMP));
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ if (!p_FmPortPerformanceCnt->queueCompVal ||
+ (p_FmPortPerformanceCnt->queueCompVal > MAX_PERFORMANCE_TX_QUEUE_COMP))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d",
+ MAX_PERFORMANCE_TX_QUEUE_COMP));
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ if (p_FmPortPerformanceCnt->queueCompVal)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("performanceCnt.queueCompVal is not relevant for H/O ports."));
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ tmpReg = 0;
+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->queueCompVal - 1) << BMI_PERFORMANCE_PORT_COMP_SHIFT);
+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->dmaCompVal- 1) << BMI_PERFORMANCE_DMA_COMP_SHIFT);
+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->fifoCompVal/BMI_FIFO_UNITS - 1) << BMI_PERFORMANCE_FIFO_COMP_SHIFT);
+ if ((p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && (p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND))
+ tmpReg |= ((uint32_t)(p_FmPortPerformanceCnt->taskCompVal - 1) << BMI_PERFORMANCE_TASK_COMP_SHIFT);
+
+ WRITE_UINT32(*p_BmiPcpReg, tmpReg);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_FmPortPerformanceCnt currParams, savedParams;
+ t_Error err;
+ bool underTest, failed = FALSE;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+
+ XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
+ p_FmPort->portType, p_FmPort->portId);
+
+ currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
+ currParams.queueCompVal = 0;
+ else
+ currParams.queueCompVal = 1;
+ currParams.dmaCompVal =(uint8_t) p_FmPort->openDmas.num;
+ currParams.fifoCompVal = p_FmPort->fifoBufs.num;
+
+ FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
+ ClearPerfCnts(p_FmPort);
+ if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
+ XX_UDelay(1000000);
+ FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
+ if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
+ {
+ XX_Print ("Max num of defined port tasks (%d) utilized - Please enlarge\n",p_FmPort->tasks.num);
+ failed = TRUE;
+ }
+ if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
+ {
+ XX_Print ("Max num of defined port openDmas (%d) utilized - Please enlarge\n",p_FmPort->openDmas.num);
+ failed = TRUE;
+ }
+ if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
+ {
+ XX_Print ("Max size of defined port fifo (%d) utilized - Please enlarge\n",p_FmPort->fifoBufs.num*BMI_FIFO_UNITS);
+ failed = TRUE;
+ }
+ if (failed)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+
+ memset(&savedParams, 0, sizeof(savedParams));
+ while (TRUE)
+ {
+ underTest = FALSE;
+ if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
+ {
+ currParams.taskCompVal--;
+ underTest = TRUE;
+ }
+ if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
+ {
+ currParams.dmaCompVal--;
+ underTest = TRUE;
+ }
+ if ((currParams.fifoCompVal != BMI_FIFO_UNITS) && !savedParams.fifoCompVal)
+ {
+ currParams.fifoCompVal -= BMI_FIFO_UNITS;
+ underTest = TRUE;
+ }
+ if (!underTest)
+ break;
+
+ ClearPerfCnts(p_FmPort);
+ if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
+ XX_UDelay(1000000);
+ FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
+
+ if (!savedParams.taskCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
+ savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal+2);
+ if (!savedParams.dmaCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
+ savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal+2);
+ if (!savedParams.fifoCompVal && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
+ savedParams.fifoCompVal = currParams.fifoCompVal+2;
+ }
+
+ XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
+ savedParams.taskCompVal, savedParams.dmaCompVal, savedParams.fifoCompVal);
+ return E_OK;
+}
+
+t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t tmpReg;
+ volatile uint32_t *p_BmiStcReg = NULL;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rstc;
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tstc;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ p_BmiStcReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ostc;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ tmpReg = GET_UINT32(*p_BmiStcReg);
+
+ if(enable)
+ tmpReg |= BMI_COUNTERS_EN;
+ else
+ tmpReg &= ~BMI_COUNTERS_EN;
+
+ WRITE_UINT32(*p_BmiStcReg, tmpReg);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_ErrQReg, *p_ErrDiscard;
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem;
+ p_ErrDiscard = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_ErrQReg = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem;
+ p_ErrDiscard = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+ }
+
+ if (GET_UINT32(*p_ErrDiscard) & errs)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Selectd Errors that were configured to cause frame discard."));
+
+ WRITE_UINT32(*p_ErrQReg, errs);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t tmpReg;
+ int i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+ for(i=0 ; i< FM_PORT_MAX_NUM_OF_EXT_POOLS ; i++)
+ {
+ tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]);
+ if ((uint8_t)((tmpReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT) == poolId)
+ {
+ if(enable)
+ tmpReg |= BMI_EXT_BUF_POOL_EN_COUNTER;
+ else
+ tmpReg &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], tmpReg);
+ break;
+ }
+ }
+ if (i == FM_PORT_MAX_NUM_OF_EXT_POOLS)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE,("poolId %d is not included in this ports pools", poolId));
+
+ return E_OK;
+}
+
+uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ bool bmiCounter = FALSE;
+ volatile uint32_t *p_Reg;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_DEQ_TOTAL):
+ case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
+ case(e_FM_PORT_COUNTERS_DEQ_CONFIRM ):
+ /* check that counter is available for the port type */
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports"));
+ return 0;
+ }
+ bmiCounter = FALSE;
+ case(e_FM_PORT_COUNTERS_ENQ_TOTAL):
+ bmiCounter = FALSE;
+ break;
+ default: /* BMI counters (or error - will be checked in BMI routine )*/
+ bmiCounter = TRUE;
+ break;
+ }
+
+ if(bmiCounter)
+ {
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ if(BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+ return 0;
+ }
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ if(BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+ return 0;
+ }
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ if(BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+ return 0;
+ }
+ break;
+ default:
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
+ return 0;
+ }
+ return GET_UINT32(*p_Reg);
+ }
+ else /* QMI counter */
+ {
+
+ /* check that counters are enabled */
+ if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN_COUNTERS))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ return 0;
+ }
+
+ /* Set counter */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_ENQ_TOTAL):
+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc);
+ case(e_FM_PORT_COUNTERS_DEQ_TOTAL):
+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc);
+ case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc);
+ case(e_FM_PORT_COUNTERS_DEQ_CONFIRM):
+ return GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc);
+ default:
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, uint32_t value)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ bool bmiCounter = FALSE;
+ volatile uint32_t *p_Reg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_DEQ_TOTAL):
+ case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
+ case(e_FM_PORT_COUNTERS_DEQ_CONFIRM ):
+ /* check that counter is available for the port type */
+ if((p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for Rx ports"));
+ case(e_FM_PORT_COUNTERS_ENQ_TOTAL):
+ bmiCounter = FALSE;
+ break;
+ default: /* BMI counters (or error - will be checked in BMI routine )*/
+ bmiCounter = TRUE;
+ break;
+ }
+
+ if(bmiCounter)
+ {
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ if(BmiRxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+ break;
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ if(BmiTxPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ if(BmiOhPortCheckAndGetCounterPtr(p_FmPort, counter, &p_Reg))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
+ }
+ WRITE_UINT32(*p_Reg, value);
+ }
+ else /* QMI counter */
+ {
+
+ /* check that counters are enabled */
+ if(!(GET_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnc) & QMI_PORT_CFG_EN_COUNTERS))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+
+ /* Set counter */
+ switch(counter)
+ {
+ case(e_FM_PORT_COUNTERS_ENQ_TOTAL):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnetfc, value);
+ break;
+ case(e_FM_PORT_COUNTERS_DEQ_TOTAL):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndtfc, value);
+ break;
+ case(e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndfdc, value);
+ break;
+ case(e_FM_PORT_COUNTERS_DEQ_CONFIRM):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndcc, value);
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
+ }
+ }
+
+ return E_OK;
+}
+
+uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t extPoolReg;
+ uint8_t tmpPool;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX) && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
+ return 0;
+ }
+
+ for(i=0;i<FM_PORT_MAX_NUM_OF_EXT_POOLS;i++)
+ {
+ extPoolReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]);
+ if (extPoolReg & BMI_EXT_BUF_POOL_VALID)
+ {
+ tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT);
+ if(tmpPool == poolId)
+ {
+ if(extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER)
+ return GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i]);
+ else
+ {
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled"));
+ return 0;
+ }
+ }
+ }
+ }
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId));
+ return 0;
+}
+
+t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value)
+{
+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
+ uint32_t extPoolReg;
+ uint8_t tmpPool;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX) && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
+
+
+ for(i=0;i<FM_PORT_MAX_NUM_OF_EXT_POOLS;i++)
+ {
+ extPoolReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i]);
+ if (extPoolReg & BMI_EXT_BUF_POOL_VALID)
+ {
+ tmpPool = (uint8_t)((extPoolReg & BMI_EXT_BUF_POOL_ID_MASK) >> BMI_EXT_BUF_POOL_ID_SHIFT);
+ if(tmpPool == poolId)
+ {
+ if(extPoolReg & BMI_EXT_BUF_POOL_EN_COUNTER)
+ {
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], value);
+ return E_OK;
+ }
+ else
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not enabled"));
+ }
+ }
+ }
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Pool %d is not used", poolId));
+}
+
+bool FM_PORT_IsStalled(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err;
+ bool isStalled;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, FALSE);
+
+ err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
+ if(err != E_OK)
+ {
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return TRUE;
+ }
+ return isStalled;
+}
+
+t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
+}
+
+t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx ports only"));
+
+ tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
+ if (l4Checksum)
+ tmpReg &= ~BMI_PORT_RFNE_FRWD_DCL4C;
+ else
+ tmpReg |= BMI_PORT_RFNE_FRWD_DCL4C;
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, tmpReg);
+
+ return E_OK;
+}
+
+
+/* API Run-time PCD Control unit functions */
+
+t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err = E_OK;
+
+ p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
+ ASSERT_COND(p_FmPort->h_FmPcd);
+
+ if(numOfProfiles)
+ {
+ err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, numOfProfiles);
+ if(err)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ }
+ FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err = E_OK;
+
+ err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
+ if(err)
+ RETURN_ERROR(MAJOR, err,NO_MSG);
+ return E_OK;
+}
+
+t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiHpnia = NULL;
+ uint32_t tmpReg;
+ uint8_t relativeSchemeId;
+ uint8_t physicalSchemeId;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE);
+
+ tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC)? NIA_KG_CC_EN:0);
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+ }
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ /* if we want to change to direct scheme, we need to check that this scheme is valid */
+ if(p_FmPcdKgScheme->direct)
+ {
+ physicalSchemeId = (uint8_t)(PTR_TO_UINT(p_FmPcdKgScheme->h_DirectScheme)-1);
+ /* check that this scheme is bound to this port */
+ if(!(p_FmPort->schemesPerPortVector & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("called with a scheme that is not bound to this port"));
+ }
+
+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd, physicalSchemeId);
+ if(relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("called with invalid Scheme "));
+ }
+
+ if(!FmPcdKgIsSchemeValidSw(p_FmPort->h_FmPcd, relativeSchemeId))
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("called with uninitialized Scheme "));
+ }
+
+ WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
+ }
+ else /* change to indirect scheme */
+ WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return E_OK;
+}
+
+t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiNia;
+ volatile uint32_t *p_BmiHpnia;
+ uint32_t tmpReg;
+ uint16_t absoluteProfileId = (uint16_t)(PTR_TO_UINT(h_Profile)-1);
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR , E_INVALID_STATE);
+
+ /* check relevancy of this routine - only when policer is used
+ directly after BMI or Parser */
+ if((p_FmPort->pcdEngines & FM_PCD_KG) || (p_FmPort->pcdEngines & FM_PCD_CC))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne;
+ p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne;
+ tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne;
+ p_BmiHpnia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofpne;
+ tmpReg = 0;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+ }
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ if(!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
+ }
+
+ tmpReg = (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
+
+ if(p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
+ {
+ /* update BMI HPNIA */
+ WRITE_UINT32(*p_BmiHpnia, tmpReg);
+ }
+ else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
+ {
+ /* rfne may contain FDCS bits, so first we read them. */
+ tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
+ /* update BMI NIA */
+ WRITE_UINT32(*p_BmiNia, tmpReg);
+ }
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return E_OK;
+}
+
+
+t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err = E_OK;
+ volatile uint32_t *p_BmiCcBase=NULL;
+ volatile uint32_t *p_BmiNia=NULL;
+ uint32_t ccTreePhysOffset;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_VALUE);
+
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only"));
+
+ /* get PCD registers pointers */
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+ }
+
+ /* check that current NIA is BMI to BMI */
+ if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state."));
+
+/*TODO - to take care of changes due to previous tree. Maybe in the previous tree where chnged pndn, pnen ...
+ it has to be returned to the default state - initially*/
+
+ p_FmPort->requiredAction = 0;
+
+ if(p_FmPort->pcdEngines & FM_PCD_CC)
+ {
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rccb;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiCcBase = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_occb;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
+ }
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ err = FmPcdCcBindTree(p_FmPort->h_FmPcd, h_CcTree, &ccTreePhysOffset, h_FmPort);
+ if(err)
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+ WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
+
+ p_FmPort->ccTreeId = h_CcTree;
+ RELEASE_LOCK(p_FmPort->lock);
+ }
+ else
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Coarse CLassification not defined for this port."));
+
+ return E_OK;
+}
+
+t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
+{
+
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only"));
+
+ /* TODO - may add here checks for:
+ SP (or in sw: schemes)
+ CPP (or in sw clsPlan)
+ Parser enabled and configured(?)
+ Tree(?)
+ Profile - only if direct.
+ Scheme - only if direct
+ */
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ err = FmPortAttachPCD(h_FmPort);
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return err;
+}
+
+t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiNia=NULL;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only"));
+
+ /* get PCD registers pointers */
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+ }
+
+ WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
+
+/*TODO - not atomic - it seems that port has to be disabled*/
+ if(p_FmPort->requiredAction & UPDATE_NIA_PNEN)
+ {
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
+ break;
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ case(e_FM_PORT_TYPE_RX):
+ case(e_FM_PORT_TYPE_RX_10G):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage"));
+ }
+ }
+
+ if(p_FmPort->requiredAction & UPDATE_NIA_PNDN)
+ {
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_TX_10G):
+ case(e_FM_PORT_TYPE_TX):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_TX);
+ break;
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, NIA_ENG_BMI | NIA_BMI_AC_FETCH);
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Can not reach this stage"));
+ }
+ }
+
+
+ if(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
+ if(FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2)!= E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ return E_OK;
+}
+
+t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParams)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
+ t_Error err = E_OK;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independent mode ports only"));
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
+ ASSERT_COND(p_FmPort->h_FmPcd);
+
+ err = SetPcd( h_FmPort, p_PcdParams);
+ if(err)
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ if(p_FmPort->pcdEngines & FM_PCD_KG)
+ {
+ schemeBind.netEnvId = p_FmPort->netEnvId;
+ schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
+ schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
+ schemeBind.useClsPlan = p_FmPort->useClsPlan;
+ for(i = 0;i<schemeBind.numOfSchemes;i++)
+ schemeBind.schemesIds[i] = (uint8_t)(PTR_TO_UINT(p_PcdParams->p_KgParams->h_Schemes[i])-1);
+
+ err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
+ if(err)
+ {
+ DeletePcd(p_FmPort);
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+
+ if ((p_FmPort->pcdEngines & FM_PCD_PRS) && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
+ FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, TRUE);
+
+ FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
+
+ err = FmPortAttachPCD(h_FmPort);
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return err;
+}
+
+t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+
+ if (p_FmPort->imEn)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for non-independant mode ports only"));
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+
+ err = FM_PORT_DetachPCD(h_FmPort);
+ if(err)
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
+
+ /* we do it anyway, instead of checking if included */
+ if (FmIsMaster(p_FmPort->h_Fm) &&
+ (p_FmPort->pcdEngines & FM_PCD_PRS))
+ FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId, FALSE);
+
+ if(p_FmPort->pcdEngines & FM_PCD_KG)
+ {
+ /* unbind all schemes */
+ p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort, &schemeBind);
+
+ err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
+ if(err)
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ }
+
+ err = DeletePcd(h_FmPort);
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return err;
+}
+
+t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
+ t_Error err = E_OK;
+ uint32_t tmpScmVec=0;
+ int i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE);
+
+ schemeBind.netEnvId = p_FmPort->netEnvId;
+ schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
+ schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
+ schemeBind.useClsPlan = p_FmPort->useClsPlan;
+ for (i=0; i<schemeBind.numOfSchemes; i++)
+ {
+ schemeBind.schemesIds[i] = (uint8_t)(PTR_TO_UINT(p_PortScheme->h_Schemes[i])-1);
+ /* build vector */
+ tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
+ }
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
+ if (err == E_OK)
+ p_FmPort->schemesPerPortVector |= tmpScmVec;
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return err;
+}
+
+t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
+ t_Error err = E_OK;
+ uint32_t tmpScmVec=0;
+ int i;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG , E_INVALID_STATE);
+
+ schemeBind.netEnvId = p_FmPort->netEnvId;
+ schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
+ schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
+ for (i=0; i<schemeBind.numOfSchemes; i++)
+ {
+ schemeBind.schemesIds[i] = (uint8_t)(PTR_TO_UINT(p_PortScheme->h_Schemes[i])-1);
+ /* build vector */
+ tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
+ }
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
+ if (err == E_OK)
+ p_FmPort->schemesPerPortVector &= ~tmpScmVec;
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return err;
+}
+
+t_Error FM_PORT_PcdPrsModifyStartOffset (t_Handle h_FmPort, t_FmPcdPrsStart *p_FmPcdPrsStart)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ volatile uint32_t *p_BmiPrsStartOffset = NULL;
+ volatile uint32_t *p_BmiNia = NULL;
+ uint32_t tmpReg;
+ uint8_t hdrNum;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PRS , E_INVALID_STATE);
+
+ switch(p_FmPort->portType)
+ {
+ case(e_FM_PORT_TYPE_RX_10G):
+ case(e_FM_PORT_TYPE_RX):
+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpso;
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne;
+ tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
+ break;
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ p_BmiPrsStartOffset = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opso;
+ p_BmiNia = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofne;
+ tmpReg = 0;
+ break;
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("available for Rx and offline parsing ports only"));
+ }
+
+ /* check that current NIA is BMI to BMI */
+ if((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) != (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("may be called only for ports in BMI-to-BMI state."));
+
+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
+ return ERROR_CODE(E_BUSY);
+ /* set the first header */
+ GET_PRS_HDR_NUM(hdrNum, p_FmPcdPrsStart->firstPrsHdr);
+ if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
+ {
+ RELEASE_LOCK(p_FmPort->lock);
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
+ }
+ WRITE_UINT32(*p_BmiNia, (uint32_t)(NIA_ENG_PRS | (uint32_t)hdrNum | tmpReg));
+
+ /* set start parsing offset */
+ WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)(p_FmPcdPrsStart->parsingOffset + p_FmPort->internalBufferOffset));
+ RELEASE_LOCK(p_FmPort->lock);
+
+ return E_OK;
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FM_PORT_DumpRegs(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err = E_OK;
+ char arr[30];
+ uint8_t flag;
+ int i=0;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortQmiRegs, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortBmiRegs, E_INVALID_HANDLE);
+
+ switch (p_FmPort->portType)
+ {
+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
+ strcpy(arr, "PORT_TYPE_OFFLINE_PARSING");
+ flag = 0;
+ break;
+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
+ strcpy(arr, "PORT_TYPE_HOST_COMMAND");
+ flag = 0;
+ break;
+ case (e_FM_PORT_TYPE_RX):
+ strcpy(arr, "PORT_TYPE_RX");
+ flag = 1;
+ break;
+ case (e_FM_PORT_TYPE_RX_10G):
+ strcpy(arr, "PORT_TYPE_RX_10G");
+ flag = 1;
+ break;
+ case (e_FM_PORT_TYPE_TX):
+ strcpy(arr, "PORT_TYPE_TX");
+ flag = 2;
+ break;
+ case (e_FM_PORT_TYPE_TX_10G):
+ strcpy(arr, "PORT_TYPE_TX_10G");
+ flag = 2;
+ break;
+ default:
+ return ERROR_CODE(E_INVALID_VALUE);
+ }
+
+ DUMP_TITLE(UINT_TO_PTR(p_FmPort->hardwarePortId), ("PortId for %s %d", arr, p_FmPort->portId ));
+ DUMP_TITLE(p_FmPort->p_FmPortBmiRegs, ("Bmi Port Regs"));
+
+ err = FmDumpPortRegs(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ switch(flag)
+ {
+ case(0):
+
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocfg);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ost);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oda);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdne);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofne);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofca);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofpne);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opso);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occb);
+
+ DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai), ("fmbm_oprai"));
+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS)
+ {
+ DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oprai[i]), sizeof(uint32_t));
+ }
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofqid );
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oefqid);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsdm );
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofsem );
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofene );
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmts);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_orlmt);
+
+ {
+#ifndef FM_NO_OP_OBSERVED_POOLS
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if (revInfo.majorRev == 4)
+#endif /* !FM_NO_OP_OBSERVED_POOLS */
+ {
+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi, ("fmbm_oebmpi"));
+
+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS)
+ {
+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_oebmpi[i], sizeof(uint32_t));
+ }
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ocgm);
+ }
+ }
+
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ostc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofrc );
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofdc );
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofledc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofufdc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_offc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofwdc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofldec);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_opcp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_occn);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_otuc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_oduc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs,fmbm_ofuc);
+ break;
+ case(1):
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rcfg);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rst);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rda);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_reth);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfed);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_ricp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rebm);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfne);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfca);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfpne);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpso);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpp);
+
+ DUMP_TITLE(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai), ("fmbm_rprai"));
+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_PRS_RESULT_NUM_OF_WORDS)
+ {
+ DUMP_MEMORY(&(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rprai[i]), sizeof(uint32_t));
+ }
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfqid);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_refqid);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsdm);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfsem);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfene);
+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi, ("fmbm_ebmpi"));
+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS)
+ {
+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_ebmpi[i], sizeof(uint32_t));
+ }
+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt, ("fmbm_acnt"));
+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_MAX_NUM_OF_EXT_POOLS)
+ {
+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_acnt[i], sizeof(uint32_t));
+ }
+ DUMP_TITLE(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm, ("fmbm_cgm"));
+ DUMP_SUBSTRUCT_ARRAY(i, FM_PORT_NUM_OF_CONGESTION_GRPS/32)
+ {
+ DUMP_MEMORY(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[i], sizeof(uint32_t));
+ }
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_mpd);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rstc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfrc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfbc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rlfc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rffc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfcd);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfldec);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rodc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpcp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rccn);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rtuc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rrquc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rduc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rfuc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rpac);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs,fmbm_rdbg);
+ break;
+ case(2):
+
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfg);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tst);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tda);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfed);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ticp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfne);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfca);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tcfqid);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfeqid);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfene);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmts);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_trlmt);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tstc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfrc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfdc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfledc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfufdc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tpcp);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tccn);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttuc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_ttcquc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tduc);
+ DUMP_VAR(&p_FmPort->p_FmPortBmiRegs->txPortBmiRegs,fmbm_tfuc);
+ break;
+
+ default:
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid flag"));
+ }
+
+ DUMP_TITLE(p_FmPort->p_FmPortQmiRegs, ("Qmi Port Regs"));
+
+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnc);
+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pns);
+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnts);
+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnen);
+ DUMP_VAR(p_FmPort->p_FmPortQmiRegs,fmqm_pnetfc);
+
+ if(flag !=1)
+ {
+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndn);
+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndc);
+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndtfc);
+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndfdc);
+ DUMP_VAR(&p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs,fmqm_pndcc);
+ }
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort;
+ int i;
+ uint8_t mod;
+ uint32_t tmpReg = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+
+ {
+#ifdef FM_NO_OP_OBSERVED_CGS
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ {
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
+ }
+ else
+#endif /* FM_NO_OP_OBSERVED_CGS */
+ if((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))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx & OP ports only"));
+ }
+
+ opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE);
+
+ /* to minimize memory access (groups may belong to the same regsiter, and may
+ be out of order), we first collect all information into a 256 booleans array,
+ representing each possible group. */
+
+ memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool));
+ for(i=0;i<p_CongestionGrps->numOfCongestionGrpsToConsider;i++)
+ tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE;
+
+ for(i=0;i<FM_PORT_NUM_OF_CONGESTION_GRPS;i++)
+ {
+ mod = (uint8_t)(i%32);
+ /* each 32 congestion groups are represented by a register */
+ if (mod == 0) /* first in a 32 bunch of congestion groups, get the currest register state */
+ tmpReg = opPort ? GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm):
+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32]);
+
+ /* set in the register, the bit representing the relevant congestion group. */
+ if(tmpArray[i])
+ tmpReg |= (0x00000001 << (uint32_t)mod);
+
+ if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */
+ {
+ if(opPort)
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg);
+ else
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32], tmpReg);
+ }
+ }
+
+ return E_OK;
+}
+
+t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ bool tmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS], opPort;
+ int i;
+ uint8_t mod;
+ uint32_t tmpReg = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+
+ {
+#ifdef FM_NO_OP_OBSERVED_CGS
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ {
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
+ }
+ else
+#endif /* FM_NO_OP_OBSERVED_CGS */
+ if((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))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx & OP ports only"));
+ }
+
+ opPort = (bool)((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? TRUE:FALSE);
+
+ /* to minimize memory access (groups may belong to the same regsiter, and may
+ be out of order), we first collect all information into a 256 booleans array,
+ representing each possible group. */
+ memset(&tmpArray, 0, FM_PORT_NUM_OF_CONGESTION_GRPS*sizeof(bool));
+ for(i=0;i<p_CongestionGrps->numOfCongestionGrpsToConsider;i++)
+ tmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] = TRUE;
+
+ for(i=0;i<FM_PORT_NUM_OF_CONGESTION_GRPS;i++)
+ {
+ mod = (uint8_t)(i%32);
+ /* each 32 congestion groups are represented by a register */
+ if (mod == 0) /* first in a 32 bunch of congestion groups, get the currest register state */
+ tmpReg = opPort ? GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm):
+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32]);
+
+ /* set in the register, the bit representing the relevant congestion group. */
+ if(tmpArray[i])
+ tmpReg &= ~(0x00000001 << (uint32_t)mod);
+
+ if (mod == 31) /* last in a 32 bunch of congestion groups - write the corresponding register */
+ {
+ if(opPort)
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ocgm, tmpReg);
+ else
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_cgm[7-i/32], tmpReg);
+ }
+ }
+
+ return E_OK;
+}
+
diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h
new file mode 100644
index 0000000..2e8a997
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port.h
@@ -0,0 +1,894 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_port.h
+
+ @Description FM Port internal structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_PORT_H
+#define __FM_PORT_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "fm_port_ext.h"
+
+#include "fm_common.h"
+
+
+#define __ERR_MODULE__ MODULE_FM_PORT
+
+
+#define MIN_EXT_BUF_SIZE 64
+#define DATA_ALIGNMENT 64
+#define MAX_LIODN_OFFSET 64
+
+/**************************************************************************//**
+ @Description Memory Map defines
+*//***************************************************************************/
+#define BMI_PORT_REGS_OFFSET 0
+#define QMI_PORT_REGS_OFFSET 0x400
+#define PRS_PORT_REGS_OFFSET 0x800
+
+/**************************************************************************//**
+ @Description defaults
+*//***************************************************************************/
+#define DEFAULT_PORT_deqHighPriority TRUE
+#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
+#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+#define DEFAULT_PORT_deqByteCnt 2000
+#define DEFAULT_PORT_bufferPrefixContent_privDataSize 0
+#define DEFAULT_PORT_bufferPrefixContent_passPrsResult FALSE
+#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp FALSE
+#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo FALSE
+#ifdef DEBUG
+#define DEFAULT_PORT_bufferPrefixContent_debugInfo FALSE
+#endif /* DEBUG */
+#define DEFAULT_PORT_bufferPrefixContent_dataAlign DATA_ALIGNMENT
+#define DEFAULT_PORT_cheksumLastBytesIgnore 0
+#define DEFAULT_PORT_cutBytesFromEnd 4
+#define DEFAULT_PORT_txFifoMinFillLevel 0
+#define DEFAULT_PORT_txFifoDeqPipelineDepth_IM 2
+#define DEFAULT_PORT_txFifoDeqPipelineDepth_1G 2
+#define DEFAULT_PORT_txFifoDeqPipelineDepth_10G 8
+#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
+#define DEFAULT_PORT_rxFifoPriElevationLevel BMI_MAX_FIFO_SIZE
+#define DEFAULT_PORT_rxFifoThreshold (BMI_MAX_FIFO_SIZE*3/4)
+#define DEFAULT_PORT_frmDiscardOverride FALSE
+#define DEFAULT_PORT_dmaSwapData e_FM_PORT_DMA_NO_SWP
+#define DEFAULT_PORT_dmaIntContextCacheAttr e_FM_PORT_DMA_NO_STASH
+#define DEFAULT_PORT_dmaHeaderCacheAttr e_FM_PORT_DMA_NO_STASH
+#define DEFAULT_PORT_dmaScatterGatherCacheAttr e_FM_PORT_DMA_NO_STASH
+#define DEFAULT_PORT_dmaWriteOptimize TRUE
+#define DEFAULT_PORT_forwardIntContextReuse FALSE
+#define DEFAULT_PORT_BufMargins_startMargins 32
+#define DEFAULT_PORT_BufMargins_endMargins 0
+#define DEFAULT_PORT_syncReq TRUE
+#define DEFAULT_PORT_syncReqForHc FALSE
+#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
+#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
+#define DEFAULT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE
+#define DEFAULT_rateLimitBurstSizeHighGranularity FALSE
+#define DEFAULT_exception IM_EV_BSY
+
+/* Host command port MUST NOT be changed to more than 1 !!! */
+#define DEFAULT_PORT_numOfTasks(type) \
+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
+ ((((type) == e_FM_PORT_TYPE_RX) || \
+ ((type) == e_FM_PORT_TYPE_TX) || \
+ ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
+
+#define DEFAULT_PORT_extraNumOfTasks(type) \
+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 8 : \
+ ((((type) == e_FM_PORT_TYPE_RX) || \
+ ((type) == e_FM_PORT_TYPE_TX) || \
+ ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 2 : 0))
+
+#define DEFAULT_PORT_numOfOpenDmas(type) \
+ (uint32_t)(((type) == e_FM_PORT_TYPE_TX_10G) ? 8 : \
+ (((type) == e_FM_PORT_TYPE_RX_10G) ? 4 : 1))
+
+#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 8 : \
+ ((((type) == e_FM_PORT_TYPE_RX) || \
+ ((type) == e_FM_PORT_TYPE_TX) || \
+ ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 1 : 0))
+
+#if defined(CONFIG_FMAN_RESOURCE_ALLOCATION_ALGORITHM)
+/* Let LLD to set minimum fifosize, otherwise fifosize settings will not work */
+#define DEFAULT_PORT_sizeOfFifo(type) \
+ (uint32_t)(KILOBYTE)
+#else
+#define DEFAULT_PORT_sizeOfFifo(type) \
+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? (16*KILOBYTE) : \
+ ((((type) == e_FM_PORT_TYPE_RX) || \
+ ((type) == e_FM_PORT_TYPE_TX) || \
+ ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? (4*KILOBYTE) : (1536)))
+#endif
+
+#define DEFAULT_PORT_extraSizeOfFifo(type) \
+ (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? (8*KILOBYTE) : \
+ (((type) == e_FM_PORT_TYPE_RX) ? (4*KILOBYTE) : (0)))
+
+#define DEFAULT_PORT_txBdRingLength 16
+#define DEFAULT_PORT_rxBdRingLength 128
+#define DEFAULT_PORT_ImfwExtStructsMemId 0
+#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
+
+#define OH_PIPELINE_DEPTH 2
+
+/**************************************************************************//**
+ @Description Memory Mapped Registers
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
+#define FM_PORT_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
+
+typedef _Packed struct
+{
+ volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
+ volatile uint32_t fmbm_rst; /**< Rx Status */
+ volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
+ volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
+ volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
+ volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
+ volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
+ volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
+ volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
+ volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
+ volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
+ volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
+ volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
+ volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
+ volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
+ volatile uint32_t reserved1[1]; /**< (0x03C 0x03F) */
+ volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
+ /**< Rx Parse Results Array Initialization*/
+ volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
+ volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
+ volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
+ volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
+ volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
+ volatile uint32_t reserved2[0x23];/**< (0x074 0x0FF) */
+ volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
+ /**< Buffer Manager pool Information-*/
+ volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
+ /**< Allocate Counter-*/
+ volatile uint32_t reserved3[8];
+ /**< 0x130/0x140 - 0x15F reserved -*/
+ volatile uint32_t fmbm_cgm[FM_PORT_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
+ /**< Congestion Group Map*/
+ volatile uint32_t fmbm_mpd; /**< BM Pool Depletion */
+ volatile uint32_t reserved4[0x1F];/**< (0x184 0x1FF) */
+ volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
+ volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
+ volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
+ volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
+ volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
+ volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
+ volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
+ volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
+ volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
+ volatile uint32_t reserved5[0x17];/**< (0x224 0x27F) */
+ volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
+ volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
+ volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
+ volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
+ volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
+ volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
+ volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
+ volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
+ volatile uint32_t reserved6[0x18];/**< (0x2A0 0x2FF) */
+ volatile uint32_t fmbm_rdbg; /**< Rx Debug-*/
+} _PackedType t_FmPortRxBmiRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
+ volatile uint32_t fmbm_tst; /**< Tx Status */
+ volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
+ volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
+ volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
+ volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
+ volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine. */
+ volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
+ volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
+ volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
+ volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
+ volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
+ volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
+ volatile uint32_t reserved0[0x73];/**< (0x038-0x200) */
+ volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
+ volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
+ volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
+ volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
+ volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
+ volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
+ volatile uint32_t reserved1[0x1A];/**< (0x218-0x280) */
+ volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
+ volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
+ volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
+ volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
+ volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
+ volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
+ volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
+} _PackedType t_FmPortTxBmiRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
+ volatile uint32_t fmbm_ost; /**< O/H Status */
+ volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
+ volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
+ volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
+ volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
+ volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
+ volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
+ volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
+ volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
+ volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
+ volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
+ volatile uint32_t reserved0[4]; /**< (0x030 - 0x03F) */
+ volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
+ /**< O/H Parse Results Array Initialization */
+ volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
+ volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
+ volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
+ volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
+ volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
+ volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
+ volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
+ volatile uint32_t reserved0a[0x21];
+ /**< 0x07C - 0x0FF Reserved */
+ union
+ {
+ volatile uint32_t fmbm_oebmpi[FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS];
+ /**< Buffer Manager Observed Pool Information */
+ volatile uint32_t reserved0b[0x18];
+ }; /**< 0x100 - 0x15F Reserved */
+ volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
+ volatile uint32_t reserved0c[0x7];/**< 0x164 - 0x17F Reserved */
+ volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
+ volatile uint32_t reserved0d[0x1F];
+ /**< 0x184 - 0x1FF Reserved */
+ volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
+ volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
+ volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
+ volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
+ volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
+ volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
+ volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
+ volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
+ volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
+ volatile uint32_t reserved2[0x17];/**< (0x218 - 0x27F) */
+ volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
+ volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
+ volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
+ volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
+ volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
+ volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
+} _PackedType t_FmPortOhBmiRegs;
+
+typedef _Packed union
+{
+ t_FmPortRxBmiRegs rxPortBmiRegs;
+ t_FmPortTxBmiRegs txPortBmiRegs;
+ t_FmPortOhBmiRegs ohPortBmiRegs;
+} _PackedType u_FmPortBmiRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
+ volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
+ volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
+ volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
+ volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
+ volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
+} _PackedType t_FmPortNonRxQmiRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
+ volatile uint32_t fmqm_pns; /**< PortID n Status Register */
+ volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
+ volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
+ volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
+ volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
+ t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
+} _PackedType t_FmPortQmiRegs;
+
+typedef _Packed struct
+{
+ _Packed struct
+ {
+ volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
+ volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
+ } _PackedType hdrs[FM_PCD_PRS_NUM_OF_HDRS];
+ volatile uint8_t reserved0[0x378];
+ volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
+ volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
+} _PackedType t_FmPortPrsRegs;
+
+/**************************************************************************//*
+ @Description Basic buffer descriptor (BD) structure
+*//***************************************************************************/
+typedef _Packed struct
+{
+ volatile uint16_t status;
+ volatile uint16_t length;
+ volatile uint8_t reserved0[0x6];
+ volatile uint8_t reserved1[0x1];
+ volatile t_FmPhysAddr buff;
+} _PackedType t_FmImBd;
+
+typedef _Packed struct
+{
+ volatile uint16_t gen; /**< tbd */
+ volatile uint8_t reserved0[0x1];
+ volatile t_FmPhysAddr bdRingBase; /**< tbd */
+ volatile uint16_t bdRingSize; /**< tbd */
+ volatile uint16_t offsetIn; /**< tbd */
+ volatile uint16_t offsetOut; /**< tbd */
+ volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
+} _PackedType t_FmPortImQd;
+
+typedef _Packed struct
+{
+ volatile uint32_t mode; /**< Mode register */
+ volatile uint32_t rxQdPtr; /**< tbd */
+ volatile uint32_t txQdPtr; /**< tbd */
+ volatile uint16_t mrblr; /**< tbd */
+ volatile uint16_t rxQdBsyCnt; /**< tbd */
+ volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
+ t_FmPortImQd rxQd;
+ t_FmPortImQd txQd;
+ volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
+} _PackedType t_FmPortImPram;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/**************************************************************************//**
+ @Description Registers bit fields
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description BMI defines
+*//***************************************************************************/
+#define BMI_PORT_CFG_EN 0x80000000
+#define BMI_PORT_CFG_EN_MACSEC 0x00800000
+#define BMI_PORT_CFG_FDOVR 0x02000000
+#define BMI_PORT_CFG_IM 0x01000000
+#define BMI_PORT_STATUS_BSY 0x80000000
+#define BMI_COUNTERS_EN 0x80000000
+#define BMI_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
+#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
+#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
+#define BMI_RFNE_FDCS_MASK 0xFF000000
+
+#define BMI_CMD_MR_LEAC 0x00200000
+#define BMI_CMD_MR_SLEAC 0x00100000
+#define BMI_CMD_MR_MA 0x00080000
+#define BMI_CMD_MR_DEAS 0x00040000
+#define BMI_CMD_TX_MR_DEF (0)
+#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
+ BMI_CMD_MR_SLEAC | \
+ BMI_CMD_MR_MA | \
+ BMI_CMD_MR_DEAS)
+#define BMI_CMD_ATTR_ORDER 0x80000000
+#define BMI_CMD_ATTR_SYNC 0x02000000
+#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
+#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
+#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
+#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
+
+#define BMI_EXT_BUF_POOL_VALID 0x80000000
+#define BMI_EXT_BUF_POOL_EN_COUNTER 0x40000000
+#define BMI_EXT_BUF_POOL_BACKUP 0x20000000
+#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
+#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
+ FM_PORT_FRM_ERR_PHYSICAL | \
+ FM_PORT_FRM_ERR_SIZE | \
+ FM_PORT_FRM_ERR_CLS_DISCARD | \
+ FM_PORT_FRM_ERR_EXTRACTION | \
+ FM_PORT_FRM_ERR_NO_SCHEME | \
+ FM_PORT_FRM_ERR_COLOR_RED | \
+ FM_PORT_FRM_ERR_COLOR_YELLOW | \
+ FM_PORT_FRM_ERR_ILL_PLCR | \
+ FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
+ FM_PORT_FRM_ERR_PRS_TIMEOUT | \
+ FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
+ FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
+ FM_PORT_FRM_ERR_PRS_HDR_ERR | \
+ FM_PORT_FRM_ERR_PROCESS_TIMEOUT | \
+ FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
+
+#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
+ ~(FM_PORT_FRM_ERR_LENGTH | \
+ FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
+
+#define BMI_RATE_LIMIT_EN 0x80000000
+#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
+#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
+#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
+#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
+
+#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
+
+#define BMI_PRS_RESULT_HIGH 0x00000000
+#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
+
+#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
+ FM_PORT_FRM_ERR_PHYSICAL | \
+ FM_PORT_FRM_ERR_SIZE | \
+ FM_PORT_FRM_ERR_EXTRACTION | \
+ FM_PORT_FRM_ERR_NO_SCHEME | \
+ FM_PORT_FRM_ERR_ILL_PLCR | \
+ FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
+ FM_PORT_FRM_ERR_PRS_TIMEOUT | \
+ FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
+ FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
+ FM_PORT_FRM_ERR_PRS_HDR_ERR | \
+ FM_PORT_FRM_ERR_PROCESS_TIMEOUT | \
+ FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW)
+
+#ifdef FM_CAPWAP_SUPPORT
+#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
+ FM_PORT_FRM_ERR_LENGTH | \
+ FM_PORT_FRM_ERR_NON_FM | \
+ FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
+
+#else
+#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
+ FM_PORT_FRM_ERR_LENGTH | \
+ FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
+#endif /* FM_CAPWAP_SUPPORT */
+
+/* shifts */
+#define BMI_PORT_CFG_MS_SEL_SHIFT 16
+#define BMI_DMA_ATTR_SWP_SHIFT 30
+#define BMI_DMA_ATTR_IC_CACHE_SHIFT 28
+#define BMI_DMA_ATTR_HDR_CACHE_SHIFT 26
+#define BMI_DMA_ATTR_SG_CACHE_SHIFT 24
+
+#define BMI_IM_FOF_SHIFT 28
+#define BMI_PR_PORTID_SHIFT 24
+
+#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
+#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
+
+#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
+#define BMI_RX_FRAME_END_CUT_SHIFT 16
+
+#define BMI_IC_TO_EXT_SHIFT 16
+#define BMI_IC_FROM_INT_SHIFT 8
+#define BMI_IC_SIZE_SHIFT 0
+
+#define BMI_INT_BUF_MARG_SHIFT 28
+
+#define BMI_EXT_BUF_MARG_START_SHIFT 16
+#define BMI_EXT_BUF_MARG_END_SHIFT 0
+
+#define BMI_CMD_ATTR_COLOR_SHIFT 26
+#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
+#define BMI_CMD_ATTR_MACCMD_SHIFT 8
+#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
+#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
+#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
+
+#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
+#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
+
+#define BMI_EXT_BUF_POOL_ID_SHIFT 16
+
+#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
+#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
+#define BMI_TX_LOW_COMF_SHIFT 0
+
+#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
+
+#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
+#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
+#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
+#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
+
+#define BMI_MAX_BURST_SHIFT 16
+#define BMI_COUNT_RATE_UNIT_SHIFT 16
+
+/* sizes */
+#define FRAME_END_DATA_SIZE 16
+#define OFFSET_UNITS 16
+#define FRAME_OFFSET_UNITS 16
+#define MAX_EXT_OFFSET 496
+#define MAX_EXT_BUFFER_OFFSET 511
+#define MAX_INT_OFFSET 240
+#define MIN_TX_INT_OFFSET 16
+#define MAX_IC_SIZE 256
+#define MAX_FRAME_OFFSET 64
+#define MAX_FIFO_PIPELINE_DEPTH 8
+#define MAX_PERFORMANCE_TASK_COMP 64
+#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
+#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
+#define MAX_PERFORMANCE_DMA_COMP 16
+#define MAX_NUM_OF_TASKS 64
+#define MAX_NUM_OF_EXTRA_TASKS 8
+#define MAX_NUM_OF_DMAS 16
+#define MAX_NUM_OF_EXTRA_DMAS 8
+#define MAX_BURST_SIZE 1024
+#define FRAG_EXTRA_SPACE 32
+
+/**************************************************************************//**
+ @Description QMI defines
+*//***************************************************************************/
+/* masks */
+#define QMI_PORT_CFG_EN 0x80000000
+#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
+#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
+#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
+
+#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
+#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
+#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
+#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
+
+#define QMI_DEQ_CFG_PRI 0x80000000
+#define QMI_DEQ_CFG_TYPE1 0x10000000
+#define QMI_DEQ_CFG_TYPE2 0x20000000
+#define QMI_DEQ_CFG_TYPE3 0x30000000
+
+#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
+#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
+
+/**************************************************************************//**
+ @Description PARSER defines
+*//***************************************************************************/
+/* masks */
+#define PRS_HDR_ERROR_DIS 0x00000800
+#define PRS_HDR_SW_PRS_EN 0x00000400
+#define PRS_CP_OFFSET_MASK 0x0000000F
+#define PRS_TPID1_MASK 0xFFFF0000
+#define PRS_TPID2_MASK 0x0000FFFF
+#define PRS_TPID_DFLT 0x91009100
+
+#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
+#define PRS_HDR_IPV6_ROUTE_HDR_DIS 0x00008000
+#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
+#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
+#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
+#define PRS_CAC_STOP 0x00000001
+#define PRS_CAC_ACTIVE 0x00000100
+
+/* shifts */
+#define PRS_PCTPID_SHIFT 16
+#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
+#define PRS_HDR_ETH_BC_SHIFT 28
+#define PRS_HDR_ETH_MC_SHIFT 24
+#define PRS_HDR_VLAN_STACKED_SHIFT 16
+#define PRS_HDR_MPLS_STACKED_SHIFT 16
+#define PRS_HDR_IPV4_1_BC_SHIFT 28
+#define PRS_HDR_IPV4_1_MC_SHIFT 24
+#define PRS_HDR_IPV4_2_UC_SHIFT 20
+#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
+#define PRS_HDR_IPV6_1_MC_SHIFT 24
+#define PRS_HDR_IPV6_2_UC_SHIFT 20
+#define PRS_HDR_IPV6_2_MC_SHIFT 16
+
+#define PRS_HDR_ETH_BC_MASK 0x0fffffff
+#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
+#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
+#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
+#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
+#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
+#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
+#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
+#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
+#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
+#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
+
+/* others */
+#define PRS_HDR_ENTRY_SIZE 8
+#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
+
+#define IPSEC_SW_PATCH_START 0x20
+#define SCTP_SW_PATCH_START 0x4D
+#define DCCP_SW_PATCH_START 0x41
+
+#define IP_FRAG_SW_PATCH_IPv4 0x300
+#define IP_FRAG_SW_PATCH_IPv6_0 0x320
+#define IP_FRAG_SW_PATCH_IPv6_1 0x372
+
+/**************************************************************************//**
+ @Description IM defines
+*//***************************************************************************/
+#define BD_R_E 0x80000000
+#define BD_L 0x08000000
+
+#define BD_RX_CRE 0x00080000
+#define BD_RX_FTL 0x00040000
+#define BD_RX_FTS 0x00020000
+#define BD_RX_OV 0x00010000
+
+#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
+#define BD_ERROR_PASS_FRAME BD_RX_ERRORS
+
+#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
+
+#define BD_STATUS_MASK 0xffff0000
+#define BD_LENGTH_MASK 0x0000ffff
+
+#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
+
+#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
+
+#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
+
+#define IM_ILEGAL_BD_ID 0xffff
+
+/* others */
+#define IM_PRAM_ALIGN 0x100
+
+/* masks */
+#define IM_MODE_GBL 0x20000000
+#define IM_MODE_BO_MASK 0x18000000
+#define IM_MODE_BO_SHIFT 3
+#define IM_MODE_GRC_STP 0x00800000
+
+#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
+
+#define IM_RXQD_BSYINTM 0x0008
+#define IM_RXQD_RXFINTM 0x0010
+#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
+
+#define IM_EV_BSY 0x40000000
+#define IM_EV_RX 0x80000000
+
+typedef struct {
+ t_Handle h_FmMuram;
+ t_FmPortImPram *p_FmPortImPram;
+ uint8_t fwExtStructsMemId;
+ uint32_t fwExtStructsMemAttr;
+ uint16_t bdRingSize;
+ t_FmImBd *p_BdRing;
+ t_Handle *p_BdShadow;
+ uint16_t currBdId;
+ uint16_t firstBdOfFrameId;
+
+ /* Rx port parameters */
+ uint8_t dataMemId; /**< Memory partition ID for data buffers */
+ uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
+ t_BufferPoolInfo rxPool;
+ uint16_t mrblr;
+ uint16_t rxFrameAccumLength;
+ t_FmPortImRxStoreCallback *f_RxStore;
+
+ /* Tx port parameters */
+ uint32_t txFirstBdStatus;
+ t_FmPortImTxConfCallback *f_TxConf;
+} t_FmMacIm;
+
+/**************************************************************************//**
+ @Description structure for defining internal context copying
+*//***************************************************************************/
+typedef struct
+{
+ uint16_t extBufOffset; /**< Offset in External buffer to which internal
+ context is copied to (Rx) or taken from (Tx, Op). */
+ uint8_t intContextOffset; /**< Offset within internal context to copy from
+ (Rx) or to copy to (Tx, Op). */
+ uint16_t size; /**< Internal offset size to be copied */
+} t_FmPortIntContextDataCopy;
+
+/**************************************************************************//**
+ @Description struct for defining external buffer margins
+*//***************************************************************************/
+typedef struct {
+ uint16_t startMargins; /**< Number of bytes to be left at the beginning
+ of the external buffer (must be divisible by 16) */
+ uint16_t endMargins; /**< number of bytes to be left at the end
+ of the external buffer(must be divisible by 16) */
+} t_FmPortBufMargins;
+
+typedef struct {
+ uint32_t dataOffset;
+ uint32_t prsResultOffset;
+ uint32_t timeStampOffset;
+ uint32_t hashResultOffset;
+ uint32_t pcdInfoOffset;
+ uint32_t manipOffset;
+#ifdef DEBUG
+ uint32_t debugOffset;
+#endif /* DEBUG */
+} t_FmPortBufferOffsets;
+
+typedef struct {
+ uint32_t dfltFqid;
+ uint32_t confFqid;
+ uint32_t errFqid;
+ uintptr_t baseAddr;
+ uint8_t deqSubPortal;
+ bool deqHighPriority;
+ e_FmPortDeqType deqType;
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ e_FmPortDeqPrefetchOption deqPrefetchOption;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+ uint16_t deqByteCnt;
+ uint8_t cheksumLastBytesIgnore;
+ uint8_t cutBytesFromEnd;
+ t_FmPortBufPoolDepletion bufPoolDepletion;
+ uint8_t pipelineDepth;
+ uint16_t fifoLowComfLevel;
+ bool frmDiscardOverride;
+ bool enRateLimit;
+ t_FmPortRateLimit rateLimit;
+ e_FmPortDualRateLimiterScaleDown rateLimitDivider;
+ bool enBufPoolDepletion;
+ uint16_t liodnOffset;
+ uint16_t liodnBase;
+ t_FmPortExtPools extBufPools;
+ e_FmPortDmaSwap dmaSwapData;
+ e_FmPortDmaCache dmaIntContextCacheAttr;
+ e_FmPortDmaCache dmaHeaderCacheAttr;
+ e_FmPortDmaCache dmaScatterGatherCacheAttr;
+ bool dmaReadOptimize;
+ bool dmaWriteOptimize;
+ uint32_t txFifoMinFillLevel;
+ uint32_t txFifoLowComfLevel;
+ uint32_t rxFifoPriElevationLevel;
+ uint32_t rxFifoThreshold;
+ t_FmPortBufMargins bufMargins;
+ t_FmPortIntContextDataCopy intContext;
+ bool syncReq;
+ e_FmPortColor color;
+ fmPortFrameErrSelect_t errorsToDiscard;
+ fmPortFrameErrSelect_t errorsToEnq;
+ uint64_t fmMuramPhysBaseAddr;
+ bool forwardReuseIntContext;
+ t_FmPortBufferPrefixContent bufferPrefixContent;
+ uint8_t internalBufferOffset;
+ t_FmPortBackupBmPools *p_BackupBmPools;
+ bool dontReleaseBuf;
+} t_FmPortDriverParam;
+
+typedef struct {
+ t_Handle h_Fm;
+ t_Handle h_FmPcd;
+ uint8_t portId;
+ e_FmPortType portType;
+ int enabled;
+ char name[MODULE_NAME_SIZE];
+ uint8_t hardwarePortId;
+ uint16_t fmClkFreq;
+ t_FmPortQmiRegs *p_FmPortQmiRegs;
+ u_FmPortBmiRegs *p_FmPortBmiRegs;
+ t_FmPortPrsRegs *p_FmPortPrsRegs;
+ fmPcdEngines_t pcdEngines;
+ uint32_t savedBmiNia;
+ uint8_t netEnvId;
+ uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
+ uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
+ uint8_t privateInfo;
+ uint32_t schemesPerPortVector;
+ bool useClsPlan;
+ uint8_t clsPlanGrpId;
+ t_Handle ccTreeId;
+ t_Handle completeArg;
+ void (*f_Complete)(t_Handle arg);
+ t_FmPortBufferOffsets bufferOffsets;
+ /* Independent-Mode parameters support */
+ bool imEn;
+ t_FmMacIm im;
+ uint8_t txFifoDeqPipelineDepth;
+ volatile bool lock;
+ t_Handle h_Spinlock;
+ t_FmPortExceptionCallback *f_Exception;
+ t_Handle h_App;
+ uint8_t internalBufferOffset;
+ uint8_t fmanCtrlEventId;
+ uint32_t exceptions;
+ bool polling;
+ uint8_t numOfTasks;
+ t_FmPortExtPools extBufPools;
+ uint32_t requiredAction;
+ uint32_t savedQmiPnen;
+ uint32_t savedNonRxQmiRegsPndn;
+ int savedPrsStartOffset;
+ t_FmPortRsrc openDmas;
+ t_FmPortRsrc tasks;
+ t_FmPortRsrc fifoBufs;
+ t_FmInterModulePortRxPoolsParams rxPoolsParams;
+ t_FmPortDriverParam *p_FmPortDriverParam;
+} t_FmPort;
+
+#define CHECK_FM_CTL_AC_POST_FETCH_PCD(savedBmiNia) \
+ ((((savedBmiNia) & NIA_ENG_MASK) == NIA_ENG_FM_CTL) && \
+ ((((savedBmiNia) & NIA_FM_CTL_AC_MASK) == NIA_FM_CTL_AC_POST_FETCH_PCD) || \
+ (((savedBmiNia) & NIA_FM_CTL_AC_MASK) == NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN)))
+
+void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
+t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
+
+t_Error FmPortImInit(t_FmPort *p_FmPort);
+void FmPortImFree(t_FmPort *p_FmPort);
+
+t_Error FmPortImEnable (t_FmPort *p_FmPort);
+t_Error FmPortImDisable (t_FmPort *p_FmPort);
+t_Error FmPortImRx (t_FmPort *p_FmPort);
+
+void FmPortSetMacsecLcv(t_Handle h_FmPort);
+void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
+
+
+static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
+{
+ uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
+ physAddr |= GET_UINT32(p_Bd->buff.low);
+
+ return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
+}
+
+static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
+{
+ WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
+ WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
+}
+
+static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
+{
+ uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
+ SET_ADDR(&p_Bd->buff, physAddr);
+}
+
+static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
+{
+ if (id < p_FmPort->im.bdRingSize-1)
+ return (uint16_t)(id+1);
+ else
+ return 0;
+}
+
+
+#endif /* __FM_PORT_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c
new file mode 100644
index 0000000..e79a61b
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Port/fm_port_im.c
@@ -0,0 +1,789 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_port_im.c
+
+ @Description FM Port Independent-Mode ...
+*//***************************************************************************/
+#include "std_ext.h"
+#include "string_ext.h"
+#include "error_ext.h"
+#include "fm_muram_ext.h"
+
+#include "fm_port.h"
+
+
+#define TX_CONF_STATUS_UNSENT 0x1
+
+#ifdef CORE_8BIT_ACCESS_ERRATA
+#undef WRITE_UINT16
+#undef GET_UINT16
+
+#define WRITE_UINT16(addr, val) \
+ do{ \
+ if((int)&(addr) % 4) \
+ WRITE_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L), \
+ ((GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L)) & 0xffff0000) | (uint32_t)val)); \
+ else \
+ WRITE_UINT32(*(uint32_t*)&addr, \
+ ((GET_UINT32(*(uint32_t*)&addr) & 0x0000ffff) | (uint32_t)val<<16)); \
+ }while(0);
+
+#define GET_UINT16(addr) (((uint32_t)&addr%4) ? \
+ ((uint16_t)GET_UINT32(*(uint32_t*)(uint32_t)((uint32_t)&addr & ~0x3L))): \
+ ((uint16_t)(GET_UINT32(*(uint32_t*)(uint32_t)&addr) >> 16)))
+#endif /* CORE_8BIT_ACCESS_ERRATA */
+
+
+typedef enum e_TxConfType
+{
+ e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
+ ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
+ ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
+} e_TxConfType;
+
+
+static void ImException(t_Handle h_FmPort, uint32_t event)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ ASSERT_COND(((event & IM_EV_RX) && FmIsMaster(p_FmPort->h_Fm)) ||
+ !FmIsMaster(p_FmPort->h_Fm));
+
+ if (event & IM_EV_RX)
+ FmPortImRx(p_FmPort);
+ if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
+ p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
+}
+
+
+static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
+{
+ t_Error retVal = E_BUSY;
+ uint32_t bdStatus;
+ uint16_t savedStartBdId, confBdId;
+
+ ASSERT_COND(p_FmPort);
+
+ /*
+ if (confType==e_TX_CONF_TYPE_CHECK)
+ return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
+ */
+
+ confBdId = savedStartBdId = p_FmPort->im.currBdId;
+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
+
+ /* If R bit is set, we don't enter, or we break.
+ we run till we get to R, or complete the loop */
+ while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
+ {
+ if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
+ BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
+
+ /* case 1: R bit is 0 and Length is set -> confirm! */
+ if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
+ {
+ if (p_FmPort->im.f_TxConf)
+ {
+ if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
+ p_FmPort->im.f_TxConf(p_FmPort->h_App,
+ BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
+ TX_CONF_STATUS_UNSENT,
+ p_FmPort->im.p_BdShadow[confBdId]);
+ else
+ p_FmPort->im.f_TxConf(p_FmPort->h_App,
+ BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
+ 0,
+ p_FmPort->im.p_BdShadow[confBdId]);
+ }
+ }
+ /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
+
+ confBdId = GetNextBdId(p_FmPort, confBdId);
+ if (confBdId == savedStartBdId)
+ retVal = E_OK;
+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
+ }
+
+ return retVal;
+}
+
+t_Error FmPortImEnable(t_FmPort *p_FmPort)
+{
+ uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
+ return E_OK;
+}
+
+t_Error FmPortImDisable(t_FmPort *p_FmPort)
+{
+ uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
+ return E_OK;
+}
+
+t_Error FmPortImRx(t_FmPort *p_FmPort)
+{
+ t_Handle h_CurrUserPriv, h_NewUserPriv;
+ uint32_t bdStatus;
+ volatile uint8_t buffPos;
+ uint16_t length;
+ uint16_t errors/*, reportErrors*/;
+ uint8_t *p_CurData, *p_Data;
+ uint32_t flags;
+
+ ASSERT_COND(p_FmPort);
+
+ flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
+ if (p_FmPort->lock)
+ {
+ XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
+ return E_OK;
+ }
+ p_FmPort->lock = TRUE;
+ XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
+
+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
+
+ while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
+ {
+ if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
+ {
+ p_FmPort->lock = FALSE;
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
+ }
+
+ if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
+ p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
+
+ errors = 0;
+ p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
+ h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
+ length = (uint16_t)((bdStatus & BD_L) ?
+ ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
+ (bdStatus & BD_LENGTH_MASK));
+ p_FmPort->im.rxFrameAccumLength += length;
+
+ /* determine whether buffer is first, last, first and last (single */
+ /* buffer frame) or middle (not first and not last) */
+ buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
+ ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
+ ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
+
+ if (bdStatus & BD_L)
+ {
+ p_FmPort->im.rxFrameAccumLength = 0;
+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
+ }
+
+ BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
+
+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
+
+ errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
+
+ p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
+ /* Pass the buffer if one of the conditions is true:
+ - There are no errors
+ - This is a part of a larger frame ( the application has already received some buffers )
+ - There is an error, but it was defined to be passed anyway. */
+ if ((buffPos != SINGLE_BUF) || !errors || (errors & (uint16_t)(BD_ERROR_PASS_FRAME>>16)))
+ {
+ if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
+ p_CurData,
+ length,
+ errors,
+ buffPos,
+ h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
+ break;
+ }
+ else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
+ p_CurData,
+ h_CurrUserPriv))
+ {
+ p_FmPort->lock = FALSE;
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
+ }
+
+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
+ }
+ p_FmPort->lock = FALSE;
+ return E_OK;
+}
+
+void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
+{
+ ASSERT_COND(p_FmPort);
+
+ SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
+ p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
+ p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
+ p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
+
+ p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
+ p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
+
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
+ p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
+ p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
+ p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
+ p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
+ if (!p_FmPort->im.rxPool.f_PhysToVirt)
+ p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
+ p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
+ if (!p_FmPort->im.rxPool.f_VirtToPhys)
+ p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
+ p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
+
+ p_FmPort->im.mrblr = 0x8000;
+ while (p_FmPort->im.mrblr)
+ {
+ if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
+ break;
+ p_FmPort->im.mrblr >>= 1;
+ }
+ if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
+ DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
+ p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
+ p_FmPort->exceptions = DEFAULT_exception;
+ if (FmIsMaster(p_FmPort->h_Fm))
+ p_FmPort->polling = FALSE;
+ else
+ p_FmPort->polling = TRUE;
+ p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
+ }
+ else
+ {
+ p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
+
+ p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
+ }
+}
+
+t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
+{
+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
+ (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
+
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ if (!POWER_OF_2(p_FmPort->im.mrblr))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
+ if (p_FmPort->im.mrblr < 256)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
+ if(p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
+#ifdef FM_PARTITION_ARRAY
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_FmPort->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ if(p_FmPort->p_FmPortDriverParam->liodnOffset >= MAX_LIODN_OFFSET)
+ {
+ p_FmPort->p_FmPortDriverParam->liodnOffset =
+ (uint16_t)(p_FmPort->p_FmPortDriverParam->liodnOffset & (MAX_LIODN_OFFSET-1));
+ DBG(WARNING, ("liodnOffset number is out of rev1 range - MSB bits cleard."));
+ }
+ }
+ }
+#endif /* FM_PARTITION_ARRAY */
+/* TODO - add checks */
+ }
+ else
+ {
+/* TODO - add checks */
+ }
+
+ return E_OK;
+}
+
+t_Error FmPortImInit(t_FmPort *p_FmPort)
+{
+ t_FmImBd *p_Bd=NULL;
+ t_Handle h_BufContext;
+ uint64_t tmpPhysBase;
+ uint16_t log2Num;
+ uint8_t *p_Data/*, *p_Tmp*/;
+ int i;
+ t_Error err;
+ uint16_t tmpReg16;
+ uint32_t tmpReg32;
+
+ ASSERT_COND(p_FmPort);
+
+ p_FmPort->im.p_FmPortImPram =
+ (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
+ if (!p_FmPort->im.p_FmPortImPram)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
+ WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
+
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
+ if (!p_FmPort->im.p_BdRing)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
+ IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
+
+ p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
+ if (!p_FmPort->im.p_BdShadow)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
+ memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
+
+ /* Initialize the Rx-BD ring */
+ for (i=0; i<p_FmPort->im.bdRingSize; i++)
+ {
+ p_Bd = BD_GET(i);
+ BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
+
+ if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
+ BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
+ p_FmPort->im.p_BdShadow[i] = h_BufContext;
+ }
+
+ if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
+ (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
+ else
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
+
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
+ p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr + 0x20));
+
+ LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
+
+ /* Initialize Rx QD */
+ tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
+ SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
+
+ /* Update the IM PRAM address in the BMI */
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
+ p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr));
+ if (!p_FmPort->polling || p_FmPort->exceptions)
+ {
+ /* Allocate, configure and register interrupts */
+ err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
+ tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
+ tmpReg32 = 0;
+
+ if(p_FmPort->exceptions & IM_EV_BSY)
+ {
+ tmpReg16 |= IM_RXQD_BSYINTM;
+ tmpReg32 |= IM_EV_BSY;
+ }
+ if(!p_FmPort->polling)
+ {
+ tmpReg16 |= IM_RXQD_RXFINTM;
+ tmpReg32 |= IM_EV_RX;
+ }
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
+
+ FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
+
+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
+ }
+ else
+ p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
+ }
+ else
+ {
+ p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
+ if (!p_FmPort->im.p_BdRing)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
+ IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
+
+ p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
+ if (!p_FmPort->im.p_BdShadow)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
+ memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
+
+ if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
+ (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
+ else
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
+
+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
+ p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr + 0x40));
+
+ /* Initialize Tx QD */
+ tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
+ SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
+
+ /* Update the IM PRAM address in the BMI */
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
+ p_FmPort->p_FmPortDriverParam->fmMuramPhysBaseAddr));
+ }
+
+
+ return E_OK;
+}
+
+void FmPortImFree(t_FmPort *p_FmPort)
+{
+ uint32_t bdStatus;
+ uint8_t *p_CurData;
+
+ ASSERT_COND(p_FmPort);
+ ASSERT_COND(p_FmPort->im.p_FmPortImPram);
+
+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ if (!p_FmPort->polling || p_FmPort->exceptions)
+ {
+ /* Deallocate and unregister interrupts */
+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
+
+ FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
+
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
+
+ FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
+ }
+ /* Try first clean what has received */
+ FmPortImRx(p_FmPort);
+
+ /* Now, get rid of the the empty buffer! */
+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
+
+ while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
+ {
+ p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
+
+ BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
+
+ p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
+ p_CurData,
+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
+
+ p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
+ }
+ }
+ else
+ TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
+
+ FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
+
+ if (p_FmPort->im.p_BdShadow)
+ XX_Free(p_FmPort->im.p_BdShadow);
+
+ if (p_FmPort->im.p_BdRing)
+ XX_FreeSmart(p_FmPort->im.p_BdRing);
+}
+
+
+t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->im.mrblr = newVal;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->im.bdRingSize = newVal;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->im.bdRingSize = newVal;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
+ uint8_t memId,
+ uint32_t memAttributes)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ p_FmPort->im.fwExtStructsMemId = memId;
+ p_FmPort->im.fwExtStructsMemAttr = memAttributes;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
+
+ if (!FmIsMaster(p_FmPort->h_Fm))
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
+ "in guest-partitions, IM is always in polling!"));
+
+ p_FmPort->polling = TRUE;
+
+ return E_OK;
+}
+
+t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ t_Error err;
+ uint16_t tmpReg16;
+ uint32_t tmpReg32;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ if(exception == e_FM_PORT_EXCEPTION_IM_BUSY)
+ {
+ if(enable)
+ {
+ p_FmPort->exceptions |= IM_EV_BSY;
+ if(p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
+ {
+ /* Allocate, configure and register interrupts */
+ err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
+
+ FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
+ tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
+ tmpReg32 = IM_EV_BSY;
+ }
+ else
+ {
+ tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
+ tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
+ }
+
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
+ }
+ else
+ {
+ p_FmPort->exceptions &= ~IM_EV_BSY;
+ if (!p_FmPort->exceptions && p_FmPort->polling)
+ {
+ FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
+ FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
+ p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
+ }
+ else
+ {
+ tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
+ tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
+ }
+ }
+ }
+ else
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
+
+ return E_OK;
+}
+
+t_Error FM_PORT_ImTx( t_Handle h_FmPort,
+ uint8_t *p_Data,
+ uint16_t length,
+ bool lastBuffer,
+ t_Handle h_BufContext)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+ uint16_t nextBdId;
+ uint32_t bdStatus, nextBdStatus;
+ bool firstBuffer;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
+ nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
+ nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
+
+ if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
+ {
+ /* Confirm the current BD - BD is available */
+ if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
+ p_FmPort->im.f_TxConf (p_FmPort->h_App,
+ BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
+ 0,
+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
+
+ bdStatus = length;
+
+ /* if this is the first BD of a frame */
+ if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
+ {
+ firstBuffer = TRUE;
+ p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
+
+ if (!lastBuffer)
+ p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
+ }
+ else
+ firstBuffer = FALSE;
+
+ BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
+
+ /* deal with last */
+ if (lastBuffer)
+ {
+ /* if single buffer frame */
+ if (firstBuffer)
+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
+ else
+ {
+ /* Set the last BD of the frame */
+ BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
+ /* Set the first BD of the frame */
+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
+ }
+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
+ }
+ else if (!firstBuffer) /* mid frame buffer */
+ BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
+
+ p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
+ }
+ else
+ {
+ /* Discard current frame. Return error. */
+ if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
+ {
+ /* Error: No free BD */
+ /* Response: Discard current frame. Return error. */
+ uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
+
+ ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
+
+ /* Since firstInFrame is not NULL, one buffer at least has already been
+ inserted into the BD ring. Using do-while covers the situation of a
+ frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
+ prior to testing whether or not it's equal to TxBd). */
+ do
+ {
+ BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
+ /* Advance BD pointer */
+ cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
+ } while (cleanBdId != p_FmPort->im.currBdId);
+
+ p_FmPort->im.currBdId = cleanBdId;
+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
+ }
+
+ return ERROR_CODE(E_FULL);
+ }
+
+ return E_OK;
+}
+
+void FM_PORT_ImTxConf(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
+}
+
+t_Error FM_PORT_ImRx(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
+
+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
+
+ return FmPortImRx(p_FmPort);
+}
diff --git a/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c
new file mode 100644
index 0000000..13ac047
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c
@@ -0,0 +1,891 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_rtc.c
+
+ @Description FM RTC driver implementation.
+
+ @Cautions None
+*//***************************************************************************/
+
+#include "error_ext.h"
+#include "debug_ext.h"
+#include "string_ext.h"
+#include "part_ext.h"
+#include "xx_ext.h"
+#include "ncsw_ext.h"
+
+#include "fm_rtc.h"
+#include "fm_common.h"
+
+
+/*****************************************************************************/
+static void SetDefaultParam(t_FmRtc *p_Rtc)
+{
+ t_FmRtcDriverParam *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
+ int i;
+
+ p_Rtc->outputClockDivisor = DEFAULT_outputClockDivisor;
+ p_Rtc->p_RtcDriverParam->bypass = DEFAULT_bypass;
+ p_RtcDriverParam->srcClk = DEFAULT_srcClock;
+ p_RtcDriverParam->invertInputClkPhase = DEFAULT_invertInputClkPhase;
+ p_RtcDriverParam->invertOutputClkPhase = DEFAULT_invertOutputClkPhase;
+ p_RtcDriverParam->pulseRealign = DEFAULT_pulseRealign;
+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
+ {
+ p_RtcDriverParam->alarmPolarity[i] = DEFAULT_alarmPolarity;
+ }
+ for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
+ {
+ p_RtcDriverParam->triggerPolarity[i] = DEFAULT_triggerPolarity;
+ }
+ p_Rtc->clockPeriodNanoSec = DEFAULT_clockPeriod; /* 1 usec */
+}
+
+/*****************************************************************************/
+static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
+{
+ t_FmRtcDriverParam *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
+ int i;
+
+ if ((p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_EXTERNAL) &&
+ (p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) &&
+ (p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_OSCILATOR))
+ RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
+
+ if (p_Rtc->outputClockDivisor == 0)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("Divisor for output clock (should be positive)"));
+ }
+
+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
+ {
+ if ((p_RtcDriverParam->alarmPolarity[i] != e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
+ (p_RtcDriverParam->alarmPolarity[i] != e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH))
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
+ }
+ }
+ for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
+ {
+ if ((p_RtcDriverParam->triggerPolarity[i] != e_FM_RTC_TRIGGER_ON_FALLING_EDGE) &&
+ (p_RtcDriverParam->triggerPolarity[i] != e_FM_RTC_TRIGGER_ON_RISING_EDGE))
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
+ }
+ }
+
+#ifdef FM_1588_SRC_CLK_ERRATA_FMAN1
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Rtc->h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0)&&
+ ((p_RtcDriverParam->srcClk==e_FM_RTC_SOURCE_CLOCK_SYSTEM) && p_RtcDriverParam->invertInputClkPhase))
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Can not use invertInputClkPhase when source clock is e_FM_RTC_SOURCE_CLOCK_SYSTEM"));
+ }
+#endif /* FM_1588_SRC_CLK_ERRATA_FMAN1 */
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+static void RtcExceptions(t_Handle h_FmRtc)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ t_FmRtcMemMap *p_MemMap;
+ register uint32_t events;
+
+ ASSERT_COND(p_Rtc);
+ p_MemMap = p_Rtc->p_MemMap;
+
+ /* Get valid events */
+ events = GET_UINT32(p_MemMap->tmr_tevent);
+ events &= GET_UINT32(p_MemMap->tmr_temask);
+
+ /* Clear event bits */
+ WRITE_UINT32(p_MemMap->tmr_tevent, events);
+
+ if (events & TMR_TEVENT_ALM1)
+ {
+ if(p_Rtc->alarmParams[0].clearOnExpiration)
+ {
+ WRITE_UINT32(p_MemMap->tmr_alarm[0].tmr_alarm_l, 0);
+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) & ~TMR_TEVENT_ALM1);
+ }
+ ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
+ p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
+ }
+ if (events & TMR_TEVENT_ALM2)
+ {
+ if(p_Rtc->alarmParams[1].clearOnExpiration)
+ {
+ WRITE_UINT32(p_MemMap->tmr_alarm[1].tmr_alarm_l, 0);
+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) & ~TMR_TEVENT_ALM2);
+ }
+ ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
+ p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
+ }
+ if (events & TMR_TEVENT_PP1)
+ {
+ ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
+ p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
+ }
+ if (events & TMR_TEVENT_PP2)
+ {
+ ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
+ p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
+ }
+ if (events & TMR_TEVENT_ETS1)
+ {
+ ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
+ p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
+ }
+ if (events & TMR_TEVENT_ETS2)
+ {
+ ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
+ p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
+ }
+}
+
+
+/*****************************************************************************/
+t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
+{
+ t_FmRtc *p_Rtc;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
+
+ /* Allocate memory for the FM RTC driver parameters */
+ p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
+ if (!p_Rtc)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
+ return NULL;
+ }
+
+ memset(p_Rtc, 0, sizeof(t_FmRtc));
+
+ /* Allocate memory for the FM RTC driver parameters */
+ p_Rtc->p_RtcDriverParam = (t_FmRtcDriverParam *)XX_Malloc(sizeof(t_FmRtcDriverParam));
+ if (!p_Rtc->p_RtcDriverParam)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
+ XX_Free(p_Rtc);
+ return NULL;
+ }
+
+ memset(p_Rtc->p_RtcDriverParam, 0, sizeof(t_FmRtcDriverParam));
+
+ /* Store RTC configuration parameters */
+ p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
+
+ /* Set default RTC configuration parameters */
+ SetDefaultParam(p_Rtc);
+
+ /* Store RTC parameters in the RTC control structure */
+ p_Rtc->p_MemMap = (t_FmRtcMemMap *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
+ p_Rtc->h_App = p_FmRtcParam->h_App;
+
+ return p_Rtc;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_Init(t_Handle h_FmRtc)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ t_FmRtcDriverParam *p_RtcDriverParam;
+ t_FmRtcMemMap *p_MemMap;
+ uint32_t freqCompensation;
+ uint32_t tmrCtrl;
+ int i;
+ uint64_t tmpDouble;
+
+ p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
+ p_MemMap = p_Rtc->p_MemMap;
+
+ if(CheckInitParameters(p_Rtc)!=E_OK)
+ RETURN_ERROR(MAJOR, E_CONFLICT,
+ ("Init Parameters are not Valid"));
+
+ /* TODO A check must be added here, that no timestamping MAC's
+ * are working in this stage. */
+ WRITE_UINT32(p_MemMap->tmr_ctrl, TMR_CTRL_TMSR);
+ XX_UDelay(10);
+ WRITE_UINT32(p_MemMap->tmr_ctrl, 0);
+
+ /* Set the source clock */
+ switch (p_RtcDriverParam->srcClk)
+ {
+ case e_FM_RTC_SOURCE_CLOCK_SYSTEM:
+ tmrCtrl = TMR_CTRL_CKSEL_MAC_CLK;
+ break;
+ case e_FM_RTC_SOURCE_CLOCK_OSCILATOR:
+ tmrCtrl = TMR_CTRL_CKSEL_OSC_CLK;
+ break;
+ default:
+ /* Use a clock from the External TMR reference clock.*/
+ tmrCtrl = TMR_CTRL_CKSEL_EXT_CLK;
+ break;
+ }
+
+ /* whatever period the user picked, the timestamp will advance in '1' every time
+ * the period passed. */
+ tmrCtrl |= ((1 << TMR_CTRL_TCLK_PERIOD_SHIFT) & TMR_CTRL_TCLK_PERIOD_MASK);
+
+ if (p_RtcDriverParam->invertInputClkPhase)
+ tmrCtrl |= TMR_CTRL_CIPH;
+ if (p_RtcDriverParam->invertOutputClkPhase)
+ tmrCtrl |= TMR_CTRL_COPH;
+
+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
+ {
+ if (p_RtcDriverParam->alarmPolarity[i] == e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW)
+ tmrCtrl |= (TMR_CTRL_ALMP1 >> i);
+ }
+
+ for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
+ if (p_RtcDriverParam->triggerPolarity[i] == e_FM_RTC_TRIGGER_ON_FALLING_EDGE)
+ tmrCtrl |= (TMR_CTRL_ETEP1 << i);
+
+ if (!p_RtcDriverParam->timerSlaveMode && p_Rtc->p_RtcDriverParam->bypass)
+ tmrCtrl |= TMR_CTRL_BYP;
+
+ WRITE_UINT32(p_MemMap->tmr_ctrl, tmrCtrl);
+
+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
+ {
+ /* Clear TMR_ALARM registers */
+ WRITE_UINT32(p_MemMap->tmr_alarm[i].tmr_alarm_l, 0xFFFFFFFF);
+ WRITE_UINT32(p_MemMap->tmr_alarm[i].tmr_alarm_h, 0xFFFFFFFF);
+ }
+
+ /* Clear TMR_TEVENT */
+ WRITE_UINT32(p_MemMap->tmr_tevent, TMR_TEVENT_ALL);
+
+ /* Initialize TMR_TEMASK */
+ WRITE_UINT32(p_MemMap->tmr_temask, 0);
+
+
+ /* find source clock frequency in Mhz */
+ if (p_Rtc->p_RtcDriverParam->srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
+ p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->extSrcClkFreq;
+ else
+ p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetClockFreq(p_Rtc->h_Fm)/2);
+
+ /* if timer in Master mode Initialize TMR_CTRL */
+ /* We want the counter (TMR_CNT) to count in nano-seconds */
+ if (!p_RtcDriverParam->timerSlaveMode && p_Rtc->p_RtcDriverParam->bypass)
+ {
+ p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
+ }
+ else
+ {
+ /* Initialize TMR_ADD with the initial frequency compensation value:
+ freqCompensation = (2^32 / frequency ratio) */
+ /* frequency ratio = sorce clock/rtc clock =
+ * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
+ freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
+ p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
+ WRITE_UINT32(p_MemMap->tmr_add, freqCompensation);
+ }
+ /* check the legality of the relation between source and destination clocks */
+ /* should be larger than 1.0001 */
+ tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
+ if((tmpDouble) <= 10001)
+ RETURN_ERROR(MAJOR, E_CONFLICT,
+ ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
+
+
+ for (i=0; i < 2; i++)
+ /* Clear TMR_FIPER registers */
+ WRITE_UINT32(p_MemMap->tmr_fiper[i], 0xFFFFFFFF);
+
+ /* Initialize TMR_PRSC */
+ WRITE_UINT32(p_MemMap->tmr_prsc, p_Rtc->outputClockDivisor);
+
+ /* Clear TMR_OFF */
+ WRITE_UINT32(p_MemMap->tmr_off_l, 0);
+ WRITE_UINT32(p_MemMap->tmr_off_h, 0);
+
+ /* Register the FM RTC interrupt */
+ FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
+
+ /* Free parameters structures */
+ XX_Free(p_Rtc->p_RtcDriverParam);
+ p_Rtc->p_RtcDriverParam = NULL;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_Free(t_Handle h_FmRtc)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+
+ if (p_Rtc->p_RtcDriverParam)
+ {
+ XX_Free(p_Rtc->p_RtcDriverParam);
+ }
+ else
+ {
+ FM_RTC_Disable(h_FmRtc);
+ }
+
+ /* Unregister FM RTC interrupt */
+ FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
+ XX_Free(p_Rtc);
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
+ e_FmSrcClk srcClk,
+ uint32_t freqInMhz)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_Rtc->p_RtcDriverParam->srcClk = srcClk;
+ if(srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
+ p_Rtc->p_RtcDriverParam->extSrcClkFreq = freqInMhz;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_Rtc->clockPeriodNanoSec = period;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_Rtc->p_RtcDriverParam->bypass = enabled;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_Rtc->p_RtcDriverParam->invertInputClkPhase = inverted;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_Rtc->p_RtcDriverParam->invertOutputClkPhase = inverted;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_Rtc->outputClockDivisor = divisor;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_Rtc->p_RtcDriverParam->pulseRealign = enable;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
+ uint8_t alarmId,
+ e_FmRtcAlarmPolarity alarmPolarity)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ if (alarmId >= FM_RTC_NUM_OF_ALARMS)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
+ }
+
+ p_Rtc->p_RtcDriverParam->alarmPolarity[alarmId] = alarmPolarity;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
+ uint8_t triggerId,
+ e_FmRtcTriggerPolarity triggerPolarity)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
+ }
+
+ p_Rtc->p_RtcDriverParam->triggerPolarity[triggerId] = triggerPolarity;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ uint32_t tmrCtrl;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ tmrCtrl = GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl);
+
+ /* TODO A check must be added here, that no timestamping MAC's
+ * are working in this stage. */
+ if (resetClock)
+ {
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl | TMR_CTRL_TMSR));
+
+ XX_UDelay(10);
+ /* Clear TMR_OFF */
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_l, 0);
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_h, 0);
+ }
+
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl | TMR_CTRL_TE));
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_Disable(t_Handle h_FmRtc)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ uint32_t tmrCtrl;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ /* TODO A check must be added here, that no timestamping MAC's
+ * are working in this stage. */
+ tmrCtrl = GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl);
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, (tmrCtrl & ~(TMR_CTRL_TE)));
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ /* TMR_OFF_L must be written first */
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_l, (uint32_t)offset);
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_off_h, (uint32_t)(offset >> 32));
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ t_FmRtcMemMap *p_MemMap;
+ uint32_t tmpReg;
+ uint64_t tmpAlarm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_MemMap = p_Rtc->p_MemMap;
+
+ if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
+ }
+
+ if(p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm time must be equal or larger than RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec));
+ if(p_FmRtcAlarmParams->alarmTime % (uint64_t)p_Rtc->clockPeriodNanoSec)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm time must be a multiple of RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec));
+ tmpAlarm = p_FmRtcAlarmParams->alarmTime/(uint64_t)p_Rtc->clockPeriodNanoSec;
+
+ /* TMR_ALARM_L must be written first */
+ WRITE_UINT32(p_MemMap->tmr_alarm[p_FmRtcAlarmParams->alarmId].tmr_alarm_l, (uint32_t)tmpAlarm);
+ WRITE_UINT32(p_MemMap->tmr_alarm[p_FmRtcAlarmParams->alarmId].tmr_alarm_h,
+ (uint32_t)(tmpAlarm >> 32));
+
+ if (p_FmRtcAlarmParams->f_AlarmCallback)
+ {
+ p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
+ p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
+
+ if(p_FmRtcAlarmParams->alarmId == 0)
+ tmpReg = TMR_TEVENT_ALM1;
+ else
+ tmpReg = TMR_TEVENT_ALM2;
+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) | tmpReg);
+ }
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ t_FmRtcMemMap *p_MemMap;
+ uint32_t tmpReg;
+ uint64_t tmpFiper;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ p_MemMap = p_Rtc->p_MemMap;
+
+ if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
+ }
+ if(GET_UINT32(p_MemMap->tmr_ctrl) & TMR_CTRL_TE)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
+ if(p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec));
+ if(p_FmRtcPeriodicPulseParams->periodicPulsePeriod % (uint64_t)p_Rtc->clockPeriodNanoSec)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse must be a multiple of RTC period - %d nanoseconds", p_Rtc->clockPeriodNanoSec));
+ tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod/(uint64_t)p_Rtc->clockPeriodNanoSec;
+ if(tmpFiper & 0xffffffff00000000LL)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse/RTC Period must be smaller than 4294967296", p_Rtc->clockPeriodNanoSec));
+
+ WRITE_UINT32(p_MemMap->tmr_fiper[p_FmRtcPeriodicPulseParams->periodicPulseId], (uint32_t)tmpFiper);
+
+ if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
+ {
+ p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
+ p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
+
+ if(p_FmRtcPeriodicPulseParams->periodicPulseId == 0)
+ tmpReg = TMR_TEVENT_PP1;
+ else
+ tmpReg = TMR_TEVENT_PP2;
+ WRITE_UINT32(p_MemMap->tmr_temask, GET_UINT32(p_MemMap->tmr_temask) | tmpReg);
+ }
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
+ }
+
+ p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
+
+ if(periodicPulseId == 0)
+ tmpReg = TMR_TEVENT_PP1;
+ else
+ tmpReg = TMR_TEVENT_PP2;
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) & ~tmpReg);
+
+ if (GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & TMR_CTRL_FS)
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & ~TMR_CTRL_FS);
+
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_fiper[periodicPulseId], 0xFFFFFFFF);
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
+ }
+
+ if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
+ {
+ p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
+ if(p_FmRtcExternalTriggerParams->externalTriggerId == 0)
+ tmpReg = TMR_TEVENT_ETS1;
+ else
+ tmpReg = TMR_TEVENT_ETS2;
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) | tmpReg);
+ }
+
+ if(p_FmRtcExternalTriggerParams->usePulseAsInput)
+ {
+ if(p_FmRtcExternalTriggerParams->externalTriggerId == 0)
+ tmpReg = TMR_CTRL_PP1L;
+ else
+ tmpReg = TMR_CTRL_PP2L;
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) | tmpReg);
+ }
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
+
+ p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
+
+ if(externalTriggerId == 0)
+ tmpReg = TMR_TEVENT_ETS1;
+ else
+ tmpReg = TMR_TEVENT_ETS2;
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_temask, GET_UINT32(p_Rtc->p_MemMap->tmr_temask) & ~tmpReg);
+
+ if(externalTriggerId == 0)
+ tmpReg = TMR_CTRL_PP1L;
+ else
+ tmpReg = TMR_CTRL_PP2L;
+
+ if (GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & tmpReg)
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_ctrl, GET_UINT32(p_Rtc->p_MemMap->tmr_ctrl) & ~tmpReg);
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
+ uint8_t triggerId,
+ uint64_t *p_TimeStamp)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ uint64_t timeStamp;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
+ }
+
+ timeStamp = (uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_etts[triggerId].tmr_etts_l);
+ timeStamp |= ((uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_etts[triggerId].tmr_etts_h) << 32);
+
+ timeStamp = timeStamp*p_Rtc->clockPeriodNanoSec;
+ *p_TimeStamp = timeStamp;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ uint64_t time;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ /* TMR_CNT_L must be read first to get an accurate value */
+ time = (uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_cnt_l);
+ time |= ((uint64_t)GET_UINT32(p_Rtc->p_MemMap->tmr_cnt_h) << 32);
+
+ time = time*p_Rtc->clockPeriodNanoSec;
+
+ *p_Ts = time;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ ts = ts/p_Rtc->clockPeriodNanoSec;
+ /* TMR_CNT_L must be written first to get an accurate value */
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_cnt_l, (uint32_t)ts);
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_cnt_h, (uint32_t)(ts >> 32));
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ *p_Compensation = (uint32_t)
+ DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
+ p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+
+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
+
+ /* set the new freqCompensation */
+ WRITE_UINT32(p_Rtc->p_MemMap->tmr_add, freqCompensation);
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc)
+{
+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
+ t_FmRtcMemMap *p_MemMap = p_Rtc->p_MemMap;
+ int i = 0;
+
+ DECLARE_DUMP;
+
+ if (p_MemMap)
+ {
+
+ DUMP_TITLE(p_MemMap, ("RTC:"));
+ DUMP_VAR(p_MemMap, tmr_id);
+ DUMP_VAR(p_MemMap, tmr_id2);
+ DUMP_VAR(p_MemMap, tmr_ctrl);
+ DUMP_VAR(p_MemMap, tmr_tevent);
+ DUMP_VAR(p_MemMap, tmr_temask);
+ DUMP_VAR(p_MemMap, tmr_cnt_h);
+ DUMP_VAR(p_MemMap, tmr_cnt_l);
+ DUMP_VAR(p_MemMap, tmr_ctrl);
+ DUMP_VAR(p_MemMap, tmr_add);
+ DUMP_VAR(p_MemMap, tmr_acc);
+ DUMP_VAR(p_MemMap, tmr_prsc);
+ DUMP_VAR(p_MemMap, tmr_off_h);
+ DUMP_VAR(p_MemMap, tmr_off_l);
+
+ DUMP_SUBSTRUCT_ARRAY(i, 2)
+ {
+ DUMP_VAR(p_MemMap, tmr_alarm[i].tmr_alarm_h);
+ DUMP_VAR(p_MemMap, tmr_alarm[i].tmr_alarm_l);
+ }
+ DUMP_SUBSTRUCT_ARRAY(i, 2)
+ {
+ DUMP_VAR(p_MemMap, tmr_fiper[i]);
+ DUMP_VAR(p_MemMap, tmr_fiper[i]);
+ }
+ DUMP_SUBSTRUCT_ARRAY(i, 2)
+ {
+ DUMP_VAR(p_MemMap, tmr_etts[i].tmr_etts_l);
+ DUMP_VAR(p_MemMap, tmr_etts[i].tmr_etts_l);
+ }
+ }
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
diff --git a/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h
new file mode 100644
index 0000000..f112225
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.h
@@ -0,0 +1,217 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_rtc.h
+
+ @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
+
+ @Cautions None
+*//***************************************************************************/
+
+#ifndef __FM_RTC_H__
+#define __FM_RTC_H__
+
+#include "std_ext.h"
+#include "fm_rtc_ext.h"
+
+
+#define __ERR_MODULE__ MODULE_FM_RTC
+
+/* General definitions */
+
+#define NANOSEC_PER_ONE_HZ_TICK 1000000000
+#define MIN_RTC_CLK_FREQ_HZ 1000
+#define MHz 1000000
+
+#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
+
+/* RTC default values */
+#define DEFAULT_srcClock e_FM_RTC_SOURCE_CLOCK_SYSTEM
+#define DEFAULT_bypass FALSE
+#define DEFAULT_invertInputClkPhase FALSE
+#define DEFAULT_invertOutputClkPhase FALSE
+#define DEFAULT_outputClockDivisor 0x00000002
+#define DEFAULT_alarmPolarity e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH
+#define DEFAULT_triggerPolarity e_FM_RTC_TRIGGER_ON_FALLING_EDGE
+#define DEFAULT_pulseRealign FALSE
+#define DEFAULT_clockPeriod 1000
+
+/* FM RTC Registers definitions */
+#define TMR_CTRL_ALMP1 0x80000000
+#define TMR_CTRL_ALMP2 0x40000000
+#define TMR_CTRL_FS 0x10000000
+#define TMR_CTRL_PP1L 0x08000000
+#define TMR_CTRL_PP2L 0x04000000
+#define TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
+#define TMR_CTRL_FRD 0x00004000
+#define TMR_CTRL_SLV 0x00002000
+#define TMR_CTRL_ETEP1 0x00000100
+#define TMR_CTRL_COPH 0x00000080
+#define TMR_CTRL_CIPH 0x00000040
+#define TMR_CTRL_TMSR 0x00000020
+#define TMR_CTRL_DBG 0x00000010
+#define TMR_CTRL_BYP 0x00000008
+#define TMR_CTRL_TE 0x00000004
+#define TMR_CTRL_CKSEL_OSC_CLK 0x00000003
+#define TMR_CTRL_CKSEL_MAC_CLK 0x00000001
+#define TMR_CTRL_CKSEL_EXT_CLK 0x00000000
+#define TMR_CTRL_TCLK_PERIOD_SHIFT 16
+
+#define TMR_TEVENT_ETS2 0x02000000
+#define TMR_TEVENT_ETS1 0x01000000
+#define TMR_TEVENT_ALM2 0x00020000
+#define TMR_TEVENT_ALM1 0x00010000
+#define TMR_TEVENT_PP1 0x00000080
+#define TMR_TEVENT_PP2 0x00000040
+#define TMR_TEVENT_PP3 0x00000020
+#define TMR_TEVENT_ALL (TMR_TEVENT_ETS2 | TMR_TEVENT_ETS1 | \
+ TMR_TEVENT_ALM2 | TMR_TEVENT_ALM1 | \
+ TMR_TEVENT_PP1 | TMR_TEVENT_PP2 | TMR_TEVENT_PP3)
+
+#define TMR_PRSC_OCK_MASK 0x0000FFFF
+
+
+/**************************************************************************//**
+ @Description Memory Mapped Registers
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/**************************************************************************//**
+ @Description FM RTC timer alarm
+*//***************************************************************************/
+typedef _Packed struct t_TmrAlaram
+{
+ volatile uint32_t tmr_alarm_h; /**< */
+ volatile uint32_t tmr_alarm_l; /**< */
+} _PackedType t_TmrAlaram;
+
+/**************************************************************************//**
+ @Description FM RTC timer Ex trigger
+*//***************************************************************************/
+typedef _Packed struct t_TmrExtTrigger
+{
+ volatile uint32_t tmr_etts_h; /**< */
+ volatile uint32_t tmr_etts_l; /**< */
+} _PackedType t_TmrExtTrigger;
+
+typedef _Packed struct
+{
+ volatile uint32_t tmr_id; /* Module ID and version register */
+ volatile uint32_t tmr_id2; /* Module ID and configuration register */
+ volatile uint32_t PTP_RESERVED1[30];
+ volatile uint32_t tmr_ctrl; /* timer control register */
+ volatile uint32_t tmr_tevent; /* timer event register */
+ volatile uint32_t tmr_temask; /* timer event mask register */
+ volatile uint32_t PTP_RESERVED2[3];
+ volatile uint32_t tmr_cnt_h; /* timer counter high register */
+ volatile uint32_t tmr_cnt_l; /* timer counter low register */
+ volatile uint32_t tmr_add; /* timer drift compensation addend register */
+ volatile uint32_t tmr_acc; /* timer accumulator register */
+ volatile uint32_t tmr_prsc; /* timer prescale */
+ volatile uint32_t PTP_RESERVED3;
+ volatile uint32_t tmr_off_h; /* timer offset high */
+ volatile uint32_t tmr_off_l; /* timer offset low */
+ volatile t_TmrAlaram tmr_alarm[FM_RTC_NUM_OF_ALARMS]; /* timer alarm */
+ volatile uint32_t PTP_RESERVED4[2];
+ volatile uint32_t tmr_fiper[FM_RTC_NUM_OF_PERIODIC_PULSES]; /* timer fixed period interval */
+ volatile uint32_t PTP_RESERVED5[2];
+ volatile t_TmrExtTrigger tmr_etts[FM_RTC_NUM_OF_EXT_TRIGGERS]; /*time stamp general purpose external */
+ volatile uint32_t PTP_RESERVED6[3];
+} _PackedType t_FmRtcMemMap;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/**************************************************************************//**
+ @Description RTC FM driver parameters structure.
+*//***************************************************************************/
+typedef struct t_FmRtcDriverParam
+{
+ t_Handle h_Fm; /**< */
+ e_FmSrcClk srcClk; /**< */
+ uint32_t extSrcClkFreq; /**< */
+ uint32_t rtcFreqHz; /**< */
+ bool timerSlaveMode; /*Slave/Master Mode*/
+ bool invertInputClkPhase;
+ bool invertOutputClkPhase;
+ uint32_t eventsMask;
+ bool bypass; /**< Indicates if frequency compensation is bypassed */
+ bool pulseRealign;
+ e_FmRtcAlarmPolarity alarmPolarity[FM_RTC_NUM_OF_ALARMS];
+ e_FmRtcTriggerPolarity triggerPolarity[FM_RTC_NUM_OF_EXT_TRIGGERS];
+} t_FmRtcDriverParam;
+
+typedef struct t_FmRtcAlarm
+{
+ t_FmRtcExceptionsCallback *f_AlarmCallback;
+ bool clearOnExpiration;
+} t_FmRtcAlarm;
+
+typedef struct t_FmRtcPeriodicPulse
+{
+ t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
+} t_FmRtcPeriodicPulse;
+
+typedef struct t_FmRtcExternalTrigger
+{
+ t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
+} t_FmRtcExternalTrigger;
+
+
+/**************************************************************************//**
+ @Description RTC FM driver control structure.
+*//***************************************************************************/
+typedef struct t_FmRtc
+{
+ t_Part *p_Part; /**< Pointer to the integration device */
+ t_Handle h_Fm;
+ t_Handle h_App; /**< Application handle */
+ t_FmRtcMemMap *p_MemMap; /**< Pointer to RTC memory map */
+ uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
+ uint32_t srcClkFreqMhz;
+ uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
+ t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
+ t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
+ t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
+ t_FmRtcDriverParam *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
+} t_FmRtc;
+
+
+#endif /* __FM_RTC_H__ */
diff --git a/sys/contrib/ncsw/Peripherals/FM/fm.c b/sys/contrib/ncsw/Peripherals/FM/fm.c
new file mode 100644
index 0000000..a0f2251
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/fm.c
@@ -0,0 +1,4605 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm.c
+
+ @Description FM driver routines implementation.
+*//***************************************************************************/
+#include "std_ext.h"
+#include "error_ext.h"
+#include "xx_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "debug_ext.h"
+#include "fm_muram_ext.h"
+
+#include "fm_common.h"
+#include "fm_ipc.h"
+#include "fm.h"
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+
+static volatile bool blockingFlag = FALSE;
+static void IpcMsgCompletionCB(t_Handle h_Fm,
+ uint8_t *p_Msg,
+ uint8_t *p_Reply,
+ uint32_t replyLength,
+ t_Error status)
+{
+ UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
+ blockingFlag = FALSE;
+}
+
+static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
+{
+ t_FMIramRegs *p_Iram;
+
+ ASSERT_COND(p_Fm);
+ p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
+
+ return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
+}
+
+static t_Error CheckFmParameters(t_Fm *p_Fm)
+{
+ if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->p_FmDriverParam->resetOnInit)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
+ if(!p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats || (p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
+ if(p_Fm->p_FmDriverParam->dmaCamNumOfEntries % DMA_CAM_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be divisble by %d", DMA_CAM_UNITS));
+ if(!p_Fm->p_FmDriverParam->dmaCamNumOfEntries || (p_Fm->p_FmDriverParam->dmaCamNumOfEntries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCamNumOfEntries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES));
+ if(p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency > DMA_THRESH_MAX_COMMQ)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ));
+ if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency > DMA_THRESH_MAX_COMMQ)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_COMMQ));
+ if(p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaCommQThresholds.clearEmergency must be smaller than dmaCommQThresholds.assertEmergency"));
+ if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
+ if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
+ if(p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaReadBufThresholds.clearEmergency must be smaller than dmaReadBufThresholds.assertEmergency"));
+ if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency > DMA_THRESH_MAX_BUF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.assertEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
+ if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency > DMA_THRESH_MAX_BUF)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency can not be larger than %d", DMA_THRESH_MAX_BUF));
+ if(p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency >= p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dmaWriteBufThresholds.clearEmergency must be smaller than dmaWriteBufThresholds.assertEmergency"));
+
+ if(!p_Fm->p_FmStateStruct->fmClkFreq)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
+ if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,
+ ("dmaWatchdog depends on FM clock. dmaWatchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
+
+#ifdef FM_PARTITION_ARRAY
+ {
+ t_FmRevisionInfo revInfo;
+ uint8_t i;
+
+ FM_GetRevision(p_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ for (i=0; i<FM_SIZE_OF_LIODN_TABLE; i++)
+ if (p_Fm->p_FmDriverParam->liodnBasePerPort[i] & ~FM_LIODN_BASE_MASK)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodn number is out of range"));
+ }
+#endif /* FM_PARTITION_ARRAY */
+
+ if(p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
+ if(!p_Fm->p_FmStateStruct->totalFifoSize || (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be in the range 256 - %d", BMI_MAX_FIFO_SIZE));
+ if(!p_Fm->p_FmStateStruct->totalNumOfTasks || (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
+ if(!p_Fm->p_FmStateStruct->maxNumOfOpenDmas || (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
+
+ if(p_Fm->p_FmDriverParam->thresholds.dispLimit > FPM_MAX_DISP_LIMIT)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("thresholds.dispLimit can't be greater than %d", FPM_MAX_DISP_LIMIT));
+
+ if(!p_Fm->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
+ if(!p_Fm->f_BusError)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
+
+ return E_OK;
+}
+
+static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
+{
+ t_Error err;
+ t_FmIpcIsr fmIpcIsr;
+ t_FmIpcMsg msg;
+
+ ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
+ ASSERT_COND(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId]);
+ if (p_Fm->intrMng[macEvent].guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_GUEST_ISR;
+ fmIpcIsr.pendingReg = pendingReg;
+ fmIpcIsr.boolErr = FALSE;
+ memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(fmIpcIsr),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return;
+ }
+ else
+ p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
+}
+
+static void BmiErrEvent(t_Fm *p_Fm)
+{
+ uint32_t event, mask, force;
+
+ event = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr);
+ mask = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
+ event &= mask;
+
+ /* clear the forced events */
+ force = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr);
+ if(force & event)
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, force & ~event);
+
+
+ /* clear the acknowledged events */
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, event);
+
+ if(event & BMI_ERR_INTR_EN_PIPELINE_ECC)
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_PIPELINE_ECC);
+ if(event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
+ if(event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
+ if(event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
+}
+
+static void QmiErrEvent(t_Fm *p_Fm)
+{
+ uint32_t event, mask, force;
+
+ event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie);
+ mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
+
+ event &= mask;
+
+ /* clear the forced events */
+ force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif);
+ if(force & event)
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, force & ~event);
+
+ /* clear the acknowledged events */
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, event);
+
+ if(event & QMI_ERR_INTR_EN_DOUBLE_ECC)
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
+ if(event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
+}
+
+static void DmaErrEvent(t_Fm *p_Fm)
+{
+ uint64_t addr=0;
+ uint32_t status, mask, tmpReg=0;
+ uint8_t tnum;
+ uint8_t hardwarePortId;
+ uint8_t relativePortId;
+ uint16_t liodn;
+
+ status = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr);
+ mask = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
+
+ /* get bus error regs befor clearing BER */
+ if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER))
+ {
+ addr = (uint64_t)GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtal);
+ addr |= ((uint64_t)(GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtah)) << 32);
+
+ /* get information about the owner of that bus error */
+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmtcid);
+ }
+
+ /* clear set events */
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, status);
+
+ if ((status & DMA_STATUS_BUS_ERR) && (mask & DMA_MODE_BER))
+ {
+ hardwarePortId = (uint8_t)(((tmpReg & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
+ HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
+ tnum = (uint8_t)((tmpReg & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
+ liodn = (uint16_t)(tmpReg & DMA_TRANSFER_LIODN_MASK);
+ ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
+ p_Fm->f_BusError(p_Fm->h_App, p_Fm->p_FmStateStruct->portsTypes[hardwarePortId], relativePortId, addr, tnum, liodn);
+ }
+ if(mask & DMA_MODE_ECC)
+ {
+ if (status & DMA_STATUS_READ_ECC)
+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
+ if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
+ if (status & DMA_STATUS_FM_WRITE_ECC)
+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
+ }
+}
+
+static void FpmErrEvent(t_Fm *p_Fm)
+{
+ uint32_t event;
+
+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
+
+ /* clear the all occurred events */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, event);
+
+ if((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
+ if((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
+ if((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
+}
+
+static void MuramErrIntr(t_Fm *p_Fm)
+{
+ uint32_t event, mask;
+
+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
+ mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
+
+ /* clear MURAM event bit */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_IRAM_ECC);
+
+ ASSERT_COND(event & FPM_RAM_CTL_MURAM_ECC);
+ ASSERT_COND(event & FPM_RAM_CTL_RAMS_ECC_EN);
+
+ if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
+}
+
+static void IramErrIntr(t_Fm *p_Fm)
+{
+ uint32_t event, mask;
+
+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr) ;
+ mask = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
+ /* clear the acknowledged events (do not clear IRAM event) */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, event & ~FPM_RAM_CTL_MURAM_ECC);
+
+ ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC);
+ ASSERT_COND(event & FPM_RAM_CTL_IRAM_ECC_EN);
+
+ if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
+}
+
+static void QmiEvent(t_Fm *p_Fm)
+{
+ uint32_t event, mask, force;
+
+ event = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie);
+ mask = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien);
+
+ event &= mask;
+
+ /* clear the forced events */
+ force = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_if);
+ if(force & event)
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, force & ~event);
+
+ /* clear the acknowledged events */
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, event);
+
+ if(event & QMI_INTR_EN_SINGLE_ECC)
+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
+}
+
+static void UnimplementedIsr(t_Handle h_Arg)
+{
+ UNUSED(h_Arg);
+
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
+}
+
+static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
+{
+ UNUSED(h_Arg); UNUSED(event);
+
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl Isr!"));
+}
+
+static void FmEnableTimeStamp(t_Fm *p_Fm)
+{
+ uint32_t tmpReg;
+ uint64_t fraction;
+ uint32_t integer;
+ uint8_t count1MicroBit = 8;
+ uint32_t tsFrequency = (uint32_t)(1<<count1MicroBit); /* in Mhz */
+
+ /* configure timestamp so that bit 8 will count 1 microsecond */
+ /* Find effective count rate at TIMESTAMP least significant bits:
+ Effective_Count_Rate = 1MHz x 2^8 = 256MHz
+ Find frequency ratio between effective count rate and the clock:
+ Effective_Count_Rate / CLK e.g. for 600 MHz clock:
+ 256/600 = 0.4266666... */
+ integer = tsFrequency/p_Fm->p_FmStateStruct->fmClkFreq;
+ /* we multiply by 2^16 to keep the fraction of the division */
+ /* we do not divid back, since we write this value as fraction - see spec */
+ fraction = ((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq)/p_Fm->p_FmStateStruct->fmClkFreq;
+ /* we check remainder of the division in order to round up if not integer */
+ if(((tsFrequency << 16) - (integer << 16)*p_Fm->p_FmStateStruct->fmClkFreq) % p_Fm->p_FmStateStruct->fmClkFreq)
+ fraction++;
+
+ tmpReg = (integer << FPM_TS_INT_SHIFT) | (uint16_t)fraction;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc2, tmpReg);
+
+ /* enable timestamp with original clock */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmtsc1, FPM_TS_CTL_EN);
+
+ p_Fm->p_FmStateStruct->count1MicroBit = count1MicroBit;
+ p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
+}
+
+static void FreeInitResources(t_Fm *p_Fm)
+{
+ if (p_Fm->camBaseAddr)
+ FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
+ if (p_Fm->fifoBaseAddr)
+ FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
+ if (p_Fm->resAddr)
+ FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
+}
+
+static t_Error ClearIRam(t_Fm *p_Fm)
+{
+ t_FMIramRegs *p_Iram;
+ int i;
+
+ ASSERT_COND(p_Fm);
+ p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
+
+ /* Enable the auto-increment */
+ WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
+ while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
+
+ for (i=0; i < (FM_IRAM_SIZE/4); i++)
+ WRITE_UINT32(p_Iram->idata, 0xffffffff);
+
+ WRITE_UINT32(p_Iram->iadd, FM_IRAM_SIZE - 4);
+ CORE_MemoryBarrier();
+ while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
+
+ return E_OK;
+}
+
+static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
+{
+ t_FMIramRegs *p_Iram;
+ int i;
+ uint32_t tmp;
+ uint8_t compTo16;
+
+ ASSERT_COND(p_Fm);
+ p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
+
+ /* Enable the auto-increment */
+ WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
+ while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
+
+ for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++)
+ WRITE_UINT32(p_Iram->idata, p_Fm->p_FmDriverParam->firmware.p_Code[i]);
+
+ compTo16 = (uint8_t)(p_Fm->p_FmDriverParam->firmware.size % 16);
+ if(compTo16)
+ for (i=0; i < ((16-compTo16) / 4); i++)
+ WRITE_UINT32(p_Iram->idata, 0xffffffff);
+
+ WRITE_UINT32(p_Iram->iadd,p_Fm->p_FmDriverParam->firmware.size-4);
+ while(GET_UINT32(p_Iram->iadd) != (p_Fm->p_FmDriverParam->firmware.size-4)) ;
+
+ /* verify that writing has completed */
+ while (GET_UINT32(p_Iram->idata) != p_Fm->p_FmDriverParam->firmware.p_Code[(p_Fm->p_FmDriverParam->firmware.size / 4)-1]) ;
+
+ if (p_Fm->p_FmDriverParam->fwVerify)
+ {
+ WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
+ while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
+ for (i=0; i < (p_Fm->p_FmDriverParam->firmware.size / 4); i++)
+ if ((tmp=GET_UINT32(p_Iram->idata)) != p_Fm->p_FmDriverParam->firmware.p_Code[i])
+ RETURN_ERROR(MAJOR, E_WRITE_FAILED,
+ ("UCode write error : write 0x%x, read 0x%x",
+ p_Fm->p_FmDriverParam->firmware.p_Code[i],tmp));
+ WRITE_UINT32(p_Iram->iadd, 0x0);
+ }
+
+ /* Enable patch from IRAM */
+ WRITE_UINT32(p_Iram->iready, IRAM_READY);
+ XX_UDelay(1000);
+
+ DBG(INFO, ("FMan-Controller code (ver %d.%d) loaded to IRAM.",
+ ((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[5],
+ ((uint8_t *)p_Fm->p_FmDriverParam->firmware.p_Code)[7]));
+
+ return E_OK;
+}
+
+static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
+{
+#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
+do { \
+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\
+} while (0)
+#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
+do { \
+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\
+} while (0)
+
+ /* error interrupts */
+ if (pending & ERR_INTR_EN_1G_MAC0)
+ FM_G_CALL_1G_MAC_ERR_ISR(0);
+ if (pending & ERR_INTR_EN_1G_MAC1)
+ FM_G_CALL_1G_MAC_ERR_ISR(1);
+ if (pending & ERR_INTR_EN_1G_MAC2)
+ FM_G_CALL_1G_MAC_ERR_ISR(2);
+ if (pending & ERR_INTR_EN_1G_MAC3)
+ FM_G_CALL_1G_MAC_ERR_ISR(3);
+ if (pending & ERR_INTR_EN_1G_MAC4)
+ FM_G_CALL_1G_MAC_ERR_ISR(4);
+ if (pending & ERR_INTR_EN_10G_MAC0)
+ FM_G_CALL_10G_MAC_ERR_ISR(0);
+}
+
+static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
+{
+#define FM_G_CALL_1G_MAC_TMR_ISR(_id) \
+do { \
+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].h_SrcHandle);\
+} while (0)
+
+ if (pending & INTR_EN_1G_MAC0_TMR)
+ FM_G_CALL_1G_MAC_TMR_ISR(0);
+ if (pending & INTR_EN_1G_MAC1_TMR)
+ FM_G_CALL_1G_MAC_TMR_ISR(1);
+ if (pending & INTR_EN_1G_MAC2_TMR)
+ FM_G_CALL_1G_MAC_TMR_ISR(2);
+ if (pending & INTR_EN_1G_MAC3_TMR)
+ FM_G_CALL_1G_MAC_TMR_ISR(3);
+ if (pending & INTR_EN_1G_MAC4_TMR)
+ FM_G_CALL_1G_MAC_TMR_ISR(4);
+ if(pending & INTR_EN_TMR)
+ p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
+}
+
+
+/****************************************/
+/* Inter-Module functions */
+/****************************************/
+static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
+ uint8_t *p_Msg,
+ uint32_t msgLength,
+ uint8_t *p_Reply,
+ uint32_t *p_ReplyLength)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
+
+ UNUSED(p_Reply);
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
+
+#ifdef DISABLE_SANITY_CHECKS
+ UNUSED(msgLength);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ ASSERT_COND(p_Msg);
+
+ *p_ReplyLength = 0;
+
+ switch(p_IpcMsg->msgId)
+ {
+ case (FM_GUEST_ISR):
+ {
+ t_FmIpcIsr ipcIsr;
+
+ memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
+ if(ipcIsr.boolErr)
+ GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
+ else
+ GuestEventIsr(p_Fm, ipcIsr.pendingReg);
+ break;
+ }
+ default:
+ *p_ReplyLength = 0;
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
+ }
+ return E_OK;
+}
+
+static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
+ uint8_t *p_Msg,
+ uint32_t msgLength,
+ uint8_t *p_Reply,
+ uint32_t *p_ReplyLength)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
+ t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
+
+#ifdef DISABLE_SANITY_CHECKS
+ UNUSED(msgLength);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ ASSERT_COND(p_IpcMsg);
+
+ memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
+ *p_ReplyLength = 0;
+
+ switch(p_IpcMsg->msgId)
+ {
+ case (FM_GET_SET_PORT_PARAMS):
+ {
+ t_FmIpcPortInInitParams ipcInitParams;
+ t_FmInterModulePortInitParams initParams;
+ t_FmIpcPhysAddr ipcPhysAddr;
+
+ memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
+ initParams.hardwarePortId = ipcInitParams.hardwarePortId;
+ initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
+ initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
+ initParams.liodnOffset = ipcInitParams.liodnOffset;
+ initParams.numOfTasks = ipcInitParams.numOfTasks;
+ initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
+ initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
+ initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
+ initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
+ initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
+ initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
+ initParams.liodnBase = ipcInitParams.liodnBase;
+
+ p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
+ ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
+ ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
+ break;
+ }
+ case (FM_SET_SIZE_OF_FIFO):
+ {
+ t_FmIpcPortFifoParams ipcPortFifoParams;
+ t_FmInterModulePortRxPoolsParams rxPoolsParams;
+
+ memcpy((uint8_t*)&ipcPortFifoParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFifoParams));
+ rxPoolsParams.numOfPools = ipcPortFifoParams.numOfPools;
+ rxPoolsParams.secondLargestBufSize = ipcPortFifoParams.secondLargestBufSize;
+ rxPoolsParams.largestBufSize = ipcPortFifoParams.largestBufSize;
+
+ p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm, ipcPortFifoParams.rsrcParams.hardwarePortId,
+ (e_FmPortType)ipcPortFifoParams.enumPortType,
+ (bool)ipcPortFifoParams.boolIndependentMode,
+ &ipcPortFifoParams.rsrcParams.val,
+ ipcPortFifoParams.rsrcParams.extra,
+ ipcPortFifoParams.deqPipelineDepth,
+ &rxPoolsParams,
+ (bool)ipcPortFifoParams.boolInitialConfig);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPortFifoParams.rsrcParams.val, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (FM_SET_NUM_OF_TASKS):
+ {
+ t_FmIpcPortRsrcParams ipcPortRsrcParams;
+
+ memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
+ p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
+ (uint8_t)ipcPortRsrcParams.val,
+ (uint8_t)ipcPortRsrcParams.extra,
+ (bool)ipcPortRsrcParams.boolInitialConfig);
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+ }
+ case (FM_SET_NUM_OF_OPEN_DMAS):
+ {
+ t_FmIpcPortRsrcParams ipcPortRsrcParams;
+
+ memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
+ p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
+ (uint8_t)ipcPortRsrcParams.val,
+ (uint8_t)ipcPortRsrcParams.extra,
+ (bool)ipcPortRsrcParams.boolInitialConfig);
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+ }
+ case (FM_RESUME_STALLED_PORT):
+ *p_ReplyLength = sizeof(uint32_t);
+ p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
+ break;
+ case (FM_MASTER_IS_ALIVE):
+ {
+ uint8_t guestId = p_IpcMsg->msgBody[0];
+ /* build the FM master partition IPC address */
+ memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
+ if(Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
+ if (p_Fm->h_IpcSessions[guestId] == NULL)
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
+ *(uint8_t*)(p_IpcReply->replyBody) = 1;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ }
+ case (FM_IS_PORT_STALLED):
+ {
+ bool tmp;
+
+ p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
+ *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ }
+ case (FM_RESET_MAC):
+ {
+ t_FmIpcMacParams ipcMacParams;
+
+ memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
+ p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
+ (e_FmMacType)(ipcMacParams.enumType),
+ ipcMacParams.id);
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+ }
+ case (FM_SET_MAC_MAX_FRAME):
+ {
+ t_Error err;
+ t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
+
+ memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
+ if ((err = FmSetMacMaxFrame(p_Fm,
+ (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
+ ipcMacMaxFrameParams.macParams.id,
+ ipcMacMaxFrameParams.maxFrameLength)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (FM_GET_CLK_FREQ):
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, sizeof(uint16_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
+ break;
+ case (FM_FREE_PORT):
+ {
+ t_FmInterModulePortFreeParams portParams;
+ t_FmIpcPortFreeParams ipcPortParams;
+
+ memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
+ portParams.hardwarePortId = ipcPortParams.hardwarePortId;
+ portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+ FmFreePortParams(h_Fm, &portParams);
+ break;
+ }
+ case (FM_REGISTER_INTR):
+ {
+ t_FmIpcRegisterIntr ipcRegIntr;
+
+ memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
+ p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
+ break;
+ }
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ case (FM_DUMP_REGS):
+ {
+ t_Error err;
+ if ((err = FM_DumpRegs(h_Fm)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (FM_DUMP_PORT_REGS):
+ {
+ t_Error err;
+
+ if ((err = FmDumpPortRegs(h_Fm, p_IpcMsg->msgBody[0])) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+#endif /* (defined(DEBUG_ERRORS) && ... */
+ case (FM_GET_REV):
+ {
+ t_FmRevisionInfo revInfo;
+ t_FmIpcRevisionInfo ipcRevInfo;
+
+ p_IpcReply->error = (uint32_t)FM_GetRevision(h_Fm, &revInfo);
+ ipcRevInfo.majorRev = revInfo.majorRev;
+ ipcRevInfo.minorRev = revInfo.minorRev;
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcRevisionInfo));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcRevisionInfo);
+ break;
+ }
+ case (FM_DMA_STAT):
+ {
+ t_FmDmaStatus dmaStatus;
+ t_FmIpcDmaStatus ipcDmaStatus;
+
+ FM_GetDmaStatus(h_Fm, &dmaStatus);
+ ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
+ ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
+ ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
+ ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
+ ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
+ break;
+ }
+ case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
+ p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ case (FM_FREE_FMAN_CTRL_EVENT_REG):
+ FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
+ break;
+ case (FM_GET_TIMESTAMP_SCALE):
+ {
+ uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
+
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (FM_GET_COUNTER):
+ {
+ e_FmCounters inCounter;
+ uint32_t outCounter;
+
+ memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
+ outCounter = FM_GetCounter(h_Fm, inCounter);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
+ {
+ t_FmIpcFmanEvents ipcFmanEvents;
+
+ memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
+ FmSetFmanCtrlIntr(h_Fm,
+ ipcFmanEvents.eventRegId,
+ ipcFmanEvents.enableEvents);
+ break;
+ }
+ case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
+ {
+ uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
+
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (FM_GET_PHYS_MURAM_BASE):
+ {
+ t_FmPhysAddr physAddr;
+ t_FmIpcPhysAddr ipcPhysAddr;
+
+ FmGetPhysicalMuramBase(h_Fm, &physAddr);
+ ipcPhysAddr.high = physAddr.high;
+ ipcPhysAddr.low = physAddr.low;
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
+ break;
+ }
+ case (FM_ENABLE_RAM_ECC):
+ {
+ t_Error err;
+
+ if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
+ ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
+ ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (FM_DISABLE_RAM_ECC):
+ {
+ t_Error err;
+
+ if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
+ ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
+ ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (FM_SET_NUM_OF_FMAN_CTRL):
+ {
+ t_Error err;
+ t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
+
+ memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
+ if ((err = FmSetNumOfRiscsPerPort(h_Fm,
+ ipcPortNumOfFmanCtrls.hardwarePortId,
+ ipcPortNumOfFmanCtrls.numOfFmanCtrls)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+ case (FM_10G_TX_ECC_WA):
+ p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
+ *p_ReplyLength = sizeof(uint32_t);
+ break;
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+ default:
+ *p_ReplyLength = 0;
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
+ }
+ return E_OK;
+}
+
+static void ErrorIsrCB(t_Handle h_Fm)
+{
+#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
+ { \
+ if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
+ SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
+ else \
+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\
+ }
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t pending;
+
+ SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE);
+
+ /* error interrupts */
+ pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmepi);
+ if (!pending)
+ return;
+
+ if(pending & ERR_INTR_EN_BMI)
+ BmiErrEvent(p_Fm);
+ if(pending & ERR_INTR_EN_QMI)
+ QmiErrEvent(p_Fm);
+ if(pending & ERR_INTR_EN_FPM)
+ FpmErrEvent(p_Fm);
+ if(pending & ERR_INTR_EN_DMA)
+ DmaErrEvent(p_Fm);
+ if(pending & ERR_INTR_EN_IRAM)
+ IramErrIntr(p_Fm);
+ if(pending & ERR_INTR_EN_MURAM)
+ MuramErrIntr(p_Fm);
+ if(pending & ERR_INTR_EN_PRS)
+ p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
+ if(pending & ERR_INTR_EN_PLCR)
+ p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
+ if(pending & ERR_INTR_EN_KG)
+ p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
+
+ /* MAC events may belong to different partitions */
+ if(pending & ERR_INTR_EN_1G_MAC0)
+ FM_M_CALL_1G_MAC_ERR_ISR(0);
+ if(pending & ERR_INTR_EN_1G_MAC1)
+ FM_M_CALL_1G_MAC_ERR_ISR(1);
+ if(pending & ERR_INTR_EN_1G_MAC2)
+ FM_M_CALL_1G_MAC_ERR_ISR(2);
+ if(pending & ERR_INTR_EN_1G_MAC3)
+ FM_M_CALL_1G_MAC_ERR_ISR(3);
+ if(pending & ERR_INTR_EN_1G_MAC4)
+ FM_M_CALL_1G_MAC_ERR_ISR(4);
+ if(pending & ERR_INTR_EN_10G_MAC0)
+ {
+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].guestId)
+ SendIpcIsr(p_Fm, e_FM_EV_ERR_10G_MAC0, pending);
+ else
+ p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_10G_MAC0].h_SrcHandle);
+ }
+}
+
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ int timeout = 1000;
+ t_Error err = E_OK;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+ uint8_t rxHardwarePortId, txHardwarePortId;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_10G_TX_ECC_WA;
+ msg.msgBody[0] = macId;
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(macId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return (t_Error)(reply.error);
+ }
+
+ SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
+ SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
+
+ SW_PORT_ID_TO_HW_PORT_ID(rxHardwarePortId, e_FM_PORT_TYPE_RX_10G, macId);
+ SW_PORT_ID_TO_HW_PORT_ID(txHardwarePortId, e_FM_PORT_TYPE_TX_10G, macId);
+ if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
+ (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE,
+ ("MAC should be initialized prior to rx and tx ports!"));
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmextc, 0x40000000);
+ CORE_MemoryBarrier();
+ while ((GET_UINT32(p_Fm->p_FmFpmRegs->fpmextc) & 0x40000000) &&
+ --timeout) ;
+ if (!timeout)
+ return ERROR_CODE(E_TIMEOUT);
+ return E_OK;
+}
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
+
+ return (p_Fm->baseAddr + FM_MM_PRS);
+}
+
+uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
+
+ return (p_Fm->baseAddr + FM_MM_KG);
+}
+
+uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Guset"));
+
+ return (p_Fm->baseAddr + FM_MM_PLCR);
+}
+
+t_Handle FmGetMuramHandle(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
+
+ return (p_Fm->h_FmMuram);
+}
+
+void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+ t_FmIpcPhysAddr ipcPhysAddr;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_GET_PHYS_MURAM_BASE;
+ replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ {
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return;
+ }
+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
+ return;
+ }
+ memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
+ p_FmPhysAddr->high = ipcPhysAddr.high;
+ p_FmPhysAddr->low = ipcPhysAddr.low;
+ return ;
+ }
+
+ /* General FM driver initialization */
+ p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
+ p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
+}
+
+t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint8_t i;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
+ replyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ *p_EventId = *(uint8_t*)(reply.replyBody);
+
+ return (t_Error)(reply.error);
+ }
+
+ for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
+ if (!p_Fm->usedEventRegs[i])
+ {
+ p_Fm->usedEventRegs[i] = TRUE;
+ *p_EventId = i;
+ break;
+ }
+
+ if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
+ RETURN_ERROR(MAJOR, E_BUSY, ("No resource - Fman controller event register."));
+
+ return E_OK;
+}
+
+void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_Error err;
+ t_FmIpcMsg msg;
+
+ if(((t_Fm *)h_Fm)->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
+ msg.msgBody[0] = eventId;
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(eventId),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return;
+ }
+
+ ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
+}
+
+void FmRegisterIntr(t_Handle h_Fm,
+ e_FmEventModules module,
+ uint8_t modId,
+ e_FmIntrType intrType,
+ void (*f_Isr) (t_Handle h_Arg),
+ t_Handle h_Arg)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint8_t event= 0;
+ t_FmIpcRegisterIntr fmIpcRegisterIntr;
+ t_Error err;
+ t_FmIpcMsg msg;
+
+ ASSERT_COND(h_Fm);
+
+ GET_FM_MODULE_EVENT(module, modId,intrType, event);
+
+ /* register in local FM structure */
+ ASSERT_COND(event != e_FM_EV_DUMMY_LAST);
+ p_Fm->intrMng[event].f_Isr = f_Isr;
+ p_Fm->intrMng[event].h_SrcHandle = h_Arg;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ if(p_Fm->h_IpcSessions[0])
+ {
+ /* register in Master FM structure */
+ fmIpcRegisterIntr.event = event;
+ fmIpcRegisterIntr.guestId = p_Fm->guestId;
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_REGISTER_INTR;
+ memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ }
+ else
+ DBG(WARNING,("'Register interrupt' - unavailable - No IPC"));
+ }
+
+}
+
+void FmUnregisterIntr(t_Handle h_Fm,
+ e_FmEventModules module,
+ uint8_t modId,
+ e_FmIntrType intrType)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint8_t event= 0;
+
+ ASSERT_COND(h_Fm);
+
+ GET_FM_MODULE_EVENT(module, modId,intrType, event);
+
+ ASSERT_COND(event != e_FM_EV_DUMMY_LAST);
+ p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
+ p_Fm->intrMng[event].h_SrcHandle = NULL;
+}
+
+void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_FmIpcFmanEvents fmanCtrl;
+ t_Error err;
+ t_FmIpcMsg msg;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ fmanCtrl.eventRegId = eventRegId;
+ fmanCtrl.enableEvents = enableEvents;
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
+ memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(fmanCtrl),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return;
+ }
+
+ ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId], enableEvents);
+}
+
+uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength, ctrlIntr;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
+ msg.msgBody[0] = eventRegId;
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(eventRegId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ {
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return 0;
+ }
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ {
+ REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return 0;
+ }
+ memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
+ return ctrlIntr;
+ }
+
+ return GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[eventRegId]);
+}
+
+void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ ASSERT_COND(0);
+ /* TODO */
+ }
+
+ p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
+ p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
+}
+
+void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ ASSERT_COND(0);
+ /* TODO */
+ }
+
+ p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
+ p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
+}
+
+void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ if(p_Fm->h_Pcd)
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
+
+ p_Fm->h_Pcd = h_FmPcd;
+
+}
+
+void FmUnregisterPcd(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ if(!p_Fm->h_Pcd)
+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("No PCD"));
+
+ p_Fm->h_Pcd = NULL;
+
+}
+
+t_Handle FmGetPcdHandle(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ return p_Fm->h_Pcd;
+}
+
+uint8_t FmGetId(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
+
+ return p_Fm->p_FmStateStruct->fmId;
+}
+
+t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls)
+{
+
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg = 0;
+ t_Error err;
+ t_FmIpcPortNumOfFmanCtrls params;
+ t_FmIpcMsg msg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ params.hardwarePortId = hardwarePortId;
+ params.numOfFmanCtrls = numOfFmanCtrls;
+ msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
+ memcpy(msg.msgBody, &params, sizeof(params));
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(params),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ return E_OK;
+ }
+
+ XX_LockSpinlock(p_Fm->h_Spinlock);
+
+ tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT);
+
+ /*TODO - maybe to put CTL# according to another criteria*/
+
+ if(numOfFmanCtrls == 2)
+ tmpReg = FPM_PORT_FM_CTL2 | FPM_PORT_FM_CTL1;
+
+ /* order restoration */
+ if(hardwarePortId%2)
+ tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL1;
+ else
+ tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PORT_FM_CTL2;
+
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+
+ return E_OK;
+}
+
+t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+ uint8_t hardwarePortId = p_PortParams->hardwarePortId;
+ t_FmIpcPortInInitParams portInParams;
+ t_FmIpcPhysAddr ipcPhysAddr;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ portInParams.hardwarePortId = p_PortParams->hardwarePortId;
+ portInParams.enumPortType = (uint32_t)p_PortParams->portType;
+ portInParams.boolIndependentMode = (uint8_t)p_PortParams->independentMode;
+ portInParams.liodnOffset = p_PortParams->liodnOffset;
+ portInParams.numOfTasks = p_PortParams->numOfTasks;
+ portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
+ portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
+ portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
+ portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
+ portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
+ portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
+ portInParams.liodnBase = p_PortParams->liodnBase;
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_GET_SET_PORT_PARAMS;
+ memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
+ replyLength = (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr));
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(portInParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(p_PortParams->fmMuramPhysBaseAddr)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
+ p_PortParams->fmMuramPhysBaseAddr.high = ipcPhysAddr.high;
+ p_PortParams->fmMuramPhysBaseAddr.low = ipcPhysAddr.low;
+
+ return (t_Error)(reply.error);
+ }
+
+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
+ XX_LockSpinlock(p_Fm->h_Spinlock);
+
+ if(p_PortParams->independentMode)
+ {
+ /* set port parameters */
+ p_Fm->independentMode = p_PortParams->independentMode;
+ /* disable dispatch limit */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, 0);
+ }
+
+ if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ {
+ if(p_Fm->hcPortInitialized)
+ {
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
+ }
+ else
+ p_Fm->hcPortInitialized = TRUE;
+ }
+ p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
+
+ err = FmSetNumOfTasks(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfTasks, p_PortParams->numOfExtraTasks, TRUE);
+ if(err)
+ {
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
+ /* for transmit & O/H ports */
+ {
+ uint8_t enqTh;
+ uint8_t deqTh;
+ bool update = FALSE;
+
+ /* update qmi ENQ/DEQ threshold */
+ p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc);
+ enqTh = (uint8_t)(tmpReg>>8);
+ /* if enqTh is too big, we reduce it to the max value that is still OK */
+ if(enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
+ {
+ enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
+ tmpReg &= ~QMI_CFG_ENQ_MASK;
+ tmpReg |= ((uint32_t)enqTh << 8);
+ update = TRUE;
+ }
+
+ deqTh = (uint8_t)tmpReg;
+ /* if deqTh is too small, we enlarge it to the min value that is still OK.
+ deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
+ if((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
+ {
+ deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
+ tmpReg &= ~QMI_CFG_DEQ_MASK;
+ tmpReg |= (uint32_t)deqTh;
+ update = TRUE;
+ }
+ if(update)
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg);
+ }
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+#ifdef FM_LOW_END_RESTRICTION
+ if((hardwarePortId==0x1) || (hardwarePortId==0x29))
+ {
+ if(p_Fm->p_FmStateStruct->lowEndRestriction)
+ {
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
+ }
+ else
+ p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
+ }
+#endif /* FM_LOW_END_RESTRICTION */
+
+ err = FmSetSizeOfFifo(p_Fm,
+ p_PortParams->hardwarePortId,
+ p_PortParams->portType,
+ p_PortParams->independentMode,
+ &p_PortParams->sizeOfFifo,
+ p_PortParams->extraSizeOfFifo,
+ p_PortParams->deqPipelineDepth,
+ NULL,
+ TRUE);
+ if(err)
+ {
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ err = FmSetNumOfOpenDmas(p_Fm, p_PortParams->hardwarePortId, p_PortParams->numOfOpenDmas, p_PortParams->numOfExtraOpenDmas, TRUE);
+ if(err)
+ {
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], (uint32_t)p_PortParams->liodnOffset);
+
+ tmpReg = (uint32_t)(hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT);
+ if(p_PortParams->independentMode)
+ {
+ if((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G))
+ tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL1;
+ else
+ tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) |FPM_PORT_FM_CTL2;
+ }
+ else
+ {
+ tmpReg |= (FPM_PORT_FM_CTL2|FPM_PORT_FM_CTL1);
+
+ /* order restoration */
+ if(hardwarePortId%2)
+ tmpReg |= (FPM_PORT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
+ else
+ tmpReg |= (FPM_PORT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
+ }
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
+
+ {
+#ifdef FM_PARTITION_ARRAY
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_Fm, &revInfo);
+ if (revInfo.majorRev >= 2)
+#endif /* FM_PARTITION_ARRAY */
+ {
+ /* set LIODN base for this port */
+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2]);
+ if(hardwarePortId%2)
+ {
+ tmpReg &= ~FM_LIODN_BASE_MASK;
+ tmpReg |= (uint32_t)p_PortParams->liodnBase;
+ }
+ else
+ {
+ tmpReg &= ~(FM_LIODN_BASE_MASK<< DMA_LIODN_SHIFT);
+ tmpReg |= (uint32_t)p_PortParams->liodnBase << DMA_LIODN_SHIFT;
+ }
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], tmpReg);
+ }
+ }
+
+ FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+
+ return E_OK;
+}
+
+void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+ uint8_t hardwarePortId = p_PortParams->hardwarePortId;
+ uint8_t numOfTasks;
+ t_Error err;
+ t_FmIpcPortFreeParams portParams;
+ t_FmIpcMsg msg;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ portParams.hardwarePortId = p_PortParams->hardwarePortId;
+ portParams.enumPortType = (uint32_t)p_PortParams->portType;
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_FREE_PORT;
+ memcpy(msg.msgBody, &portParams, sizeof(portParams));
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(portParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return;
+ }
+
+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
+ XX_LockSpinlock(p_Fm->h_Spinlock);
+
+
+ if(p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
+ {
+ ASSERT_COND(p_Fm->hcPortInitialized);
+ p_Fm->hcPortInitialized = FALSE;
+ }
+
+ p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
+
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
+ /* free numOfTasks */
+ numOfTasks = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1);
+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
+
+ /* free numOfOpenDmas */
+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= ((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= (((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
+
+ /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
+ tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg);
+
+ /* free sizeOfFifo */
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]);
+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >=
+ (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS));
+ p_Fm->p_FmStateStruct->accumulatedFifoSize -=
+ (((tmpReg & BMI_FIFO_SIZE_MASK) + 1) * BMI_FIFO_UNITS);
+
+ /* clear registers */
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], 0);
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], 0);
+ /* WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], 0); */
+
+#ifdef FM_PORT_DISABLED_ERRATA_FMANx9
+ /* this errata means that when a port is taken down, other port may not use its
+ * resources for a while as it may still be using it (in case of reject).
+ */
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ XX_UDelay(100000);
+ }
+#endif /* FM_PORT_DISABLED_ERRATA_FMANx9 */
+
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ if((p_PortParams->portType != e_FM_PORT_TYPE_RX) && (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
+ /* for transmit & O/H ports */
+ {
+ uint8_t enqTh;
+ uint8_t deqTh;
+
+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc);
+ /* update qmi ENQ/DEQ threshold */
+ p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
+
+ /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
+ so we can enlarge enqTh */
+ enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
+ tmpReg &= ~QMI_CFG_ENQ_MASK;
+ tmpReg |= ((uint32_t)enqTh << QMI_CFG_ENQ_SHIFT);
+
+ /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
+ so we can reduce deqTh */
+ deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
+ tmpReg &= ~QMI_CFG_DEQ_MASK;
+ tmpReg |= (uint32_t)deqTh;
+
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, tmpReg);
+ }
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+#ifdef FM_LOW_END_RESTRICTION
+ if((hardwarePortId==0x1) || (hardwarePortId==0x29))
+ p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
+#endif /* FM_LOW_END_RESTRICTION */
+ XX_UnlockSpinlock(p_Fm->h_Spinlock);
+}
+
+t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_IS_PORT_STALLED;
+ msg.msgBody[0] = hardwarePortId;
+ replyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(hardwarePortId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
+
+ return (t_Error)(reply.error);
+ }
+
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
+ *p_IsStalled = (bool)!!(tmpReg & FPM_PS_STALLED);
+
+ return E_OK;
+}
+
+t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+ t_Error err;
+ bool isStalled;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_RESUME_STALLED_PORT;
+ msg.msgBody[0] = hardwarePortId;
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(hardwarePortId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return (t_Error)(reply.error);
+ }
+
+ /* Get port status */
+ err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
+ if(err)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
+ if (!isStalled)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port is not stalled"));
+
+ tmpReg = (uint32_t)((hardwarePortId << FPM_PORT_FM_CTL_PORTID_SHIFT) | FPM_PRC_REALSE_STALLED);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmpr, tmpReg);
+
+ return E_OK;
+}
+
+t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t bitMask, timeout = 1000;
+ t_FmIpcMacParams macParams;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ if(p_Fm->h_IpcSessions[0])
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ macParams.id = macId;
+ macParams.enumType = (uint32_t)type;
+ msg.msgId = FM_RESET_MAC;
+ memcpy(msg.msgBody, &macParams, sizeof(macParams));
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(macParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return (t_Error)(reply.error);
+ }
+ else
+ if(!p_Fm->p_FmFpmRegs)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("No IPC and no registers address"));
+ }
+
+ /* Get the relevant bit mask */
+ if (type == e_FM_MAC_10G)
+ {
+ switch(macId)
+ {
+ case(0):
+ bitMask = FPM_RSTC_10G0_RESET;
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id"));
+ }
+ }
+ else
+ {
+ switch(macId)
+ {
+ case(0):
+ bitMask = FPM_RSTC_1G0_RESET;
+ break;
+ case(1):
+ bitMask = FPM_RSTC_1G1_RESET;
+ break;
+ case(2):
+ bitMask = FPM_RSTC_1G2_RESET;
+ break;
+ case(3):
+ bitMask = FPM_RSTC_1G3_RESET;
+ break;
+ case(4):
+ bitMask = FPM_RSTC_1G4_RESET;
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Illegal MAC Id"));
+ }
+ }
+
+ /* reset */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, bitMask);
+ while ((GET_UINT32(p_Fm->p_FmFpmRegs->fmrstc) & bitMask) &&
+ --timeout) ;
+ if (!timeout)
+ return ERROR_CODE(E_TIMEOUT);
+ return E_OK;
+}
+
+t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
+ t_Error err;
+ t_FmIpcMsg msg;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ macMaxFrameLengthParams.macParams.id = macId;
+ macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
+ macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
+ msg.msgId = FM_SET_MAC_MAX_FRAME;
+ memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ return E_OK;
+ }
+
+#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
+ if (type == e_FM_MAC_10G)
+ p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
+ else
+#else
+ UNUSED(type);
+#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
+ p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
+
+ return E_OK;
+}
+
+uint16_t FmGetClockFreq(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ /* for MC environment: this depends on the
+ * fact that fmClkFreq was properly initialized at "init". */
+ return p_Fm->p_FmStateStruct->fmClkFreq;
+}
+
+uint32_t FmGetTimeStampScale(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength, timeStamp;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_GET_TIMESTAMP_SCALE;
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
+ return timeStamp;
+ }
+
+ if(!p_Fm->p_FmStateStruct->enabledTimeStamp)
+ FmEnableTimeStamp(p_Fm);
+
+ return p_Fm->p_FmStateStruct->count1MicroBit;
+}
+
+bool FmRamsEccIsExternalCtl(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
+ if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+t_Error FmEnableRamsEcc(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ p_Fm->p_FmStateStruct->ramsEccOwners++;
+ p_Fm->p_FmStateStruct->internalCall = TRUE;
+
+ return FM_EnableRamsEcc(p_Fm);
+}
+
+t_Error FmDisableRamsEcc(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
+ p_Fm->p_FmStateStruct->ramsEccOwners--;
+
+ if(p_Fm->p_FmStateStruct->ramsEccOwners==0)
+ {
+ p_Fm->p_FmStateStruct->internalCall = TRUE;
+ return FM_DisableRamsEcc(p_Fm);
+ }
+ return E_OK;
+}
+
+uint8_t FmGetGuestId(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ return p_Fm->guestId;
+}
+
+bool FmIsMaster(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ return (p_Fm->guestId == NCSW_MASTER_ID);
+}
+
+t_Error FmSetSizeOfFifo(t_Handle h_Fm,
+ uint8_t hardwarePortId,
+ e_FmPortType portType,
+ bool independentMode,
+ uint32_t *p_SizeOfFifo,
+ uint32_t extraSizeOfFifo,
+ uint8_t deqPipelineDepth,
+ t_FmInterModulePortRxPoolsParams *p_RxPoolsParams,
+ bool initialConfig)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint8_t relativePortId;
+ uint16_t macMaxFrameLength = 0, oldVal;
+ uint32_t minFifoSizeRequired = 0, sizeOfFifo, tmpReg = 0;
+ t_FmIpcPortFifoParams fifoParams;
+ t_Error err;
+
+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
+ ASSERT_COND(initialConfig || p_RxPoolsParams);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ ASSERT_COND(p_RxPoolsParams);
+
+ memset(&fifoParams, 0, sizeof(fifoParams));
+ fifoParams.rsrcParams.hardwarePortId = hardwarePortId;
+ fifoParams.rsrcParams.val = *p_SizeOfFifo;
+ fifoParams.rsrcParams.extra = extraSizeOfFifo;
+ fifoParams.enumPortType = (uint32_t)portType;
+ fifoParams.boolIndependentMode = (uint8_t)independentMode;
+ fifoParams.deqPipelineDepth = deqPipelineDepth;
+ fifoParams.numOfPools = p_RxPoolsParams->numOfPools;
+ fifoParams.secondLargestBufSize = p_RxPoolsParams->secondLargestBufSize;
+ fifoParams.largestBufSize = p_RxPoolsParams->largestBufSize;
+ fifoParams.boolInitialConfig = (uint8_t)initialConfig;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_SET_SIZE_OF_FIFO;
+ memcpy(msg.msgBody, &fifoParams, sizeof(fifoParams));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(fifoParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ memcpy((uint8_t*)p_SizeOfFifo, reply.replyBody, sizeof(uint32_t));
+
+ return (t_Error)(reply.error);
+ }
+ sizeOfFifo = *p_SizeOfFifo;
+ /* if neseccary (cases where frame length is relevant), update sizeOfFifo field. */
+ if((portType == e_FM_PORT_TYPE_TX) || ((portType == e_FM_PORT_TYPE_RX) && independentMode))
+ {
+ HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
+ ASSERT_COND(relativePortId < FM_MAX_NUM_OF_1G_MACS);
+ macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths1G[relativePortId];
+ }
+
+#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
+ if((portType == e_FM_PORT_TYPE_TX_10G) || ((portType == e_FM_PORT_TYPE_RX_10G) && independentMode))
+ {
+ HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
+ ASSERT_COND(relativePortId < FM_MAX_NUM_OF_10G_MACS);
+ macMaxFrameLength = p_Fm->p_FmStateStruct->macMaxFrameLengths10G[relativePortId];
+ }
+#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
+
+ /*************************/
+ /* TX PORTS */
+ /*************************/
+ if((portType == e_FM_PORT_TYPE_TX) || (portType == e_FM_PORT_TYPE_TX_10G))
+ {
+ if(independentMode)
+ minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ?
+ (macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS :
+ macMaxFrameLength) +
+ (3*BMI_FIFO_UNITS));
+ else
+ minFifoSizeRequired = (uint32_t)((macMaxFrameLength % BMI_FIFO_UNITS ?
+ (macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS :
+ macMaxFrameLength) +
+ (deqPipelineDepth+3)*BMI_FIFO_UNITS);
+ }
+ /*************************/
+ /* RX IM PORTS */
+ /*************************/
+ else if(((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && independentMode)
+ minFifoSizeRequired = (uint32_t)(((macMaxFrameLength % BMI_FIFO_UNITS) ?
+ ((macMaxFrameLength/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
+ macMaxFrameLength) +
+ (4*BMI_FIFO_UNITS));
+
+ /* for Rx (non-Im) ports or OP, buffer pools are relevant for fifo size.
+ If this routine is called as part of the "GetSet" routine, initialConfig is TRUE
+ and these checks where done in the port routine.
+ If it is called by an explicit user request ("SetSizeOfFifo"), than these parameters
+ should be checked/updated */
+ if(!initialConfig &&
+ ((portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
+ (((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G)) && !independentMode)))
+ {
+ if((portType == e_FM_PORT_TYPE_RX) || (portType == e_FM_PORT_TYPE_RX_10G))
+ {
+ /*************************/
+ /* RX non-IM PORTS */
+ /*************************/
+#ifdef FM_FIFO_ALLOCATION_OLD_ALG
+ t_FmRevisionInfo revInfo;
+
+ FM_GetRevision(p_Fm, &revInfo);
+ if(revInfo.majorRev != 4)
+ minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->largestBufSize % BMI_FIFO_UNITS) ?
+ ((p_RxPoolsParams->largestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
+ p_RxPoolsParams->largestBufSize) +
+ (7*BMI_FIFO_UNITS));
+ else
+#endif /* FM_FIFO_ALLOCATION_OLD_ALG */
+ {
+ if(p_RxPoolsParams->numOfPools == 1)
+ minFifoSizeRequired = 8*BMI_FIFO_UNITS;
+ else
+ {
+ minFifoSizeRequired = (uint32_t)(((p_RxPoolsParams->secondLargestBufSize % BMI_FIFO_UNITS) ?
+ ((p_RxPoolsParams->secondLargestBufSize/BMI_FIFO_UNITS + 1) * BMI_FIFO_UNITS) :
+ p_RxPoolsParams->secondLargestBufSize) +
+ (7*BMI_FIFO_UNITS));
+ if((sizeOfFifo < minFifoSizeRequired))
+ {
+ DBG(WARNING, ("User set FIFO size for Rx port is not optimized. (not modified by driver)"));
+ minFifoSizeRequired = 8*BMI_FIFO_UNITS;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*************************/
+ /* OP PORTS */
+ /*************************/
+ /* check if pool size is not too big */
+ if(p_RxPoolsParams->largestBufSize > sizeOfFifo )
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Largest pool size is bigger than ports committed fifo size"));
+ }
+ }
+
+
+ if (minFifoSizeRequired && (sizeOfFifo < minFifoSizeRequired))
+ {
+ sizeOfFifo = minFifoSizeRequired;
+ DBG(WARNING, ("FIFO size enlarged to %d for port %#x", minFifoSizeRequired, hardwarePortId));
+ }
+
+ if(initialConfig)
+ oldVal = 0;
+ else
+ {
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1]);
+ /* read into oldVal the current extra fifo size */
+ oldVal = (uint16_t)((((tmpReg & BMI_EXTRA_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS) >> BMI_EXTRA_FIFO_SIZE_SHIFT);
+ }
+
+ if(extraSizeOfFifo > oldVal)
+ p_Fm->p_FmStateStruct->extraFifoPoolSize = NCSW_MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
+
+ if(!initialConfig)
+ /* read into oldVal the current num of tasks */
+ oldVal = (uint16_t)(((tmpReg & BMI_FIFO_SIZE_MASK) + 1)*BMI_FIFO_UNITS);
+
+ /* check that there are enough uncommitted fifo size */
+ if((p_Fm->p_FmStateStruct->accumulatedFifoSize - oldVal + sizeOfFifo) >
+ (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize))
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Requested fifo size and extra size exceed total FIFO size."));
+ else
+ {
+ /* update acummulated */
+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= oldVal);
+ p_Fm->p_FmStateStruct->accumulatedFifoSize -= oldVal;
+ p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
+ /* calculate reg */
+ tmpReg = (uint32_t)((sizeOfFifo/BMI_FIFO_UNITS - 1) |
+ ((extraSizeOfFifo/BMI_FIFO_UNITS) << BMI_EXTRA_FIFO_SIZE_SHIFT));
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], tmpReg);
+ }
+ *p_SizeOfFifo = sizeOfFifo;
+
+ return E_OK;
+}
+
+t_Error FmSetNumOfTasks(t_Handle h_Fm,
+ uint8_t hardwarePortId,
+ uint8_t numOfTasks,
+ uint8_t numOfExtraTasks,
+ bool initialConfig)
+{
+ t_Fm *p_Fm = (t_Fm *)h_Fm;
+ uint8_t oldVal;
+ uint32_t tmpReg = 0;
+ t_FmIpcPortRsrcParams rsrcParams;
+ t_Error err;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ rsrcParams.hardwarePortId = hardwarePortId;
+ rsrcParams.val = numOfTasks;
+ rsrcParams.extra = numOfExtraTasks;
+ rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_SET_NUM_OF_TASKS;
+ memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(rsrcParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return (t_Error)(reply.error);
+ }
+
+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
+
+ if(initialConfig)
+ oldVal = 0;
+ else
+ {
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
+ /* read into oldVal the current extra tasks */
+ oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_TASKS_MASK) >> BMI_EXTRA_NUM_OF_TASKS_SHIFT);
+ }
+
+ if(numOfExtraTasks > oldVal)
+ p_Fm->p_FmStateStruct->extraTasksPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
+
+ if(!initialConfig)
+ /* read into oldVal the current num of tasks */
+ oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_TASKS_MASK) >> BMI_NUM_OF_TASKS_SHIFT) + 1);
+
+ /* check that there are enough uncommitted tasks */
+ if((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - oldVal + numOfTasks) >
+ (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
+ ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
+ p_Fm->p_FmStateStruct->fmId));
+ else
+ {
+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= oldVal);
+ /* update acummulated */
+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= oldVal;
+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
+ /* calculate reg */
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
+ tmpReg |= (uint32_t)(((numOfTasks-1) << BMI_NUM_OF_TASKS_SHIFT) |
+ (numOfExtraTasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1],tmpReg);
+ }
+
+ return E_OK;
+}
+
+t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
+ uint8_t hardwarePortId,
+ uint8_t numOfOpenDmas,
+ uint8_t numOfExtraOpenDmas,
+ bool initialConfig)
+
+{
+ t_Fm *p_Fm = (t_Fm *)h_Fm;
+ uint8_t oldVal;
+ uint32_t tmpReg = 0;
+ t_FmIpcPortRsrcParams rsrcParams;
+ t_Error err;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ rsrcParams.hardwarePortId = hardwarePortId;
+ rsrcParams.val = numOfOpenDmas;
+ rsrcParams.extra = numOfExtraOpenDmas;
+ rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
+ memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
+ replyLength = sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(rsrcParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != sizeof(uint32_t))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return (t_Error)(reply.error);
+ }
+
+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
+
+ if(initialConfig)
+ oldVal = 0;
+ else
+ {
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]);
+ /* read into oldVal the current extra tasks */
+ oldVal = (uint8_t)((tmpReg & BMI_NUM_OF_EXTRA_DMAS_MASK) >> BMI_EXTRA_NUM_OF_DMAS_SHIFT);
+ }
+
+ if(numOfExtraOpenDmas > oldVal)
+ p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = (uint8_t)NCSW_MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
+
+ if(!initialConfig)
+ /* read into oldVal the current num of tasks */
+ oldVal = (uint8_t)(((tmpReg & BMI_NUM_OF_DMAS_MASK) >> BMI_NUM_OF_DMAS_SHIFT) + 1);
+
+ /* check that there are enough uncommitted open DMA's */
+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= oldVal);
+ if((p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - oldVal + numOfOpenDmas) >
+ p_Fm->p_FmStateStruct->maxNumOfOpenDmas)
+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
+ ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
+ p_Fm->p_FmStateStruct->fmId));
+ else
+ {
+ /* update acummulated */
+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= oldVal;
+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
+ /* calculate reg */
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1]) & ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
+ tmpReg |= (uint32_t)(((numOfOpenDmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
+ (numOfExtraOpenDmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], tmpReg);
+
+ /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
+ tmpReg |= (uint32_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize - 1) << BMI_CFG2_DMAS_SHIFT;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg);
+ }
+
+ return E_OK;
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FmDumpPortRegs (t_Handle h_Fm,uint8_t hardwarePortId)
+{
+ t_Fm *p_Fm = (t_Fm *)h_Fm;
+ t_FmIpcMsg msg;
+ t_Error err;
+
+ DECLARE_DUMP;
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_DUMP_PORT_REGS;
+ msg.msgBody[0] = hardwarePortId;
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(hardwarePortId),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ return E_OK;
+ }
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
+
+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
+
+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], ("bm_ppid for port %u", (hardwarePortId)));
+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_ppid[hardwarePortId-1], sizeof(uint32_t));
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
+
+
+/*****************************************************************************/
+/* API Init unit functions */
+/*****************************************************************************/
+t_Handle FM_Config(t_FmParams *p_FmParam)
+{
+ t_Fm *p_Fm;
+ uint8_t i;
+ uintptr_t baseAddr;
+
+ SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
+ SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
+ (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
+ E_INVALID_VALUE, NULL);
+
+ baseAddr = p_FmParam->baseAddr;
+
+ /* Allocate FM structure */
+ p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
+ if (!p_Fm)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
+ return NULL;
+ }
+ memset(p_Fm, 0, sizeof(t_Fm));
+
+ p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
+ if (!p_Fm->p_FmStateStruct)
+ {
+ XX_Free(p_Fm);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
+ return NULL;
+ }
+ memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
+
+ /* Initialize FM parameters which will be kept by the driver */
+ p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
+ p_Fm->guestId = p_FmParam->guestId;
+
+ for(i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
+ p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
+
+ /* Allocate the FM driver's parameters structure */
+ p_Fm->p_FmDriverParam = (t_FmDriverParam *)XX_Malloc(sizeof(t_FmDriverParam));
+ if (!p_Fm->p_FmDriverParam)
+ {
+ XX_Free(p_Fm->p_FmStateStruct);
+ XX_Free(p_Fm);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
+ return NULL;
+ }
+ memset(p_Fm->p_FmDriverParam, 0, sizeof(t_FmDriverParam));
+
+ /* Initialize FM parameters which will be kept by the driver */
+ p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
+ p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
+ p_Fm->h_App = p_FmParam->h_App;
+ p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
+ p_Fm->f_Exception = p_FmParam->f_Exception;
+ p_Fm->f_BusError = p_FmParam->f_BusError;
+ p_Fm->p_FmFpmRegs = (t_FmFpmRegs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
+ p_Fm->p_FmBmiRegs = (t_FmBmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
+ p_Fm->p_FmQmiRegs = (t_FmQmiRegs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
+ p_Fm->p_FmDmaRegs = (t_FmDmaRegs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
+ p_Fm->baseAddr = baseAddr;
+ p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
+ p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
+ p_Fm->hcPortInitialized = FALSE;
+ p_Fm->independentMode = FALSE;
+ p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
+ p_Fm->p_FmStateStruct->totalNumOfTasks = DEFAULT_totalNumOfTasks;
+ p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize;
+ p_Fm->p_FmStateStruct->maxNumOfOpenDmas = DEFAULT_maxNumOfOpenDmas;
+ p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
+ p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
+ for(i = 0;i<FM_MAX_NUM_OF_1G_MACS;i++)
+ p_Fm->p_FmStateStruct->macMaxFrameLengths1G[i] = DEFAULT_mtu;
+#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
+ for(i = 0;i<FM_MAX_NUM_OF_10G_MACS;i++)
+ p_Fm->p_FmStateStruct->macMaxFrameLengths10G[i] = DEFAULT_mtu;
+#endif /*defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)*/
+
+ p_Fm->h_Spinlock = XX_InitSpinlock();
+ if (!p_Fm->h_Spinlock)
+ {
+ XX_Free(p_Fm->p_FmDriverParam);
+ XX_Free(p_Fm->p_FmStateStruct);
+ XX_Free(p_Fm);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("cant allocate spinlock!"));
+ return NULL;
+ }
+
+#ifdef FM_PARTITION_ARRAY
+ /* Initialize FM driver parameters parameters (for initialization phase only) */
+ memcpy(p_Fm->p_FmDriverParam->liodnBasePerPort, p_FmParam->liodnBasePerPort, FM_SIZE_OF_LIODN_TABLE*sizeof(uint16_t));
+#endif /* FM_PARTITION_ARRAY */
+
+ /*p_Fm->p_FmDriverParam->numOfPartitions = p_FmParam->numOfPartitions; */
+ p_Fm->p_FmDriverParam->enCounters = FALSE;
+
+ p_Fm->p_FmDriverParam->resetOnInit = DEFAULT_resetOnInit;
+
+ p_Fm->p_FmDriverParam->thresholds.dispLimit = DEFAULT_dispLimit;
+ p_Fm->p_FmDriverParam->thresholds.prsDispTh = DEFAULT_prsDispTh;
+ p_Fm->p_FmDriverParam->thresholds.plcrDispTh = DEFAULT_plcrDispTh;
+ p_Fm->p_FmDriverParam->thresholds.kgDispTh = DEFAULT_kgDispTh;
+ p_Fm->p_FmDriverParam->thresholds.bmiDispTh = DEFAULT_bmiDispTh;
+ p_Fm->p_FmDriverParam->thresholds.qmiEnqDispTh = DEFAULT_qmiEnqDispTh;
+ p_Fm->p_FmDriverParam->thresholds.qmiDeqDispTh = DEFAULT_qmiDeqDispTh;
+ p_Fm->p_FmDriverParam->thresholds.fmCtl1DispTh = DEFAULT_fmCtl1DispTh;
+ p_Fm->p_FmDriverParam->thresholds.fmCtl2DispTh = DEFAULT_fmCtl2DispTh;
+
+ p_Fm->p_FmDriverParam->dmaStopOnBusError = DEFAULT_dmaStopOnBusError;
+
+ p_Fm->p_FmDriverParam->dmaCacheOverride = DEFAULT_cacheOverride;
+ p_Fm->p_FmDriverParam->dmaAidMode = DEFAULT_aidMode;
+ p_Fm->p_FmDriverParam->dmaAidOverride = DEFAULT_aidOverride;
+ p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = DEFAULT_axiDbgNumOfBeats;
+ p_Fm->p_FmDriverParam->dmaCamNumOfEntries = DEFAULT_dmaCamNumOfEntries;
+ p_Fm->p_FmDriverParam->dmaWatchdog = DEFAULT_dmaWatchdog;
+
+ p_Fm->p_FmDriverParam->dmaCommQThresholds.clearEmergency = DEFAULT_dmaCommQLow;
+ p_Fm->p_FmDriverParam->dmaCommQThresholds.assertEmergency = DEFAULT_dmaCommQHigh;
+ p_Fm->p_FmDriverParam->dmaReadBufThresholds.clearEmergency = DEFAULT_dmaReadIntBufLow;
+ p_Fm->p_FmDriverParam->dmaReadBufThresholds.assertEmergency = DEFAULT_dmaReadIntBufHigh;
+ p_Fm->p_FmDriverParam->dmaWriteBufThresholds.clearEmergency = DEFAULT_dmaWriteIntBufLow;
+ p_Fm->p_FmDriverParam->dmaWriteBufThresholds.assertEmergency = DEFAULT_dmaWriteIntBufHigh;
+ p_Fm->p_FmDriverParam->dmaSosEmergency = DEFAULT_dmaSosEmergency;
+
+ p_Fm->p_FmDriverParam->dmaDbgCntMode = DEFAULT_dmaDbgCntMode;
+
+ p_Fm->p_FmDriverParam->dmaEnEmergency = FALSE;
+ p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = FALSE;
+ p_Fm->p_FmDriverParam->catastrophicErr = DEFAULT_catastrophicErr;
+ p_Fm->p_FmDriverParam->dmaErr = DEFAULT_dmaErr;
+ p_Fm->p_FmDriverParam->haltOnExternalActivation = DEFAULT_haltOnExternalActivation;
+ p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = DEFAULT_haltOnUnrecoverableEccError;
+ p_Fm->p_FmDriverParam->enIramTestMode = FALSE;
+ p_Fm->p_FmDriverParam->enMuramTestMode = FALSE;
+ p_Fm->p_FmDriverParam->externalEccRamsEnable = DEFAULT_externalEccRamsEnable;
+
+ p_Fm->p_FmDriverParam->fwVerify = DEFAULT_VerifyUcode;
+ p_Fm->p_FmDriverParam->firmware.size = p_FmParam->firmware.size;
+ if (p_Fm->p_FmDriverParam->firmware.size)
+ {
+ p_Fm->p_FmDriverParam->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->p_FmDriverParam->firmware.size);
+ if (!p_Fm->p_FmDriverParam->firmware.p_Code)
+ {
+ XX_FreeSpinlock(p_Fm->h_Spinlock);
+ XX_Free(p_Fm->p_FmStateStruct);
+ XX_Free(p_Fm->p_FmDriverParam);
+ XX_Free(p_Fm);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
+ return NULL;
+ }
+ memcpy(p_Fm->p_FmDriverParam->firmware.p_Code, p_FmParam->firmware.p_Code, p_Fm->p_FmDriverParam->firmware.size);
+ }
+
+ return p_Fm;
+}
+
+/**************************************************************************//**
+ @Function FM_Init
+
+ @Description Initializes the FM module
+
+ @Param[in] h_Fm - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_Init(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_FmDriverParam *p_FmDriverParam = NULL;
+ t_Error err = E_OK;
+ uint32_t tmpReg, cfgReg = 0;
+ int i;
+ uint16_t periodInFmClocks;
+ uint8_t remainder;
+ t_FmRevisionInfo revInfo;
+
+ SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ uint8_t isMasterAlive;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+
+ /* build the FM guest partition IPC address */
+ if(Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+
+ /* build the FM master partition IPC address */
+ memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
+ if(Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+
+ for(i=0;i<e_FM_EV_DUMMY_LAST;i++)
+ p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
+
+ p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
+ if (p_Fm->h_IpcSessions[0])
+ {
+ err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_MASTER_IS_ALIVE;
+ msg.msgBody[0] = p_Fm->guestId;
+ replyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ do
+ {
+ blockingFlag = TRUE;
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId)+sizeof(p_Fm->guestId),
+ (uint8_t*)&reply,
+ &replyLength,
+ IpcMsgCompletionCB,
+ h_Fm)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ while(blockingFlag) ;
+ if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ isMasterAlive = *(uint8_t*)(reply.replyBody);
+ } while (!isMasterAlive);
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_GET_CLK_FREQ;
+ replyLength = sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(replyLength != (sizeof(uint32_t) + sizeof(p_Fm->p_FmStateStruct->fmClkFreq)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ memcpy((uint8_t*)&p_Fm->p_FmStateStruct->fmClkFreq, reply.replyBody, sizeof(uint16_t));
+ }
+ else
+ {
+ DBG(WARNING, ("FM Guest mode - without IPC"));
+ if(!p_Fm->p_FmStateStruct->fmClkFreq )
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
+ if(!p_Fm->baseAddr)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No baseAddr configured for guest without IPC"));
+ }
+
+ XX_Free(p_Fm->p_FmDriverParam);
+ p_Fm->p_FmDriverParam = NULL;
+
+ if ((p_Fm->guestId == NCSW_MASTER_ID) ||
+ (p_Fm->h_IpcSessions[0]))
+ {
+ FM_DisableRamsEcc(p_Fm);
+ FmMuramClear(p_Fm->h_FmMuram);
+ FM_EnableRamsEcc(p_Fm);
+ }
+
+ return E_OK;
+ }
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ FM_GetRevision(p_Fm, &revInfo);
+
+#ifdef FM_NO_DISPATCH_RAM_ECC
+ if (revInfo.majorRev != 4)
+ p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
+#endif /* FM_NO_DISPATCH_RAM_ECC */
+
+#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_LIST_RAM_ECC;
+#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
+
+#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_PIPELINE_ECC;
+#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
+
+#ifdef FM_QMI_NO_ECC_EXCEPTIONS
+ if (revInfo.majorRev == 4)
+ p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
+
+ CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
+
+ p_FmDriverParam = p_Fm->p_FmDriverParam;
+
+ FmMuramClear(p_Fm->h_FmMuram);
+
+#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
+ if (p_FmDriverParam->resetOnInit)
+ {
+ t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
+ uint32_t debug_reg;
+
+ /* write to IRAM first location the debug instruction */
+ WRITE_UINT32(p_Iram->iadd, 0);
+ while (GET_UINT32(p_Iram->iadd) != 0) ;
+ WRITE_UINT32(p_Iram->idata, FM_UCODE_DEBUG_INSTRUCTION);
+
+ WRITE_UINT32(p_Iram->iadd, 0);
+ while (GET_UINT32(p_Iram->iadd) != 0) ;
+ while (GET_UINT32(p_Iram->idata) != FM_UCODE_DEBUG_INSTRUCTION) ;
+
+ /* Enable patch from IRAM */
+ WRITE_UINT32(p_Iram->iready, IRAM_READY);
+ XX_UDelay(100);
+
+ /* reset FMAN */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
+ XX_UDelay(100);
+
+ /* verify breakpoint debug status register */
+ debug_reg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
+#ifndef NCSW_LINUX
+ if(!debug_reg)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid debug status register value = 0"));
+#else
+ if(!debug_reg)
+ DBG(INFO,("Invalid debug status register value = 0"));
+#endif
+ /*************************************/
+ /* Load FMan-Controller code to Iram */
+ /*************************************/
+ if (ClearIRam(p_Fm) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ if (p_Fm->p_FmDriverParam->firmware.p_Code &&
+ (LoadFmanCtrlCode(p_Fm) != E_OK))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ XX_UDelay(100);
+
+ /* reset FMAN again to start the microcode */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
+ XX_UDelay(1000);
+ }
+ else
+ {
+#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
+ if(p_FmDriverParam->resetOnInit)
+ {
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrstc, FPM_RSTC_FM_RESET);
+ XX_UDelay(100);
+ }
+
+ /*************************************/
+ /* Load FMan-Controller code to Iram */
+ /*************************************/
+ if (ClearIRam(p_Fm) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ if (p_Fm->p_FmDriverParam->firmware.p_Code &&
+ (LoadFmanCtrlCode(p_Fm) != E_OK))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
+ }
+#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
+
+#ifdef FM_CAPWAP_SUPPORT
+ /* save first 256 byte in MURAM */
+ p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
+ if (!p_Fm->resAddr)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
+
+ WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
+#endif /* FM_CAPWAP_SUPPORT */
+
+ /* General FM driver initialization */
+ p_Fm->fmMuramPhysBaseAddr = (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
+ for(i=0;i<e_FM_EV_DUMMY_LAST;i++)
+ p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
+ for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
+ p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
+
+ /**********************/
+ /* Init DMA Registers */
+ /**********************/
+ /* clear status reg events */
+ tmpReg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC | DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
+ /*tmpReg |= (DMA_STATUS_SYSTEM_DPEXT_ECC | DMA_STATUS_FM_DPEXT_ECC | DMA_STATUS_SYSTEM_DPDAT_ECC | DMA_STATUS_FM_DPDAT_ECC | DMA_STATUS_FM_SPDAT_ECC);*/
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr) | tmpReg);
+
+ /* configure mode register */
+ tmpReg = 0;
+ tmpReg |= p_FmDriverParam->dmaCacheOverride << DMA_MODE_CACHE_OR_SHIFT;
+ if(p_FmDriverParam->dmaAidOverride)
+ tmpReg |= DMA_MODE_AID_OR;
+ if (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_BUS_ERROR)
+ tmpReg |= DMA_MODE_BER;
+ if ((p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_SYSTEM_WRITE_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_READ_ECC) | (p_Fm->p_FmStateStruct->exceptions & FM_EX_DMA_FM_WRITE_ECC))
+ tmpReg |= DMA_MODE_ECC;
+ if(p_FmDriverParam->dmaStopOnBusError)
+ tmpReg |= DMA_MODE_SBER;
+ tmpReg |= (uint32_t)(p_FmDriverParam->dmaAxiDbgNumOfBeats - 1) << DMA_MODE_AXI_DBG_SHIFT;
+ if (p_FmDriverParam->dmaEnEmergency)
+ {
+ tmpReg |= p_FmDriverParam->dmaEmergency.emergencyBusSelect;
+ tmpReg |= p_FmDriverParam->dmaEmergency.emergencyLevel << DMA_MODE_EMERGENCY_LEVEL_SHIFT;
+ if(p_FmDriverParam->dmaEnEmergencySmoother)
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmemsr, p_FmDriverParam->dmaEmergencySwitchCounter);
+ }
+ tmpReg |= ((p_FmDriverParam->dmaCamNumOfEntries/DMA_CAM_UNITS) - 1) << DMA_MODE_CEN_SHIFT;
+
+ tmpReg |= DMA_MODE_SECURE_PROT;
+ tmpReg |= p_FmDriverParam->dmaDbgCntMode << DMA_MODE_DBG_SHIFT;
+ tmpReg |= p_FmDriverParam->dmaAidMode << DMA_MODE_AID_MODE_SHIFT;
+
+#ifdef FM_PEDANTIC_DMA
+ tmpReg |= DMA_MODE_EMERGENCY_READ;
+#endif /* FM_PEDANTIC_DMA */
+
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
+
+ /* configure thresholds register */
+ tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.assertEmergency << DMA_THRESH_COMMQ_SHIFT) |
+ ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.assertEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) |
+ ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.assertEmergency);
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmtr, tmpReg);
+
+ /* configure hysteresis register */
+ tmpReg = ((uint32_t)p_FmDriverParam->dmaCommQThresholds.clearEmergency << DMA_THRESH_COMMQ_SHIFT) |
+ ((uint32_t)p_FmDriverParam->dmaReadBufThresholds.clearEmergency << DMA_THRESH_READ_INT_BUF_SHIFT) |
+ ((uint32_t)p_FmDriverParam->dmaWriteBufThresholds.clearEmergency);
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmhy, tmpReg);
+
+ /* configure emergency threshold */
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsetr, p_FmDriverParam->dmaSosEmergency);
+
+ /* configure Watchdog */
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmwcr, USEC_TO_CLK(p_FmDriverParam->dmaWatchdog, p_Fm->p_FmStateStruct->fmClkFreq));
+
+ /* Allocate MURAM for CAM */
+ p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
+ (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY),
+ DMA_CAM_ALIGN));
+ if (!p_Fm->camBaseAddr )
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
+
+ WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), 0, (uint32_t)(p_FmDriverParam->dmaCamNumOfEntries*DMA_CAM_SIZEOF_ENTRY));
+
+ /* VirtToPhys */
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmebcr,
+ (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr));
+
+#ifdef FM_PARTITION_ARRAY
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ /* liodn-partitions */
+ for (i=0 ; i<FM_SIZE_OF_LIODN_TABLE ; i+=2)
+ {
+ tmpReg = (((uint32_t)p_FmDriverParam->liodnBasePerPort[i] << DMA_LIODN_SHIFT) |
+ (uint32_t)p_FmDriverParam->liodnBasePerPort[i+1]);
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmplr[i/2], tmpReg);
+ }
+ }
+#endif /* FM_PARTITION_ARRAY */
+
+ /**********************/
+ /* Init FPM Registers */
+ /**********************/
+ tmpReg = (uint32_t)(p_FmDriverParam->thresholds.dispLimit << FPM_DISP_LIMIT_SHIFT);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmflc, tmpReg);
+
+ tmpReg = (((uint32_t)p_FmDriverParam->thresholds.prsDispTh << FPM_THR1_PRS_SHIFT) |
+ ((uint32_t)p_FmDriverParam->thresholds.kgDispTh << FPM_THR1_KG_SHIFT) |
+ ((uint32_t)p_FmDriverParam->thresholds.plcrDispTh << FPM_THR1_PLCR_SHIFT) |
+ ((uint32_t)p_FmDriverParam->thresholds.bmiDispTh << FPM_THR1_BMI_SHIFT));
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis1, tmpReg);
+
+ tmpReg = (((uint32_t)p_FmDriverParam->thresholds.qmiEnqDispTh << FPM_THR2_QMI_ENQ_SHIFT) |
+ ((uint32_t)p_FmDriverParam->thresholds.qmiDeqDispTh << FPM_THR2_QMI_DEQ_SHIFT) |
+ ((uint32_t)p_FmDriverParam->thresholds.fmCtl1DispTh << FPM_THR2_FM_CTL1_SHIFT) |
+ ((uint32_t)p_FmDriverParam->thresholds.fmCtl2DispTh << FPM_THR2_FM_CTL2_SHIFT));
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmdis2, tmpReg);
+
+ /* define exceptions and error behavior */
+ tmpReg = 0;
+ /* Clear events */
+ tmpReg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_SINGLE_ECC);
+ /* enable interrupts */
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_STALL_ON_TASKS)
+ tmpReg |= FPM_EV_MASK_STALL_EN;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_SINGLE_ECC)
+ tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_FPM_DOUBLE_ECC)
+ tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN;
+ tmpReg |= (p_Fm->p_FmDriverParam->catastrophicErr << FPM_EV_MASK_CAT_ERR_SHIFT);
+ tmpReg |= (p_Fm->p_FmDriverParam->dmaErr << FPM_EV_MASK_DMA_ERR_SHIFT);
+ if(!p_Fm->p_FmDriverParam->haltOnExternalActivation)
+ tmpReg |= FPM_EV_MASK_EXTERNAL_HALT;
+ if(!p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError)
+ tmpReg |= FPM_EV_MASK_ECC_ERR_HALT;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
+
+ /* clear all fmCtls event registers */
+ for(i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[i], 0xFFFFFFFF);
+
+ /* RAM ECC - enable and clear events*/
+ /* first we need to clear all parser memory, as it is uninitialized and
+ may cause ECC errors */
+ tmpReg = 0;
+ /* event bits */
+ tmpReg = (FPM_RAM_CTL_MURAM_ECC | FPM_RAM_CTL_IRAM_ECC);
+ /* Rams enable is not effected by the RCR bit, but by a COP configuration */
+ if(p_Fm->p_FmDriverParam->externalEccRamsEnable)
+ tmpReg |= FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL;
+
+ /* enable test mode */
+ if(p_FmDriverParam->enMuramTestMode)
+ tmpReg |= FPM_RAM_CTL_MURAM_TEST_ECC;
+ if(p_FmDriverParam->enIramTestMode)
+ tmpReg |= FPM_RAM_CTL_IRAM_TEST_ECC;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg);
+
+ tmpReg = 0;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_IRAM_ECC)
+ {
+ tmpReg |= FPM_IRAM_ECC_ERR_EX_EN;
+ FmEnableRamsEcc(p_Fm);
+ }
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_NURAM_ECC)
+ {
+ tmpReg |= FPM_MURAM_ECC_ERR_EX_EN;
+ FmEnableRamsEcc(p_Fm);
+ }
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
+
+ /**********************/
+ /* Init BMI Registers */
+ /**********************/
+
+ /* define common resources */
+ /* allocate MURAM for FIFO according to total size */
+ p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
+ p_Fm->p_FmStateStruct->totalFifoSize,
+ BMI_FIFO_ALIGN));
+ if (!p_Fm->fifoBaseAddr)
+ {
+ FreeInitResources(p_Fm);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for FIFO failed"));
+ }
+
+ tmpReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
+ tmpReg = tmpReg / BMI_FIFO_ALIGN;
+
+ tmpReg |= ((p_Fm->p_FmStateStruct->totalFifoSize/BMI_FIFO_UNITS - 1) << BMI_CFG1_FIFO_SIZE_SHIFT);
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, tmpReg);
+
+ tmpReg = ((uint32_t)(p_Fm->p_FmStateStruct->totalNumOfTasks - 1) << BMI_CFG2_TASKS_SHIFT );
+ /* num of DMA's will be dynamically updated when each port is set */
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, tmpReg);
+
+ /* define unmaskable exceptions, enable and clear events */
+ tmpReg = 0;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ievr, (BMI_ERR_INTR_EN_LIST_RAM_ECC |
+ BMI_ERR_INTR_EN_PIPELINE_ECC |
+ BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
+ BMI_ERR_INTR_EN_DISPATCH_RAM_ECC));
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC)
+ tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC)
+ tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC)
+ tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
+ tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
+
+ /**********************/
+ /* Init QMI Registers */
+ /**********************/
+ /* Clear error interrupt events */
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eie, (QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF));
+ tmpReg = 0;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
+ tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC)
+ tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
+ /* enable events */
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
+
+ if(p_Fm->p_FmDriverParam->tnumAgingPeriod)
+ {
+ /* tnumAgingPeriod is in units of microseconds, p_FmClockFreq is in Mhz */
+ periodInFmClocks = (uint16_t)(p_Fm->p_FmDriverParam->tnumAgingPeriod*p_Fm->p_FmStateStruct->fmClkFreq);
+ /* periodInFmClocks must be a 64 multiply */
+ remainder = (uint8_t)(periodInFmClocks % 64);
+ if (remainder > 64)
+ tmpReg = (uint32_t)((periodInFmClocks/64) + 1);
+ else
+ {
+ tmpReg = (uint32_t)(periodInFmClocks/64);
+ if(!tmpReg)
+ tmpReg = 1;
+ }
+ tmpReg <<= QMI_TAPC_TAP;
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_tapc, tmpReg);
+
+ }
+ tmpReg = 0;
+ /* Clear interrupt events */
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ie, QMI_INTR_EN_SINGLE_ECC);
+ if(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC)
+ tmpReg |= QMI_INTR_EN_SINGLE_ECC;
+ /* enable events */
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg);
+
+ /* clear & enable global counters - calculate reg and save for later,
+ because it's the same reg for QMI enable */
+ if(p_Fm->p_FmDriverParam->enCounters)
+ cfgReg = QMI_CFG_EN_COUNTERS;
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ cfgReg |= (uint32_t)(((QMI_DEF_TNUMS_THRESH) << 8) | (uint32_t)QMI_DEF_TNUMS_THRESH);
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+ if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
+ {
+ XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
+ XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
+ }
+
+ if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
+ {
+ XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, ErrorIsrCB, p_Fm);
+ XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
+ }
+
+ /* build the FM master partition IPC address */
+ if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+
+ err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
+ if(err)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ /**********************/
+ /* Enable all modules */
+ /**********************/
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, BMI_INIT_START);
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, cfgReg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN);
+
+ if (p_Fm->p_FmDriverParam->firmware.p_Code)
+ {
+ XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code);
+ p_Fm->p_FmDriverParam->firmware.p_Code = NULL;
+ }
+
+ XX_Free(p_Fm->p_FmDriverParam);
+ p_Fm->p_FmDriverParam = NULL;
+
+ return E_OK;
+}
+
+/**************************************************************************//**
+ @Function FM_Free
+
+ @Description Frees all resources that were assigned to FM module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_Fm - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_Free(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ if (p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
+
+ if(!p_Fm->recoveryMode)
+ XX_Free(p_Fm->p_FmStateStruct);
+
+ XX_Free(p_Fm);
+
+ return E_OK;
+ }
+
+ /* disable BMI and QMI */
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_init, 0);
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc, 0);
+
+ /* release BMI resources */
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg2, 0);
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_cfg1, 0);
+
+ /* disable ECC */
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, 0);
+
+ if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
+ XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
+
+ if (p_Fm->p_FmStateStruct)
+ {
+ if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
+ {
+ XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
+ XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
+ }
+ if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
+ {
+ XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
+ XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
+ }
+ }
+
+ if (p_Fm->h_Spinlock)
+ XX_FreeSpinlock(p_Fm->h_Spinlock);
+
+ if (p_Fm->p_FmDriverParam)
+ {
+ if (p_Fm->p_FmDriverParam->firmware.p_Code)
+ XX_Free(p_Fm->p_FmDriverParam->firmware.p_Code);
+ XX_Free(p_Fm->p_FmDriverParam);
+ p_Fm->p_FmDriverParam = NULL;
+ }
+
+ FreeInitResources(p_Fm);
+
+ if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
+ XX_Free(p_Fm->p_FmStateStruct);
+
+ XX_Free(p_Fm);
+
+ return E_OK;
+}
+
+/*************************************************/
+/* API Advanced Init unit functions */
+/*************************************************/
+
+t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
+{
+
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->resetOnInit = enable;
+
+ return E_OK;
+}
+
+
+t_Error FM_ConfigTotalNumOfTasks(t_Handle h_Fm, uint8_t totalNumOfTasks)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmStateStruct->totalNumOfTasks = totalNumOfTasks;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigMaxNumOfOpenDmas(t_Handle h_Fm, uint8_t maxNumOfOpenDmas)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmStateStruct->maxNumOfOpenDmas = maxNumOfOpenDmas;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ memcpy(&p_Fm->p_FmDriverParam->thresholds, p_FmThresholds, sizeof(t_FmThresholds));
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaCacheOverride = cacheOverride;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaAidOverride = aidOverride;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaAidMode = aidMode;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaAxiDbgNumOfBeats = axiDbgNumOfBeats;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaCamNumOfEntries = numOfEntries;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+#ifdef FM_NO_WATCHDOG
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(h_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("watchdog!"));
+ }
+#endif /* FM_NO_WATCHDOG */
+
+ p_Fm->p_FmDriverParam->dmaWatchdog = watchdogValue;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
+
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ memcpy(&p_Fm->p_FmDriverParam->dmaWriteBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ memcpy(&p_Fm->p_FmDriverParam->dmaCommQThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ memcpy(&p_Fm->p_FmDriverParam->dmaReadBufThresholds, p_FmDmaThresholds, sizeof(t_FmDmaThresholds));
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaEnEmergency = TRUE;
+ memcpy(&p_Fm->p_FmDriverParam->dmaEmergency, p_Emergency, sizeof(t_FmDmaEmergency));
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ if(!p_Fm->p_FmDriverParam->dmaEnEmergency)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM_ConfigEnDmaEmergencySmoother may be called only after FM_ConfigEnDmaEmergency"));
+
+ p_Fm->p_FmDriverParam->dmaEnEmergencySmoother = TRUE;
+ p_Fm->p_FmDriverParam->dmaEmergencySwitchCounter = emergencyCnt;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaDbgCntMode = fmDmaDbgCntMode;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaStopOnBusError = stop;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaSosEmergency = dmaSosEmergency;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->enCounters = TRUE;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->dmaErr = dmaErr;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->catastrophicErr = catastrophicErr;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->enMuramTestMode = TRUE;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->enIramTestMode = TRUE;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+#ifdef FM_HALT_SIG_ERRATA_GEN12
+ {
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(h_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnExternalActivation!"));
+ }
+#endif /* FM_HALT_SIG_ERRATA_GEN12 */
+
+ p_Fm->p_FmDriverParam->haltOnExternalActivation = enable;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
+#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
+
+ p_Fm->p_FmDriverParam->haltOnUnrecoverableEccError = enable;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t bitMask = 0;
+ t_FmRevisionInfo revInfo;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ FM_GetRevision(p_Fm, &revInfo);
+#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
+ if((exception == e_FM_EX_BMI_PIPELINE_ECC) && (enable))
+ {
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECC!"));
+ return E_OK;
+ }
+ }
+#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
+#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
+ if((exception == e_FM_EX_BMI_LIST_RAM_ECC) && (enable))
+ {
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC!"));
+ return E_OK;
+ }
+ }
+#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
+#ifdef FM_QMI_NO_ECC_EXCEPTIONS
+ if(((exception == e_FM_EX_QMI_SINGLE_ECC) || (exception == e_FM_EX_QMI_DOUBLE_ECC)) &&
+ enable)
+ {
+ if (revInfo.majorRev == 4)
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("QMI ECC exception!"));
+ return E_OK;
+ }
+ }
+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
+#ifdef FM_NO_DISPATCH_RAM_ECC
+ if((exception == e_FM_EX_BMI_DISPATCH_RAM_ECC) && (enable))
+ {
+ if (revInfo.majorRev != 4)
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
+ return E_OK;
+ }
+ }
+#endif /* FM_NO_DISPATCH_RAM_ECC */
+
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Fm->p_FmStateStruct->exceptions |= bitMask;
+ else
+ p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ p_Fm->p_FmDriverParam->externalEccRamsEnable = enable;
+
+ return E_OK;
+}
+
+t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+#ifdef FM_NO_TNUM_AGING
+ t_FmRevisionInfo revInfo;
+#endif /* FM_NO_TNUM_AGING */
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+#ifdef FM_NO_TNUM_AGING
+ FM_GetRevision(h_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("FM_ConfigTnumAgingPeriod!"));
+#endif /* FM_NO_TNUM_AGING */
+
+ p_Fm->p_FmDriverParam->tnumAgingPeriod = tnumAgingPeriod;
+
+ return E_OK;
+
+}
+
+/****************************************************/
+/* API Run-time Control uint functions */
+/****************************************************/
+t_Handle FM_GetPcdHandle(t_Handle h_Fm)
+{
+ SANITY_CHECK_RETURN_VALUE(h_Fm, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(!((t_Fm*)h_Fm)->p_FmDriverParam, E_INVALID_STATE, NULL);
+
+ return ((t_Fm*)h_Fm)->h_Pcd;
+}
+
+void FM_EventIsr(t_Handle h_Fm)
+{
+#define FM_M_CALL_1G_MAC_TMR_ISR(_id) \
+ { \
+ if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].guestId) \
+ SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id), pending); \
+ else \
+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0_TMR+_id)].h_SrcHandle);\
+ }
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t pending, event;
+
+ SANITY_CHECK_RETURN(h_Fm, E_INVALID_HANDLE);
+
+ /* normal interrupts */
+ pending = GET_UINT32(p_Fm->p_FmFpmRegs->fmnpi);
+ ASSERT_COND(pending);
+ if (pending & INTR_EN_BMI)
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("BMI Event - undefined!"));
+ if (pending & INTR_EN_QMI)
+ QmiEvent(p_Fm);
+ if (pending & INTR_EN_PRS)
+ p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
+ if (pending & INTR_EN_PLCR)
+ p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
+ if (pending & INTR_EN_KG)
+ p_Fm->intrMng[e_FM_EV_KG].f_Isr(p_Fm->intrMng[e_FM_EV_KG].h_SrcHandle);
+ if (pending & INTR_EN_TMR)
+ p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
+
+ /* MAC events may belong to different partitions */
+ if (pending & INTR_EN_1G_MAC0_TMR)
+ FM_M_CALL_1G_MAC_TMR_ISR(0);
+ if (pending & INTR_EN_1G_MAC1_TMR)
+ FM_M_CALL_1G_MAC_TMR_ISR(1);
+ if (pending & INTR_EN_1G_MAC2_TMR)
+ FM_M_CALL_1G_MAC_TMR_ISR(2);
+ if (pending & INTR_EN_1G_MAC3_TMR)
+ FM_M_CALL_1G_MAC_TMR_ISR(3);
+ if (pending & INTR_EN_1G_MAC4_TMR)
+ FM_M_CALL_1G_MAC_TMR_ISR(4);
+
+ /* IM port events may belong to different partitions */
+ if (pending & INTR_EN_REV0)
+ {
+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[0]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[0]);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[0], event);
+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
+ /*TODO IPC ISR For Fman Ctrl */
+ ASSERT_COND(0);
+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
+ else
+ p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
+
+ }
+ if (pending & INTR_EN_REV1)
+ {
+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[1]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[1]);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[1], event);
+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
+ /*TODO IPC ISR For Fman Ctrl */
+ ASSERT_COND(0);
+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
+ else
+ p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
+
+ }
+ if (pending & INTR_EN_REV2)
+ {
+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[2]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[2]);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[2], event);
+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
+ /*TODO IPC ISR For Fman Ctrl */
+ ASSERT_COND(0);
+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
+ else
+ p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
+ }
+ if (pending & INTR_EN_REV3)
+ {
+ event = GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcev[3]) & GET_UINT32(p_Fm->p_FmFpmRegs->fmfpfcee[3]);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmcev[3], event);
+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
+ /*TODO IPC ISR For Fman Ctrl */
+ ASSERT_COND(0);
+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
+ else
+ p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
+ }
+}
+
+t_Error FM_ErrorIsr(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
+
+ /* error interrupts */
+ if (GET_UINT32(p_Fm->p_FmFpmRegs->fmepi) == 0)
+ return ERROR_CODE(E_EMPTY);
+
+ ErrorIsrCB(p_Fm);
+ return E_OK;
+}
+
+t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ int i;
+ uint8_t sum;
+ uint8_t hardwarePortId;
+ uint32_t tmpRegs[8] = {0,0,0,0,0,0,0,0};
+ uint8_t relativePortId, shift, weight, maxPercent = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ /* check that all ports add up to 100% */
+ sum = 0;
+ for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
+ sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
+ if (sum != 100)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
+
+ /* find highest precent */
+ for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
+ {
+ if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
+ maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
+ }
+
+ /* calculate weight for each port */
+ for (i=0;i<p_PortsBandwidth->numOfPorts;i++)
+ {
+ weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT )/maxPercent);
+ /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exect division
+ is not reached, we round up so that:
+ 0 until maxPercent/PORT_MAX_WEIGHT get "1"
+ maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
+ ...
+ maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
+ if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
+ weight++;
+
+ /* find the location of this port within the register */
+ SW_PORT_ID_TO_HW_PORT_ID(hardwarePortId,
+ p_PortsBandwidth->portsBandwidths[i].type,
+ p_PortsBandwidth->portsBandwidths[i].relativePortId);
+ relativePortId = (uint8_t)(hardwarePortId % 8);
+ shift = (uint8_t)(32-4*(relativePortId+1));
+
+
+ if(weight > 1)
+ /* Add this port to tmpReg */
+ /* (each 8 ports result in one register)*/
+ tmpRegs[hardwarePortId/8] |= ((weight-1) << shift);
+ }
+
+ for(i=0;i<8;i++)
+ if(tmpRegs[i])
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_arb[i], tmpRegs[i]);
+
+ return E_OK;
+}
+
+t_Error FM_EnableRamsEcc(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ t_FmIpcMsg msg;
+ t_Error err;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_ENABLE_RAM_ECC;
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ return E_OK;
+ }
+
+ if(!p_Fm->p_FmStateStruct->internalCall)
+ p_Fm->p_FmStateStruct->explicitEnable = TRUE;
+ p_Fm->p_FmStateStruct->internalCall = FALSE;
+
+ if(p_Fm->p_FmStateStruct->ramsEccEnable)
+ return E_OK;
+ else
+ {
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
+ if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
+ {
+ DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG"));
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | FPM_RAM_CTL_IRAM_ECC_EN);
+ }
+ else
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg | (FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN));
+ p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
+ }
+
+ return E_OK;
+}
+
+t_Error FM_DisableRamsEcc(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+ bool explicitDisable = FALSE;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ t_Error err;
+ t_FmIpcMsg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_DISABLE_RAM_ECC;
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ return E_OK;
+ }
+
+ if(!p_Fm->p_FmStateStruct->internalCall)
+ explicitDisable = TRUE;
+ p_Fm->p_FmStateStruct->internalCall = FALSE;
+
+ /* if rams are already disabled, or if rams were explicitly enabled and are
+ currently called indirectly (not explicitly), ignore this call. */
+ if(!p_Fm->p_FmStateStruct->ramsEccEnable || (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
+ return E_OK;
+ else
+ {
+ if(p_Fm->p_FmStateStruct->explicitEnable)
+ /* This is the case were both explicit are TRUE.
+ Turn off this flag for cases were following ramsEnable
+ routines are called */
+ p_Fm->p_FmStateStruct->explicitEnable = FALSE;
+
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrcr);
+ if(tmpReg & FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL)
+ {
+ DBG(WARNING, ("Rams ECC is configured to be controlled through JTAG"));
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~FPM_RAM_CTL_IRAM_ECC_EN);
+ }
+ else
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrcr, tmpReg & ~(FPM_RAM_CTL_RAMS_ECC_EN | FPM_RAM_CTL_IRAM_ECC_EN));
+ p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
+ }
+
+ return E_OK;
+}
+
+t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t bitMask = 0;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Fm->p_FmStateStruct->exceptions |= bitMask;
+ else
+ p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
+
+ switch(exception)
+ {
+ case(e_FM_EX_DMA_BUS_ERROR):
+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
+ if(enable)
+ tmpReg |= DMA_MODE_BER;
+ else
+ tmpReg &= ~DMA_MODE_BER;
+ /* disable bus error */
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
+ break;
+ case(e_FM_EX_DMA_READ_ECC):
+ case(e_FM_EX_DMA_SYSTEM_WRITE_ECC):
+ case(e_FM_EX_DMA_FM_WRITE_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr);
+ if(enable)
+ tmpReg |= DMA_MODE_ECC;
+ else
+ tmpReg &= ~DMA_MODE_ECC;
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, tmpReg);
+ break;
+ case(e_FM_EX_FPM_STALL_ON_TASKS):
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
+ if(enable)
+ tmpReg |= FPM_EV_MASK_STALL_EN;
+ else
+ tmpReg &= ~FPM_EV_MASK_STALL_EN;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
+ break;
+ case(e_FM_EX_FPM_SINGLE_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
+ if(enable)
+ tmpReg |= FPM_EV_MASK_SINGLE_ECC_EN;
+ else
+ tmpReg &= ~FPM_EV_MASK_SINGLE_ECC_EN;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
+ break;
+ case( e_FM_EX_FPM_DOUBLE_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
+ if(enable)
+ tmpReg |= FPM_EV_MASK_DOUBLE_ECC_EN;
+ else
+ tmpReg &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg);
+ break;
+ case( e_FM_EX_QMI_SINGLE_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien);
+ if(enable)
+ {
+#ifdef FM_QMI_NO_ECC_EXCEPTIONS
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Fm, &revInfo);
+ if (revInfo.majorRev == 4)
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC"));
+ return E_OK;
+ }
+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
+ tmpReg |= QMI_INTR_EN_SINGLE_ECC;
+ }
+ else
+ tmpReg &= ~QMI_INTR_EN_SINGLE_ECC;
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_ien, tmpReg);
+ break;
+ case(e_FM_EX_QMI_DOUBLE_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
+ if(enable)
+ {
+#ifdef FM_QMI_NO_ECC_EXCEPTIONS
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Fm, &revInfo);
+ if (revInfo.majorRev == 4)
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_DOUBLE_ECC"));
+ return E_OK;
+ }
+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
+ tmpReg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
+ }
+ else
+ tmpReg &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
+ break;
+ case(e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
+ tmpReg = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien);
+ if(enable)
+ tmpReg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
+ else
+ tmpReg &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eien, tmpReg);
+ break;
+ case(e_FM_EX_BMI_LIST_RAM_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
+ if(enable)
+ {
+#ifdef FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_LIST_RAM_ECC"));
+ return E_OK;
+ }
+#endif /* FM_RAM_LIST_ERR_IRQ_ERRATA_FMAN8 */
+ tmpReg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
+ }
+ else
+ tmpReg &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
+ break;
+ case(e_FM_EX_BMI_PIPELINE_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
+ if(enable)
+ {
+#ifdef FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Fm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_PIPELINE_ECCBMI_LIST_RAM_ECC"));
+ return E_OK;
+ }
+#endif /* FM_BMI_PIPELINE_ERR_IRQ_ERRATA_FMAN9 */
+ tmpReg |= BMI_ERR_INTR_EN_PIPELINE_ECC;
+ }
+ else
+ tmpReg &= ~BMI_ERR_INTR_EN_PIPELINE_ECC;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
+ break;
+ case(e_FM_EX_BMI_STATISTICS_RAM_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
+ if(enable)
+ tmpReg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
+ else
+ tmpReg &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
+ break;
+ case(e_FM_EX_BMI_DISPATCH_RAM_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier);
+ if(enable)
+ {
+#ifdef FM_NO_DISPATCH_RAM_ECC
+ t_FmRevisionInfo revInfo;
+ FM_GetRevision(p_Fm, &revInfo);
+ if (revInfo.majorRev != 4)
+ {
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_EX_BMI_DISPATCH_RAM_ECC"));
+ return E_OK;
+ }
+#endif /* FM_NO_DISPATCH_RAM_ECC */
+ tmpReg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
+ }
+ else
+ tmpReg &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ier, tmpReg);
+ break;
+ case(e_FM_EX_IRAM_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
+ if(enable)
+ {
+ /* enable ECC if not enabled */
+ FmEnableRamsEcc(p_Fm);
+ /* enable ECC interrupts */
+ tmpReg |= FPM_IRAM_ECC_ERR_EX_EN;
+ }
+ else
+ {
+ /* ECC mechanism may be disabled, depending on driver status */
+ FmDisableRamsEcc(p_Fm);
+ tmpReg &= ~FPM_IRAM_ECC_ERR_EX_EN;
+ }
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
+ break;
+
+ case(e_FM_EX_MURAM_ECC):
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fmrie);
+ if(enable)
+ {
+ /* enable ECC if not enabled */
+ FmEnableRamsEcc(p_Fm);
+ /* enable ECC interrupts */
+ tmpReg |= FPM_MURAM_ECC_ERR_EX_EN;
+ }
+ else
+ {
+ /* ECC mechanism may be disabled, depending on driver status */
+ FmDisableRamsEcc(p_Fm);
+ tmpReg &= ~FPM_MURAM_ECC_ERR_EX_EN;
+ }
+
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmrie, tmpReg);
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
+ }
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+ t_FmIpcRevisionInfo ipcRevInfo;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+
+ if (p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_GET_REV;
+ replyLength = sizeof(uint32_t) + sizeof(t_FmRevisionInfo);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmRevisionInfo)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmRevisionInfo));
+ p_FmRevisionInfo->majorRev = ipcRevInfo.majorRev;
+ p_FmRevisionInfo->minorRev = ipcRevInfo.minorRev;
+ return (t_Error)(reply.error);
+ }
+
+ /* read revision register 1 */
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fm_ip_rev_1);
+ p_FmRevisionInfo->majorRev = (uint8_t)((tmpReg & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
+ p_FmRevisionInfo->minorRev = (uint8_t)((tmpReg & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
+
+ return E_OK;
+}
+
+uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ t_Error err;
+ uint32_t counterValue;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength, outCounter;
+
+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
+
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_GET_COUNTER;
+ memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) +sizeof(counterValue),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ if(replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
+
+ return outCounter;
+ }
+
+ switch(counter)
+ {
+ case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc);
+ case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc);
+ case(e_FM_COUNTERS_DEQ_0):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0);
+ case(e_FM_COUNTERS_DEQ_1):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1);
+ case(e_FM_COUNTERS_DEQ_2):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2);
+ case(e_FM_COUNTERS_DEQ_3):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3);
+ case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc);
+ case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc);
+ case(e_FM_COUNTERS_DEQ_FROM_FD):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc);
+ case(e_FM_COUNTERS_DEQ_CONFIRM):
+ return GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc);
+ case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
+ return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc);
+ case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
+ return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc);
+ case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT):
+ return GET_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc);
+ default:
+ break;
+ }
+ /* should never get here */
+ ASSERT_COND(FALSE);
+
+ return 0;
+}
+
+t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ /* When applicable (when there is an 'enable counters' bit,
+ check that counters are enabled */
+ switch(counter)
+ {
+ case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
+ case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
+ case(e_FM_COUNTERS_DEQ_0):
+ case(e_FM_COUNTERS_DEQ_1):
+ case(e_FM_COUNTERS_DEQ_2):
+ case(e_FM_COUNTERS_DEQ_3):
+ case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
+ case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
+ case(e_FM_COUNTERS_DEQ_FROM_FD):
+ case(e_FM_COUNTERS_DEQ_CONFIRM):
+ if(!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
+ break;
+ default:
+ break;
+ }
+
+ /* Set counter */
+ switch(counter)
+ {
+ case(e_FM_COUNTERS_ENQ_TOTAL_FRAME):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_etfc, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_TOTAL_FRAME):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dtfc, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_0):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc0, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_1):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc1, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_2):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc2, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_3):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dc3, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_FROM_DEFAULT):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfdc, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_FROM_CONTEXT):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dfcc, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_FROM_FD):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dffc, val);
+ break;
+ case(e_FM_COUNTERS_DEQ_CONFIRM):
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_dcc, val);
+ break;
+ case(e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsefrc, val);
+ break;
+ case(e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmsqfrc, val);
+ break;
+ case(e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT):
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmssrc, val);
+ break;
+ default:
+ break;
+ }
+
+ return E_OK;
+}
+
+void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t bitMask;
+
+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ bitMask = (uint32_t)((muramPort==e_FM_DMA_MURAM_PORT_WRITE) ? DMA_MODE_EMERGENCY_WRITE : DMA_MODE_EMERGENCY_READ);
+
+ if(enable)
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | bitMask);
+ else /* disable */
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) & ~bitMask);
+
+ return;
+}
+
+void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ WRITE_UINT32(p_Fm->p_FmDmaRegs->fmdmmr, GET_UINT32(p_Fm->p_FmDmaRegs->fmdmmr) | ((uint32_t)pri << DMA_MODE_BUS_PRI_SHIFT) );
+
+ return;
+}
+
+void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+ t_Error err;
+ t_FmIpcMsg msg;
+ t_FmIpcReply reply;
+ uint32_t replyLength;
+ t_FmIpcDmaStatus ipcDmaStatus;
+
+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = FM_DMA_STAT;
+ replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ {
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ return;
+ }
+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ return;
+ }
+ memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
+
+ p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
+ p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
+ p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
+ p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
+ p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
+ return;
+ }
+
+ tmpReg = GET_UINT32(p_Fm->p_FmDmaRegs->fmdmsr);
+
+ p_FmDmaStatus->cmqNotEmpty = (bool)(tmpReg & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
+ p_FmDmaStatus->busError = (bool)(tmpReg & DMA_STATUS_BUS_ERR);
+ p_FmDmaStatus->readBufEccError = (bool)(tmpReg & DMA_STATUS_READ_ECC);
+ p_FmDmaStatus->writeBufEccSysError = (bool)(tmpReg & DMA_STATUS_SYSTEM_WRITE_ECC);
+ p_FmDmaStatus->writeBufEccFmError = (bool)(tmpReg & DMA_STATUS_FM_WRITE_ECC);
+ return;
+}
+
+t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ switch(exception)
+ {
+ case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DEQ_FROM_DEF);
+ break;
+ case e_FM_EX_QMI_SINGLE_ECC:
+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_if, QMI_INTR_EN_SINGLE_ECC);
+ break;
+ case e_FM_EX_QMI_DOUBLE_ECC:
+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_Fm->p_FmQmiRegs->fmqm_eif, QMI_ERR_INTR_EN_DOUBLE_ECC);
+ break;
+ case e_FM_EX_BMI_LIST_RAM_ECC:
+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_LIST_RAM_ECC);
+ break;
+ case e_FM_EX_BMI_PIPELINE_ECC:
+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_PIPELINE_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_PIPELINE_ECC);
+ break;
+ case e_FM_EX_BMI_STATISTICS_RAM_ECC:
+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_STATISTICS_RAM_ECC);
+ break;
+ case e_FM_EX_BMI_DISPATCH_RAM_ECC:
+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
+ WRITE_UINT32(p_Fm->p_FmBmiRegs->fmbm_ifr, BMI_ERR_INTR_EN_DISPATCH_RAM_ECC);
+ break;
+ default:
+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
+ }
+
+ return E_OK;
+}
+
+void FM_Resume(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+ if (p_Fm->guestId == NCSW_MASTER_ID)
+ {
+ tmpReg = GET_UINT32(p_Fm->p_FmFpmRegs->fpmem);
+ /* clear tmpReg event bits in order not to clear standing events */
+ tmpReg &= ~(FPM_EV_MASK_DOUBLE_ECC | FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC);
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fpmem, tmpReg | FPM_EV_MASK_RELEASE_FM);
+ }
+ else
+ ASSERT_COND(0); /* TODO */
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error FM_DumpRegs(t_Handle h_Fm)
+{
+ t_Fm *p_Fm = (t_Fm *)h_Fm;
+ uint8_t i = 0;
+ t_Error err;
+ t_FmIpcMsg msg;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
+
+
+ if(p_Fm->guestId != NCSW_MASTER_ID)
+ {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgId = FM_DUMP_REGS;
+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ return E_OK;
+ }
+
+
+ DUMP_SUBTITLE(("\n"));
+
+ DUMP_TITLE(p_Fm->p_FmFpmRegs, ("FmFpmRegs Regs"));
+
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtnc);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmpr);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,brkc);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmflc);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis1);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdis2);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmepi);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmrie);
+
+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcev, ("fmfpfcev"));
+ DUMP_SUBSTRUCT_ARRAY(i, 4)
+ {
+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcev[i], sizeof(uint32_t));
+ }
+
+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfpfcee, ("fmfpfcee"));
+ DUMP_SUBSTRUCT_ARRAY(i, 4)
+ {
+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfpfcee[i], sizeof(uint32_t));
+ }
+
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc1);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsc2);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsp);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmtsf);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmrcr);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmextc);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext1);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmext2);
+
+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmdrd, ("fpmdrd"));
+ DUMP_SUBSTRUCT_ARRAY(i, 16)
+ {
+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmdrd[i], sizeof(uint32_t));
+ }
+
+ DUMP_SUBTITLE(("\n"));
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmdra);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_1);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fm_ip_rev_2);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmrstc);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmcld);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fmnpi);
+ DUMP_VAR(p_Fm->p_FmFpmRegs,fpmem);
+
+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fpmcev, ("fpmcev"));
+ DUMP_SUBSTRUCT_ARRAY(i, 4)
+ {
+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fpmcev[i], sizeof(uint32_t));
+ }
+
+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps, ("fmfp_ps"));
+ DUMP_SUBSTRUCT_ARRAY(i, 64)
+ {
+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[i], sizeof(uint32_t));
+ }
+
+
+ DUMP_TITLE(p_Fm->p_FmDmaRegs, ("p_FmDmaRegs Regs"));
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsr);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmmr);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtr);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmhy);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsetr);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtah);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtal);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmtcid);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmra);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmrd);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmwcr);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmebcr);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqdr);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr1);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmccqvr2);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr3);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr4);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmcqvr5);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsefrc);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmsqfrc);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmssrc);
+ DUMP_VAR(p_Fm->p_FmDmaRegs,fmdmdcr);
+
+ DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr, ("fmdmplr"));
+
+ DUMP_SUBSTRUCT_ARRAY(i, FM_SIZE_OF_LIODN_TABLE/2)
+ {
+ DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[i], sizeof(uint32_t));
+ }
+
+ DUMP_TITLE(p_Fm->p_FmBmiRegs, ("p_FmBmiRegs COMMON Regs"));
+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_init);
+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg1);
+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_cfg2);
+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ievr);
+ DUMP_VAR(p_Fm->p_FmBmiRegs,fmbm_ier);
+
+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_arb, ("fmbm_arb"));
+ DUMP_SUBSTRUCT_ARRAY(i, 8)
+ {
+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_arb[i], sizeof(uint32_t));
+ }
+
+
+ DUMP_TITLE(p_Fm->p_FmQmiRegs, ("p_FmQmiRegs COMMON Regs"));
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gc);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eie);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eien);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_eif);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ie);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ien);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_if);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_gs);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_ts);
+ DUMP_VAR(p_Fm->p_FmQmiRegs,fmqm_etfc);
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
diff --git a/sys/contrib/ncsw/Peripherals/FM/fm.h b/sys/contrib/ncsw/Peripherals/FM/fm.h
new file mode 100644
index 0000000..cd61d96
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/fm.h
@@ -0,0 +1,699 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm.h
+
+ @Description FM internal structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_H
+#define __FM_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "fm_ext.h"
+#include "fm_ipc.h"
+
+
+#define __ERR_MODULE__ MODULE_FM
+
+#define FM_MAX_NUM_OF_HW_PORT_IDS 64
+#define FM_MAX_NUM_OF_GUESTS 100
+
+/**************************************************************************//**
+ @Description Exceptions
+*//***************************************************************************/
+#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
+#define FM_EX_DMA_READ_ECC 0x40000000
+#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
+#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
+#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
+#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
+#define FM_EX_FPM_DOUBLE_ECC 0x02000000
+#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
+#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
+#define FM_EX_QMI_DOUBLE_ECC 0x00400000
+#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
+#define FM_EX_BMI_PIPELINE_ECC 0x00100000
+#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
+#define FM_EX_IRAM_ECC 0x00040000
+#define FM_EX_NURAM_ECC 0x00020000
+#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
+
+#define GET_EXCEPTION_FLAG(bitMask, exception) switch(exception){ \
+ case e_FM_EX_DMA_BUS_ERROR: \
+ bitMask = FM_EX_DMA_BUS_ERROR; break; \
+ case e_FM_EX_DMA_READ_ECC: \
+ bitMask = FM_EX_DMA_READ_ECC; break; \
+ case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
+ bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
+ case e_FM_EX_DMA_FM_WRITE_ECC: \
+ bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
+ case e_FM_EX_FPM_STALL_ON_TASKS: \
+ bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
+ case e_FM_EX_FPM_SINGLE_ECC: \
+ bitMask = FM_EX_FPM_SINGLE_ECC; break; \
+ case e_FM_EX_FPM_DOUBLE_ECC: \
+ bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
+ case e_FM_EX_QMI_SINGLE_ECC: \
+ bitMask = FM_EX_QMI_SINGLE_ECC; break; \
+ case e_FM_EX_QMI_DOUBLE_ECC: \
+ bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
+ case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
+ bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
+ case e_FM_EX_BMI_LIST_RAM_ECC: \
+ bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
+ case e_FM_EX_BMI_PIPELINE_ECC: \
+ bitMask = FM_EX_BMI_PIPELINE_ECC; break; \
+ case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
+ bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
+ case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
+ bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
+ case e_FM_EX_IRAM_ECC: \
+ bitMask = FM_EX_IRAM_ECC; break; \
+ case e_FM_EX_MURAM_ECC: \
+ bitMask = FM_EX_NURAM_ECC; break; \
+ default: bitMask = 0;break;}
+
+/**************************************************************************//**
+ @Description defaults
+*//***************************************************************************/
+#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
+ FM_EX_DMA_READ_ECC |\
+ FM_EX_DMA_SYSTEM_WRITE_ECC |\
+ FM_EX_DMA_FM_WRITE_ECC |\
+ FM_EX_FPM_STALL_ON_TASKS |\
+ FM_EX_FPM_SINGLE_ECC |\
+ FM_EX_FPM_DOUBLE_ECC |\
+ FM_EX_QMI_SINGLE_ECC |\
+ FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
+ FM_EX_QMI_DOUBLE_ECC |\
+ FM_EX_BMI_LIST_RAM_ECC |\
+ FM_EX_BMI_PIPELINE_ECC |\
+ FM_EX_BMI_STATISTICS_RAM_ECC |\
+ FM_EX_BMI_DISPATCH_RAM_ECC |\
+ FM_EX_IRAM_ECC |\
+ FM_EX_NURAM_ECC )
+#define DEFAULT_totalNumOfTasks (BMI_MAX_NUM_OF_TASKS*3/4)
+#define DEFAULT_totalFifoSize (BMI_MAX_FIFO_SIZE*3/4)
+#define DEFAULT_maxNumOfOpenDmas (BMI_MAX_NUM_OF_DMAS*3/4)
+#define DEFAULT_eccEnable FALSE
+#define DEFAULT_dispLimit 0
+#define DEFAULT_prsDispTh 16
+#define DEFAULT_plcrDispTh 16
+#define DEFAULT_kgDispTh 16
+#define DEFAULT_bmiDispTh 16
+#define DEFAULT_qmiEnqDispTh 16
+#define DEFAULT_qmiDeqDispTh 16
+#define DEFAULT_fmCtl1DispTh 16
+#define DEFAULT_fmCtl2DispTh 16
+#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
+#ifdef FM_PEDANTIC_DMA
+#define DEFAULT_aidOverride TRUE
+#else
+#define DEFAULT_aidOverride FALSE
+#endif /* FM_PEDANTIC_DMA */
+#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
+#define DEFAULT_dmaStopOnBusError FALSE
+#define DEFAULT_stopAtBusError FALSE
+#define DEFAULT_axiDbgNumOfBeats 1
+#define DEFAULT_dmaCamNumOfEntries 32
+#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
+#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
+#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
+#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
+#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
+#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
+#define DEFAULT_dmaSosEmergency 0
+#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
+#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
+#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
+#define DEFAULT_resetOnInit FALSE
+#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
+#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
+#define DEFAULT_externalEccRamsEnable FALSE
+#define DEFAULT_VerifyUcode FALSE
+#define DEFAULT_tnumAgingPeriod 0
+#define DEFAULT_dmaWatchdog 0 /* disabled */
+#define DEFAULT_mtu 9600
+
+/**************************************************************************//**
+ @Description Modules registers offsets
+*//***************************************************************************/
+#define FM_MM_MURAM 0x00000000
+#define FM_MM_BMI 0x00080000
+#define FM_MM_QMI 0x00080400
+#define FM_MM_PRS 0x000c7000
+#define FM_MM_KG 0x000C1000
+#define FM_MM_DMA 0x000C2000
+#define FM_MM_FPM 0x000C3000
+#define FM_MM_PLCR 0x000C0000
+#define FM_MM_IMEM 0x000C4000
+
+/**************************************************************************//**
+ @Description Interrupt Enable/Mask
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Memory Mapped Registers
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct
+{
+ volatile uint32_t fpmtnc; /**< FPM TNUM Control */
+ volatile uint32_t fpmpr; /**< FPM Port_ID FmCtl Association */
+ volatile uint32_t brkc; /**< FPM Breakpoint Control */
+ volatile uint32_t fpmflc; /**< FPM Flush Control */
+ volatile uint32_t fpmdis1; /**< FPM Dispatch Thresholds1 */
+ volatile uint32_t fpmdis2; /**< FPM Dispatch Thresholds2 */
+ volatile uint32_t fmepi; /**< FM Error Pending Interrupts */
+ volatile uint32_t fmrie; /**< FM Error Interrupt Enable */
+ volatile uint32_t fmfpfcev[4]; /**< FPM FMan-Controller Event 1-4 */
+ volatile uint8_t res1[16]; /**< reserved */
+ volatile uint32_t fmfpfcee[4]; /**< PM FMan-Controller Event 1-4 */
+ volatile uint8_t res2[16]; /**< reserved */
+ volatile uint32_t fpmtsc1; /**< FPM TimeStamp Control1 */
+ volatile uint32_t fpmtsc2; /**< FPM TimeStamp Control2 */
+ volatile uint32_t fpmtsp; /**< FPM Time Stamp */
+ volatile uint32_t fpmtsf; /**< FPM Time Stamp Fraction */
+ volatile uint32_t fmrcr; /**< FM Rams Control */
+ volatile uint32_t fpmextc; /**< FPM External Requests Control */
+ volatile uint32_t fpmext1; /**< FPM External Requests Config1 */
+ volatile uint32_t fpmext2; /**< FPM External Requests Config2 */
+ volatile uint32_t fpmdrd[16]; /**< FPM Data_Ram Data 0-15 */
+ volatile uint32_t fpmdra; /**< FPM Data Ram Access */
+ volatile uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 */
+ volatile uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 */
+ volatile uint32_t fmrstc; /**< FM Reset Command */
+ volatile uint32_t fmcld; /**< FM Classifier Debug */
+ volatile uint32_t fmnpi; /**< FM Normal Pending Interrupts */
+ volatile uint32_t fmfp_exte; /**< FPM External Requests Enable */
+ volatile uint32_t fpmem; /**< FPM Event & Mask */
+ volatile uint32_t fpmcev[4]; /**< FPM CPU Event 1-4 */
+ volatile uint8_t res4[16]; /**< reserved */
+ volatile uint32_t fmfp_ps[0x40]; /**< FPM Port Status */
+ volatile uint8_t reserved1[0x260];
+ volatile uint32_t fpmts[128]; /**< 0x400: FPM Task Status */
+} _PackedType t_FmFpmRegs;
+
+#define NUM_OF_DBG_TRAPS 3
+
+typedef _Packed struct
+{
+ volatile uint32_t fmbm_init; /**< BMI Initialization */
+ volatile uint32_t fmbm_cfg1; /**< BMI Configuration 1 */
+ volatile uint32_t fmbm_cfg2; /**< BMI Configuration 2 */
+ volatile uint32_t reserved[5];
+ volatile uint32_t fmbm_ievr; /**< Interrupt Event Register */
+ volatile uint32_t fmbm_ier; /**< Interrupt Enable Register */
+ volatile uint32_t fmbm_ifr; /**< Interrupt Force Register */
+ volatile uint32_t reserved1[5];
+ volatile uint32_t fmbm_arb[8]; /**< BMI Arbitration */
+ volatile uint32_t reserved2[12];
+ volatile uint32_t fmbm_dtc[NUM_OF_DBG_TRAPS]; /**< BMI Debug Trap Counter */
+ volatile uint32_t reserved3;
+ volatile uint32_t fmbm_dcv[NUM_OF_DBG_TRAPS][4]; /**< BMI Debug Compare Value */
+ volatile uint32_t fmbm_dcm[NUM_OF_DBG_TRAPS][4]; /**< BMI Debug Compare Mask */
+ volatile uint32_t fmbm_gde; /**< BMI Global Debug Enable */
+ volatile uint32_t fmbm_pp[63]; /**< BMI Port Parameters */
+ volatile uint32_t reserved4;
+ volatile uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size */
+ volatile uint32_t reserved5;
+ volatile uint32_t fmbm_ppid[63]; /**< Port Partition ID */
+} _PackedType t_FmBmiRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t fmqm_gc; /**< General Configuration Register */
+ volatile uint32_t Reserved0;
+ volatile uint32_t fmqm_eie; /**< Error Interrupt Event Register */
+ volatile uint32_t fmqm_eien; /**< Error Interrupt Enable Register */
+ volatile uint32_t fmqm_eif; /**< Error Interrupt Force Register */
+ volatile uint32_t fmqm_ie; /**< Interrupt Event Register */
+ volatile uint32_t fmqm_ien; /**< Interrupt Enable Register */
+ volatile uint32_t fmqm_if; /**< Interrupt Force Register */
+ volatile uint32_t fmqm_gs; /**< Global Status Register */
+ volatile uint32_t fmqm_ts; /**< Task Status Register */
+ volatile uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter */
+ volatile uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter */
+ volatile uint32_t fmqm_dc0; /**< Dequeue Counter 0 */
+ volatile uint32_t fmqm_dc1; /**< Dequeue Counter 1 */
+ volatile uint32_t fmqm_dc2; /**< Dequeue Counter 2 */
+ volatile uint32_t fmqm_dc3; /**< Dequeue Counter 3 */
+ volatile uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter */
+ volatile uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter */
+ volatile uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter */
+ volatile uint32_t fmqm_dcc; /**< Dequeue Confirm Counter */
+ volatile uint32_t Reserved1a[7];
+ volatile uint32_t fmqm_tapc; /**< Tnum Aging Period Control */
+ volatile uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter */
+ volatile uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter */
+ volatile uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter */
+ volatile uint32_t Reserved1b;
+ volatile uint32_t fmqm_dtc; /**< 0x0080 Debug Trap Counter */
+ volatile uint32_t fmqm_efddd; /**< 0x0084 Enqueue Frame Descriptor Dynamic Debug */
+ volatile uint32_t Reserved3[2];
+ _Packed struct {
+ volatile uint32_t fmqm_dtcfg1; /**< 0x0090 Debug Trap Configuration 1 Register */
+ volatile uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register */
+ volatile uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register */
+ volatile uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register */
+ volatile uint32_t fmqm_dtcfg2; /**< Debug Trap Configuration 2 Register */
+ volatile uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register */
+ volatile uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register */
+ volatile uint32_t Reserved1;
+ } _PackedType dbgTraps[NUM_OF_DBG_TRAPS];
+} _PackedType t_FmQmiRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t fmdmsr; /**< FM DMA status register 0x04 */
+ volatile uint32_t fmdmmr; /**< FM DMA mode register 0x08 */
+ volatile uint32_t fmdmtr; /**< FM DMA bus threshold register 0x0c */
+ volatile uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x10 */
+ volatile uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x14 */
+ volatile uint32_t fmdmtah; /**< FM DMA transfer bus address high register 0x18 */
+ volatile uint32_t fmdmtal; /**< FM DMA transfer bus address low register 0x1C */
+ volatile uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID register 0x20 */
+ volatile uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x24 */
+ volatile uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x28 */
+ volatile uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x2C */
+ volatile uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x30 */
+ volatile uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug register 0x34 */
+ volatile uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value register #1 0x38 */
+ volatile uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value register #2 0x3C */
+ volatile uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x40 */
+ volatile uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x44 */
+ volatile uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x48 */
+ volatile uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Counter 0x50 */
+ volatile uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Counter 0x54 */
+ volatile uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x54 */
+ volatile uint32_t fmdmdcr; /**< FM DMA Debug Counter */
+ volatile uint32_t fmdmemsr; /**< FM DMA Emrgency Smoother Register */
+ volatile uint32_t reserved;
+ volatile uint32_t fmdmplr[FM_SIZE_OF_LIODN_TABLE/2];
+ /**< FM DMA PID-LIODN # register */
+} _PackedType t_FmDmaRegs;
+
+typedef _Packed struct
+{
+ volatile uint32_t iadd; /**< FM IRAM instruction address register */
+ volatile uint32_t idata; /**< FM IRAM instruction data register */
+ volatile uint32_t itcfg; /**< FM IRAM timing config register */
+ volatile uint32_t iready; /**< FM IRAM ready register */
+ volatile uint8_t res[0x80000-0x10];
+} _PackedType t_FMIramRegs;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/**************************************************************************//**
+ @Description General defines
+*//***************************************************************************/
+
+#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
+#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
+
+
+/**************************************************************************//**
+ @Description DMA definitions
+*//***************************************************************************/
+
+/* masks */
+#define DMA_MODE_AID_OR 0x20000000
+#define DMA_MODE_SBER 0x10000000
+#define DMA_MODE_BER 0x00200000
+#define DMA_MODE_ECC 0x00000020
+#define DMA_MODE_PRIVILEGE_PROT 0x00001000
+#define DMA_MODE_SECURE_PROT 0x00000800
+#define DMA_MODE_EMERGENCY_READ 0x00080000
+#define DMA_MODE_EMERGENCY_WRITE 0x00040000
+
+#define DMA_TRANSFER_PORTID_MASK 0xFF000000
+#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
+#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
+
+#define DMA_HIGH_LIODN_MASK 0x0FFF0000
+#define DMA_LOW_LIODN_MASK 0x00000FFF
+
+#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
+#define DMA_STATUS_BUS_ERR 0x08000000
+#define DMA_STATUS_READ_ECC 0x04000000
+#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
+#define DMA_STATUS_FM_WRITE_ECC 0x01000000
+#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
+#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
+#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
+#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
+#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
+
+#define FM_LIODN_BASE_MASK 0x00000FFF
+
+/* shifts */
+#define DMA_MODE_CACHE_OR_SHIFT 30
+#define DMA_MODE_BUS_PRI_SHIFT 16
+#define DMA_MODE_AXI_DBG_SHIFT 24
+#define DMA_MODE_CEN_SHIFT 13
+#define DMA_MODE_BUS_PROT_SHIFT 10
+#define DMA_MODE_DBG_SHIFT 7
+#define DMA_MODE_EMERGENCY_LEVEL_SHIFT 6
+#define DMA_MODE_AID_MODE_SHIFT 4
+#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
+#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
+
+#define DMA_THRESH_COMMQ_SHIFT 24
+#define DMA_THRESH_READ_INT_BUF_SHIFT 16
+
+#define DMA_LIODN_SHIFT 16
+
+#define DMA_TRANSFER_PORTID_SHIFT 24
+#define DMA_TRANSFER_TNUM_SHIFT 16
+
+/* sizes */
+#define DMA_MAX_WATCHDOG 0xffffffff
+
+/* others */
+#define DMA_CAM_SIZEOF_ENTRY 0x40
+#define DMA_CAM_ALIGN 0x1000
+#define DMA_CAM_UNITS 8
+
+
+/**************************************************************************//**
+ @Description FPM defines
+*//***************************************************************************/
+
+/* masks */
+#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
+#define FPM_EV_MASK_STALL 0x40000000
+#define FPM_EV_MASK_SINGLE_ECC 0x20000000
+#define FPM_EV_MASK_RELEASE_FM 0x00010000
+#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
+#define FPM_EV_MASK_STALL_EN 0x00004000
+#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
+#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
+#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
+
+#define FPM_RAM_CTL_RAMS_ECC_EN 0x80000000
+#define FPM_RAM_CTL_IRAM_ECC_EN 0x40000000
+#define FPM_RAM_CTL_MURAM_ECC 0x00008000
+#define FPM_RAM_CTL_IRAM_ECC 0x00004000
+#define FPM_RAM_CTL_MURAM_TEST_ECC 0x20000000
+#define FPM_RAM_CTL_IRAM_TEST_ECC 0x10000000
+#define FPM_RAM_CTL_RAMS_ECC_EN_SRC_SEL 0x08000000
+
+#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
+#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
+
+#define FPM_REV1_MAJOR_MASK 0x0000FF00
+#define FPM_REV1_MINOR_MASK 0x000000FF
+
+#define FPM_REV2_INTEG_MASK 0x00FF0000
+#define FPM_REV2_ERR_MASK 0x0000FF00
+#define FPM_REV2_CFG_MASK 0x000000FF
+
+#define FPM_TS_FRACTION_MASK 0x0000FFFF
+#define FPM_TS_CTL_EN 0x80000000
+
+#define FPM_PORT_FM_CTL1 0x00000001
+#define FPM_PORT_FM_CTL2 0x00000002
+#define FPM_PRC_REALSE_STALLED 0x00800000
+
+#define FPM_PS_STALLED 0x00800000
+#define FPM_PS_FM_CTL1_SEL 0x80000000
+#define FPM_PS_FM_CTL2_SEL 0x40000000
+#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
+
+#define FPM_RSTC_FM_RESET 0x80000000
+#define FPM_RSTC_10G0_RESET 0x04000000
+#define FPM_RSTC_1G0_RESET 0x40000000
+#define FPM_RSTC_1G1_RESET 0x20000000
+#define FPM_RSTC_1G2_RESET 0x10000000
+#define FPM_RSTC_1G3_RESET 0x08000000
+#define FPM_RSTC_1G4_RESET 0x02000000
+
+
+/* shifts */
+#define FPM_DISP_LIMIT_SHIFT 24
+
+#define FPM_THR1_PRS_SHIFT 24
+#define FPM_THR1_KG_SHIFT 16
+#define FPM_THR1_PLCR_SHIFT 8
+#define FPM_THR1_BMI_SHIFT 0
+
+#define FPM_THR2_QMI_ENQ_SHIFT 24
+#define FPM_THR2_QMI_DEQ_SHIFT 0
+#define FPM_THR2_FM_CTL1_SHIFT 16
+#define FPM_THR2_FM_CTL2_SHIFT 8
+
+#define FPM_EV_MASK_CAT_ERR_SHIFT 1
+#define FPM_EV_MASK_DMA_ERR_SHIFT 0
+
+#define FPM_REV1_MAJOR_SHIFT 8
+#define FPM_REV1_MINOR_SHIFT 0
+
+#define FPM_REV2_INTEG_SHIFT 16
+#define FPM_REV2_ERR_SHIFT 8
+#define FPM_REV2_CFG_SHIFT 0
+
+#define FPM_TS_INT_SHIFT 16
+
+#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
+
+#define FPM_PS_FM_CTL_SEL_SHIFT 30
+#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
+
+/* Interrupts defines */
+#define FPM_EVENT_FM_CTL_0 0x00008000
+#define FPM_EVENT_FM_CTL 0x0000FF00
+#define FPM_EVENT_FM_CTL_BRK 0x00000080
+
+/* others */
+#define FPM_MAX_DISP_LIMIT 31
+
+/**************************************************************************//**
+ @Description BMI defines
+*//***************************************************************************/
+/* masks */
+#define BMI_INIT_START 0x80000000
+#define BMI_ERR_INTR_EN_PIPELINE_ECC 0x80000000
+#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
+#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
+#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
+#define BMI_NUM_OF_TASKS_MASK 0x3F000000
+#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
+#define BMI_NUM_OF_DMAS_MASK 0x00000F00
+#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
+#define BMI_FIFO_SIZE_MASK 0x000003FF
+#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
+#define BMI_CFG2_DMAS_MASK 0x0000003F
+
+/* shifts */
+#define BMI_CFG2_TASKS_SHIFT 16
+#define BMI_CFG2_DMAS_SHIFT 0
+#define BMI_CFG1_FIFO_SIZE_SHIFT 16
+#define BMI_FIFO_SIZE_SHIFT 0
+#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
+#define BMI_NUM_OF_TASKS_SHIFT 24
+#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
+#define BMI_NUM_OF_DMAS_SHIFT 8
+#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
+
+/* others */
+#define BMI_FIFO_ALIGN 0x100
+
+
+/**************************************************************************//**
+ @Description QMI defines
+*//***************************************************************************/
+/* masks */
+#define QMI_CFG_ENQ_EN 0x80000000
+#define QMI_CFG_DEQ_EN 0x40000000
+#define QMI_CFG_EN_COUNTERS 0x10000000
+#define QMI_CFG_SOFT_RESET 0x01000000
+#define QMI_CFG_DEQ_MASK 0x0000003F
+#define QMI_CFG_ENQ_MASK 0x00003F00
+
+#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
+#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
+#define QMI_INTR_EN_SINGLE_ECC 0x80000000
+
+/* shifts */
+#define QMI_CFG_ENQ_SHIFT 8
+#define QMI_TAPC_TAP 22
+
+
+/**************************************************************************//**
+ @Description IRAM defines
+*//***************************************************************************/
+/* masks */
+#define IRAM_IADD_AIE 0x80000000
+#define IRAM_READY 0x80000000
+
+typedef struct {
+ void (*f_Isr) (t_Handle h_Arg, uint32_t event);
+ t_Handle h_SrcHandle;
+} t_FmanCtrlIntrSrc;
+
+
+typedef struct
+{
+ /* uint8_t numOfPartitions; */
+ bool resetOnInit;
+#ifdef FM_PARTITION_ARRAY
+ uint16_t liodnBasePerPort[FM_SIZE_OF_LIODN_TABLE];
+#endif
+ bool enCounters;
+ t_FmThresholds thresholds;
+ e_FmDmaCacheOverride dmaCacheOverride;
+ e_FmDmaAidMode dmaAidMode;
+ bool dmaAidOverride;
+ uint8_t dmaAxiDbgNumOfBeats;
+ uint8_t dmaCamNumOfEntries;
+ uint32_t dmaWatchdog;
+ t_FmDmaThresholds dmaCommQThresholds;
+ t_FmDmaThresholds dmaWriteBufThresholds;
+ t_FmDmaThresholds dmaReadBufThresholds;
+ uint32_t dmaSosEmergency;
+ e_FmDmaDbgCntMode dmaDbgCntMode;
+ bool dmaStopOnBusError;
+ bool dmaEnEmergency;
+ t_FmDmaEmergency dmaEmergency;
+ bool dmaEnEmergencySmoother;
+ uint32_t dmaEmergencySwitchCounter;
+ bool haltOnExternalActivation;
+ bool haltOnUnrecoverableEccError;
+ e_FmCatastrophicErr catastrophicErr;
+ e_FmDmaErr dmaErr;
+ bool enMuramTestMode;
+ bool enIramTestMode;
+ bool externalEccRamsEnable;
+ uint16_t tnumAgingPeriod;
+ t_FmPcdFirmwareParams firmware;
+ bool fwVerify;
+} t_FmDriverParam;
+
+typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
+
+typedef struct
+{
+/***************************/
+/* Master/Guest parameters */
+/***************************/
+ uint8_t fmId;
+ e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
+ uint16_t fmClkFreq;
+/**************************/
+/* Master Only parameters */
+/**************************/
+ bool enabledTimeStamp;
+ uint8_t count1MicroBit;
+ uint8_t totalNumOfTasks;
+ uint32_t totalFifoSize;
+ uint8_t maxNumOfOpenDmas;
+ uint8_t accumulatedNumOfTasks;
+ uint32_t accumulatedFifoSize;
+ uint8_t accumulatedNumOfOpenDmas;
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ uint8_t accumulatedNumOfDeqTnums;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+#ifdef FM_LOW_END_RESTRICTION
+ bool lowEndRestriction;
+#endif /* FM_LOW_END_RESTRICTION */
+ uint32_t exceptions;
+ int irq;
+ int errIrq;
+ bool ramsEccEnable;
+ bool explicitEnable;
+ bool internalCall;
+ uint8_t ramsEccOwners;
+ uint32_t extraFifoPoolSize;
+ uint8_t extraTasksPoolSize;
+ uint8_t extraOpenDmasPoolSize;
+#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
+ uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
+#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) */
+ uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
+} t_FmStateStruct;
+
+typedef struct
+{
+/***************************/
+/* Master/Guest parameters */
+/***************************/
+/* locals for recovery */
+ uintptr_t baseAddr;
+
+/* un-needed for recovery */
+ t_Handle h_Pcd;
+ char fmModuleName[MODULE_NAME_SIZE];
+ char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
+ t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
+ t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
+ uint8_t guestId;
+/**************************/
+/* Master Only parameters */
+/**************************/
+/* locals for recovery */
+ t_FmFpmRegs *p_FmFpmRegs;
+ t_FmBmiRegs *p_FmBmiRegs;
+ t_FmQmiRegs *p_FmQmiRegs;
+ t_FmDmaRegs *p_FmDmaRegs;
+ t_FmExceptionsCallback *f_Exception;
+ t_FmBusErrorCallback *f_BusError;
+ t_Handle h_App; /* Application handle */
+ t_Handle h_Spinlock;
+ bool recoveryMode;
+ t_FmStateStruct *p_FmStateStruct;
+
+/* un-needed for recovery */
+ t_FmDriverParam *p_FmDriverParam;
+ t_Handle h_FmMuram;
+ uint64_t fmMuramPhysBaseAddr;
+ bool independentMode;
+ bool hcPortInitialized;
+ uintptr_t camBaseAddr; /* save for freeing */
+ uintptr_t resAddr;
+ uintptr_t fifoBaseAddr; /* save for freeing */
+ t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
+ bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
+} t_Fm;
+
+
+#endif /* __FM_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/fm_guest.c b/sys/contrib/ncsw/Peripherals/FM/fm_guest.c
new file mode 100644
index 0000000..886f6a0
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/fm_guest.c
@@ -0,0 +1,35 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+
diff --git a/sys/contrib/ncsw/Peripherals/FM/fm_ipc.h b/sys/contrib/ncsw/Peripherals/FM/fm_ipc.h
new file mode 100644
index 0000000..7bb2e48
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/fm_ipc.h
@@ -0,0 +1,449 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_ipc.h
+
+ @Description FM Inter-Partition prototypes, structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_IPC_H
+#define __FM_IPC_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_IPC_grp FM Inter-Partition messaging Unit
+
+ @Description FM Inter-Partition messaging unit API definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/**************************************************************************//**
+ @Description enum for defining MAC types
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description A structure of parameters for specifying a MAC.
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint8_t id;
+ uint32_t enumType;
+} _PackedType t_FmIpcMacParams;
+
+/**************************************************************************//**
+ @Description A structure of parameters for specifying a MAC.
+*//***************************************************************************/
+typedef _Packed struct
+{
+ t_FmIpcMacParams macParams;
+ uint16_t maxFrameLength;
+} _PackedType t_FmIpcMacMaxFrameParams;
+
+/**************************************************************************//**
+ @Description FM physical Address
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcPhysAddr
+{
+ volatile uint8_t high;
+ volatile uint32_t low;
+} _PackedType t_FmIpcPhysAddr;
+
+/**************************************************************************//**
+ @Description Structure for IPC communication during FM_PORT_Init.
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcPortInInitParams {
+ uint8_t hardwarePortId; /**< IN. port Id */
+ uint32_t enumPortType; /**< IN. Port type */
+ uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
+ uint16_t liodnOffset; /**< IN. Port's requested resource */
+ uint8_t numOfTasks; /**< IN. Port's requested resource */
+ uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
+ uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
+ uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
+ uint32_t sizeOfFifo; /**< IN. Port's requested resource */
+ uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
+ uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
+ LIODN base for this port, to be
+ used together with LIODN offset. */
+} _PackedType t_FmIpcPortInInitParams;
+
+
+/**************************************************************************//**
+ @Description Structure for IPC communication between port and FM
+ regarding tasks and open DMA resources management.
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcPortRsrcParams {
+ uint8_t hardwarePortId; /**< IN. port Id */
+ uint32_t val; /**< IN. Port's requested resource */
+ uint32_t extra; /**< IN. Port's requested resource */
+ uint8_t boolInitialConfig;
+} _PackedType t_FmIpcPortRsrcParams;
+
+
+/**************************************************************************//**
+ @Description Structure for IPC communication between port and FM
+ regarding tasks and open DMA resources management.
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcPortFifoParams {
+ t_FmIpcPortRsrcParams rsrcParams;
+ uint32_t enumPortType;
+ uint8_t boolIndependentMode;
+ uint8_t deqPipelineDepth;
+ uint8_t numOfPools;
+ uint16_t secondLargestBufSize;
+ uint16_t largestBufSize;
+ uint8_t boolInitialConfig;
+} _PackedType t_FmIpcPortFifoParams;
+
+/**************************************************************************//**
+ @Description Structure for port-FM communication during FM_PORT_Free.
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcPortFreeParams {
+ uint8_t hardwarePortId; /**< IN. port Id */
+ uint32_t enumPortType; /**< IN. Port type */
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+} _PackedType t_FmIpcPortFreeParams;
+
+/**************************************************************************//**
+ @Description Structure for defining DMA status
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcDmaStatus {
+ uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
+ uint8_t boolBusError; /**< Bus error occurred */
+ uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
+ uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
+ uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
+} _PackedType t_FmIpcDmaStatus;
+
+typedef _Packed struct t_FmIpcRegisterIntr
+{
+ uint8_t guestId; /* IN */
+ uint32_t event; /* IN */
+} _PackedType t_FmIpcRegisterIntr;
+
+typedef _Packed struct t_FmIpcIsr
+{
+ uint8_t boolErr; /* IN */
+ uint32_t pendingReg; /* IN */
+} _PackedType t_FmIpcIsr;
+
+/**************************************************************************//**
+ @Description structure for returning revision information
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcRevisionInfo {
+ uint8_t majorRev; /**< OUT: Major revision */
+ uint8_t minorRev; /**< OUT: Minor revision */
+} _PackedType t_FmIpcRevisionInfo;
+
+/**************************************************************************//**
+ @Description Structure for defining Fm number of Fman controlers
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
+ uint8_t hardwarePortId; /**< IN. port Id */
+ uint8_t numOfFmanCtrls; /**< IN. Port type */
+} t_FmIpcPortNumOfFmanCtrls;
+
+/**************************************************************************//**
+ @Description structure for setting Fman contriller events
+*//***************************************************************************/
+typedef _Packed struct t_FmIpcFmanEvents {
+ uint8_t eventRegId; /**< IN: Fman controller event register id */
+ uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
+} _PackedType t_FmIpcFmanEvents;
+
+#define FM_IPC_MAX_REPLY_BODY_SIZE 16
+#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
+#define FM_IPC_MAX_MSG_SIZE 30
+typedef _Packed struct t_FmIpcMsg
+{
+ uint32_t msgId;
+ uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
+} _PackedType t_FmIpcMsg;
+
+typedef _Packed struct t_FmIpcReply
+{
+ uint32_t error;
+ uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
+} _PackedType t_FmIpcReply;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/***************************************************************************/
+/************************ FRONT-END-TO-BACK-END*****************************/
+/***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_GET_TIMESTAMP_SCALE
+
+ @Description Used by FM front-end.
+
+ @Param[out] uint32_t Pointer
+*//***************************************************************************/
+#define FM_GET_TIMESTAMP_SCALE 1
+
+/**************************************************************************//**
+ @Function FM_GET_COUNTER
+
+ @Description Used by FM front-end.
+
+ @Param[in/out] t_FmIpcGetCounter Pointer
+*//***************************************************************************/
+#define FM_GET_COUNTER 2
+
+/**************************************************************************//**
+ @Function FM_DUMP_REGS
+
+ @Description Used by FM front-end for the PORT module in order to set and get
+ parameters in/from master FM module on FM PORT initialization time.
+
+ @Param None
+*//***************************************************************************/
+#define FM_DUMP_REGS 3
+
+/**************************************************************************//**
+ @Function FM_GET_SET_PORT_PARAMS
+
+ @Description Used by FM front-end for the PORT module in order to set and get
+ parameters in/from master FM module on FM PORT initialization time.
+
+ @Param[in/out] t_FmIcPortInitParams Pointer
+*//***************************************************************************/
+#define FM_GET_SET_PORT_PARAMS 4
+
+/**************************************************************************//**
+ @Function FM_FREE_PORT
+
+ @Description Used by FM front-end for the PORT module when a port is freed
+ to free all FM PORT resources.
+
+ @Param[in] uint8_t Pointer
+*//***************************************************************************/
+#define FM_FREE_PORT 5
+
+/**************************************************************************//**
+ @Function FM_RESET_MAC
+
+ @Description Used by front-end for the MAC module to reset the MAC registers
+
+ @Param[in] t_FmIpcMacParams Pointer .
+*//***************************************************************************/
+#define FM_RESET_MAC 6
+
+/**************************************************************************//**
+ @Function FM_RESUME_STALLED_PORT
+
+ @Description Used by FM front-end for the PORT module in order to
+ release a stalled FM Port.
+
+ @Param[in] uint8_t Pointer
+*//***************************************************************************/
+#define FM_RESUME_STALLED_PORT 7
+
+/**************************************************************************//**
+ @Function FM_IS_PORT_STALLED
+
+ @Description Used by FM front-end for the PORT module in order to check whether
+ an FM port is stalled.
+
+ @Param[in/out] t_FmIcPortIsStalled Pointer
+*//***************************************************************************/
+#define FM_IS_PORT_STALLED 8
+
+/**************************************************************************//**
+ @Function FM_DUMP_PORT_REGS
+
+ @Description Used by FM front-end for the PORT module in order to dump
+ all port registers.
+
+ @Param[in] uint8_t Pointer
+*//***************************************************************************/
+#define FM_DUMP_PORT_REGS 9
+
+/**************************************************************************//**
+ @Function FM_GET_REV
+
+ @Description Used by FM front-end for the PORT module in order to dump
+ all port registers.
+
+ @Param[in] uint8_t Pointer
+*//***************************************************************************/
+#define FM_GET_REV 10
+
+/**************************************************************************//**
+ @Function FM_REGISTER_INTR
+
+ @Description Used by FM front-end to register an interrupt handler to
+ be called upon interrupt for guest.
+
+ @Param[out] t_FmIpcRegisterIntr Pointer
+*//***************************************************************************/
+#define FM_REGISTER_INTR 11
+
+/**************************************************************************//**
+ @Function FM_GET_CLK_FREQ
+
+ @Description Used by FM Front-end to read the FM clock frequency.
+
+ @Param[out] uint32_t Pointer
+*//***************************************************************************/
+#define FM_GET_CLK_FREQ 12
+
+/**************************************************************************//**
+ @Function FM_DMA_STAT
+
+ @Description Used by FM front-end to read the FM DMA status.
+
+ @Param[out] t_FmIpcDmaStatus Pointer
+*//***************************************************************************/
+#define FM_DMA_STAT 13
+
+/**************************************************************************//**
+ @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
+
+ @Description Used by FM front-end to allocate event register.
+
+ @Param[out] Event register id Pointer
+*//***************************************************************************/
+#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
+
+/**************************************************************************//**
+ @Function FM_FREE_FMAN_CTRL_EVENT_REG
+
+ @Description Used by FM front-end to free locate event register.
+
+ @Param[in] uint8_t Pointer - Event register id
+*//***************************************************************************/
+#define FM_FREE_FMAN_CTRL_EVENT_REG 15
+
+/**************************************************************************//**
+ @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
+
+ @Description Used by FM front-end to enable events in the FPM
+ Fman controller event register.
+
+ @Param[in] t_FmIpcFmanEvents Pointer
+*//***************************************************************************/
+#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
+
+/**************************************************************************//**
+ @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
+
+ @Description Used by FM front-end to enable events in the FPM
+ Fman controller event register.
+
+ @Param[in/out] t_FmIpcFmanEvents Pointer
+*//***************************************************************************/
+#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
+
+/**************************************************************************//**
+ @Function FM_SET_MAC_MAX_FRAME
+
+ @Description Used by FM front-end to set MAC's MTU/RTU's in
+ back-end.
+
+ @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
+*//***************************************************************************/
+#define FM_SET_MAC_MAX_FRAME 18
+
+/**************************************************************************//**
+ @Function FM_GET_PHYS_MURAM_BASE
+
+ @Description Used by FM front-end in order to get MURAM base address
+
+ @Param[in/out] t_FmIpcPhysAddr Pointer
+*//***************************************************************************/
+#define FM_GET_PHYS_MURAM_BASE 19
+
+/**************************************************************************//**
+ @Function FM_MASTER_IS_ALIVE
+
+ @Description Used by FM front-end in order to verify Master is up
+
+ @Param[in/out] bool
+*//***************************************************************************/
+#define FM_MASTER_IS_ALIVE 20
+
+#define FM_ENABLE_RAM_ECC 21
+#define FM_DISABLE_RAM_ECC 22
+#define FM_SET_NUM_OF_FMAN_CTRL 23
+#define FM_SET_SIZE_OF_FIFO 24
+#define FM_SET_NUM_OF_TASKS 25
+#define FM_SET_NUM_OF_OPEN_DMAS 26
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+#define FM_10G_TX_ECC_WA 100
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+/***************************************************************************/
+/************************ BACK-END-TO-FRONT-END*****************************/
+/***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_GUEST_ISR
+
+ @Description Used by FM back-end to report an interrupt to the front-end.
+
+ @Param[out] t_FmIpcIsr Pointer
+*//***************************************************************************/
+#define FM_GUEST_ISR 1
+
+
+
+/** @} */ /* end of FM_IPC_grp group */
+/** @} */ /* end of FM_grp group */
+
+
+#endif /* __FM_IPC_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/fm_muram.c b/sys/contrib/ncsw/Peripherals/FM/fm_muram.c
new file mode 100644
index 0000000..e52f233
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/fm_muram.c
@@ -0,0 +1,164 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File FM_muram.c
+
+ @Description FM MURAM ...
+*//***************************************************************************/
+#include "error_ext.h"
+#include "std_ext.h"
+#include "mm_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "fm_muram_ext.h"
+#include "fm_common.h"
+
+
+#define __ERR_MODULE__ MODULE_FM_MURAM
+
+
+typedef struct
+{
+ t_Handle h_Mem;
+ uintptr_t baseAddr;
+ uint32_t size;
+} t_FmMuram;
+
+
+void FmMuramClear(t_Handle h_FmMuram)
+{
+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
+
+ SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
+ IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
+}
+
+
+t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
+{
+ t_Handle h_Mem;
+ t_FmMuram *p_FmMuram;
+
+ if (!baseAddress)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
+ return NULL;
+ }
+
+ if (baseAddress%4)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
+ return NULL;
+ }
+
+ /* Allocate FM MURAM structure */
+ p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
+ if (!p_FmMuram)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
+ return NULL;
+ }
+ memset(p_FmMuram, 0, sizeof(t_FmMuram));
+
+
+ if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
+ {
+ XX_Free(p_FmMuram);
+ REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
+ return NULL;
+ }
+
+ /* Initialize FM MURAM parameters which will be kept by the driver */
+ p_FmMuram->baseAddr = baseAddress;
+ p_FmMuram->size = size;
+ p_FmMuram->h_Mem = h_Mem;
+
+ return p_FmMuram;
+}
+
+t_Error FM_MURAM_Free(t_Handle h_FmMuram)
+{
+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
+
+ if (p_FmMuram->h_Mem)
+ MM_Free(p_FmMuram->h_Mem);
+
+ XX_Free(h_FmMuram);
+
+ return E_OK;
+}
+
+void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
+{
+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
+ uintptr_t addr;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
+
+ addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
+
+ if (addr == ILLEGAL_BASE)
+ return NULL;
+
+ return UINT_TO_PTR(addr);
+}
+
+void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
+{
+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
+ uintptr_t addr;
+
+ SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
+
+ addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
+
+ if (addr == ILLEGAL_BASE)
+ return NULL;
+
+ return UINT_TO_PTR(addr);
+}
+
+t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
+{
+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
+
+ SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
+
+ if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
+ RETURN_ERROR(MINOR, E_INVALID_HANDLE, ("memory pointer!!!"));
+
+ return E_OK;
+}
diff --git a/sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h b/sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h
new file mode 100644
index 0000000..d1aaa3d
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/inc/fm_common.h
@@ -0,0 +1,1173 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File fm_common.h
+
+ @Description FM internal structures and definitions.
+*//***************************************************************************/
+#ifndef __FM_COMMON_H
+#define __FM_COMMON_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "fm_pcd_ext.h"
+#include "fm_port_ext.h"
+
+#define CLS_PLAN_NUM_PER_GRP 8
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/**************************************************************************//**
+ @Description PCD KG scheme registers
+*//***************************************************************************/
+typedef _Packed struct t_FmPcdPlcrInterModuleProfileRegs {
+ volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
+ volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
+ volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
+ volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
+ volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
+ volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
+ volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
+ volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
+ volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
+ volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
+ volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
+ volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
+ volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
+ volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
+ volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
+ volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
+ volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
+} _PackedType t_FmPcdPlcrInterModuleProfileRegs;
+
+/**************************************************************************//**
+ @Description PCD KG scheme registers
+*//***************************************************************************/
+typedef _Packed struct t_FmPcdKgInterModuleSchemeRegs {
+ volatile uint32_t kgse_mode; /**< MODE */
+ volatile uint32_t kgse_ekfc; /**< Extract Known Fields Command */
+ volatile uint32_t kgse_ekdv; /**< Extract Known Default Value */
+ volatile uint32_t kgse_bmch; /**< Bit Mask Command High */
+ volatile uint32_t kgse_bmcl; /**< Bit Mask Command Low */
+ volatile uint32_t kgse_fqb; /**< Frame Queue Base */
+ volatile uint32_t kgse_hc; /**< Hash Command */
+ volatile uint32_t kgse_ppc; /**< Policer Profile Command */
+ volatile uint32_t kgse_gec[FM_PCD_KG_NUM_OF_GENERIC_REGS];
+ /**< Generic Extract Command */
+ volatile uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
+ volatile uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
+ volatile uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
+ volatile uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
+ volatile uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
+} _PackedType t_FmPcdKgInterModuleSchemeRegs;
+
+typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
+ volatile uint32_t portIdAndCapwapReassmTbl;
+ volatile uint32_t fqidForTimeOutFrames;
+ volatile uint32_t timeoutRequestTime;
+}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
+
+
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+typedef struct {
+ uint8_t baseEntry;
+ uint16_t numOfClsPlanEntries;
+ uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
+} t_FmPcdKgInterModuleClsPlanSet;
+
+/**************************************************************************//**
+ @Description Structure for binding a port to keygen schemes.
+*//***************************************************************************/
+typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
+ uint8_t hardwarePortId;
+ uint8_t netEnvId;
+ bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
+ uint8_t numOfSchemes;
+ uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
+} t_FmPcdKgInterModuleBindPortToSchemes;
+
+typedef struct {
+ uint32_t nextCcNodeInfo;
+ t_List node;
+} t_CcNodeInfo;
+
+typedef struct
+{
+ t_Handle h_CcNode;
+ uint16_t index;
+ t_List node;
+}t_CcNodeInformation;
+#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
+
+typedef struct
+{
+ t_Handle h_Manip;
+ t_List node;
+}t_ManipInfo;
+#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
+
+typedef struct {
+ uint32_t type;
+ uint8_t prOffset;
+
+ uint16_t dataOffset;
+ uint8_t poolIndex;
+
+ uint8_t poolIdForManip;
+ uint8_t numOfTasks;
+
+ uint8_t hardwarePortId;
+
+} t_GetCcParams;
+
+typedef struct {
+ uint32_t type;
+ int psoSize;
+ uint32_t nia;
+
+} t_SetCcParams;
+
+typedef struct {
+ t_GetCcParams getCcParams;
+ t_SetCcParams setCcParams;
+} t_FmPortGetSetCcParams;
+
+
+static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
+{
+ uint32_t intFlags;
+ if (h_Spinlock)
+ intFlags = XX_LockIntrSpinlock(h_Spinlock);
+ else
+ intFlags = XX_DisableAllIntr();
+ if (*p_Flag)
+ {
+ if (h_Spinlock)
+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
+ else
+ XX_RestoreAllIntr(intFlags);
+ return FALSE;
+ }
+ *p_Flag = TRUE;
+ if (h_Spinlock)
+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
+ else
+ XX_RestoreAllIntr(intFlags);
+ return TRUE;
+}
+
+#define RELEASE_LOCK(_flag) _flag = FALSE;
+
+/**************************************************************************//**
+ @Collection Defines used for manipulation CC and BMI
+ @{
+*//***************************************************************************/
+#define INTERNAL_CONTEXT_OFFSET 0x80000000
+#define OFFSET_OF_PR 0x40000000
+#define BUFFER_POOL_ID_FOR_MANIP 0x20000000
+#define NUM_OF_TASKS 0x10000000
+#define OFFSET_OF_DATA 0x08000000
+#define HW_PORT_ID 0x04000000
+
+
+#define UPDATE_NIA_PNEN 0x80000000
+#define UPDATE_PSO 0x40000000
+#define UPDATE_NIA_PNDN 0x20000000
+#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
+/* @} */
+
+/**************************************************************************//**
+ @Collection Defines used for manipulation CC and CC
+ @{
+*//***************************************************************************/
+#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
+#define UPDATE_CC_WITH_TREE 0x40000000
+#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
+/* @} */
+
+/**************************************************************************//**
+ @Collection Defines used for enabling/disabling FM interrupts
+ @{
+*//***************************************************************************/
+typedef uint32_t t_FmBlockErrIntrEnable;
+
+#define ERR_INTR_EN_DMA 0x00010000
+#define ERR_INTR_EN_FPM 0x80000000
+#define ERR_INTR_EN_BMI 0x00800000
+#define ERR_INTR_EN_QMI 0x00400000
+#define ERR_INTR_EN_PRS 0x00200000
+#define ERR_INTR_EN_KG 0x00100000
+#define ERR_INTR_EN_PLCR 0x00080000
+#define ERR_INTR_EN_MURAM 0x00040000
+#define ERR_INTR_EN_IRAM 0x00020000
+#define ERR_INTR_EN_10G_MAC0 0x00008000
+#define ERR_INTR_EN_1G_MAC0 0x00004000
+#define ERR_INTR_EN_1G_MAC1 0x00002000
+#define ERR_INTR_EN_1G_MAC2 0x00001000
+#define ERR_INTR_EN_1G_MAC3 0x00000800
+#define ERR_INTR_EN_1G_MAC4 0x00000400
+#define ERR_INTR_EN_MACSEC_MAC0 0x00000200
+
+
+typedef uint32_t t_FmBlockIntrEnable;
+
+#define INTR_EN_BMI 0x80000000
+#define INTR_EN_QMI 0x40000000
+#define INTR_EN_PRS 0x20000000
+#define INTR_EN_KG 0x10000000
+#define INTR_EN_PLCR 0x08000000
+#define INTR_EN_1G_MAC0_TMR 0x00080000
+#define INTR_EN_1G_MAC1_TMR 0x00040000
+#define INTR_EN_1G_MAC2_TMR 0x00020000
+#define INTR_EN_1G_MAC3_TMR 0x00010000
+#define INTR_EN_1G_MAC4_TMR 0x00000040
+#define INTR_EN_REV0 0x00008000
+#define INTR_EN_REV1 0x00004000
+#define INTR_EN_REV2 0x00002000
+#define INTR_EN_REV3 0x00001000
+#define INTR_EN_BRK 0x00000080
+#define INTR_EN_TMR 0x01000000
+#define INTR_EN_MACSEC_MAC0 0x00000001
+/* @} */
+
+#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
+ FM_MAX_NUM_OF_1G_RX_PORTS + \
+ FM_MAX_NUM_OF_10G_RX_PORTS + \
+ FM_MAX_NUM_OF_1G_TX_PORTS + \
+ FM_MAX_NUM_OF_10G_TX_PORTS)
+
+#define MODULE_NAME_SIZE 30
+#define DUMMY_PORT_ID 0
+
+#define FM_LIODN_OFFSET_MASK 0x3FF
+
+/**************************************************************************//**
+ @Description NIA Description
+*//***************************************************************************/
+#define NIA_ORDER_RESTOR 0x00800000
+#define NIA_ENG_FM_CTL 0x00000000
+#define NIA_ENG_PRS 0x00440000
+#define NIA_ENG_KG 0x00480000
+#define NIA_ENG_PLCR 0x004C0000
+#define NIA_ENG_BMI 0x00500000
+#define NIA_ENG_QMI_ENQ 0x00540000
+#define NIA_ENG_QMI_DEQ 0x00580000
+#define NIA_ENG_MASK 0x007C0000
+
+#define NIA_FM_CTL_AC_CC 0x00000006
+#define NIA_FM_CTL_AC_HC 0x0000000C
+#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
+#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
+#define NIA_FM_CTL_AC_FRAG 0x0000000e
+#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
+#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
+#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
+#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
+#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
+#define NIA_FM_CTL_AC_MASK 0x0000001f
+
+#define NIA_BMI_AC_ENQ_FRAME 0x00000002
+#define NIA_BMI_AC_TX_RELEASE 0x000002C0
+#define NIA_BMI_AC_RELEASE 0x000000C0
+#define NIA_BMI_AC_DISCARD 0x000000C1
+#define NIA_BMI_AC_TX 0x00000274
+#define NIA_BMI_AC_FETCH 0x00000208
+#define NIA_BMI_AC_MASK 0x000003FF
+
+#define NIA_KG_DIRECT 0x00000100
+#define NIA_KG_CC_EN 0x00000200
+#define NIA_PLCR_ABSOLUTE 0x00008000
+
+#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
+
+/**************************************************************************//**
+ @Description Port Id defines
+*//***************************************************************************/
+#define BASE_OH_PORTID 1
+#define BASE_1G_RX_PORTID 8
+#define BASE_10G_RX_PORTID 0x10
+#define BASE_1G_TX_PORTID 0x28
+#define BASE_10G_TX_PORTID 0x30
+
+#define FM_PCD_PORT_OH_BASE_INDX 0
+#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
+#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
+#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
+#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
+
+#if (FM_MAX_NUM_OF_OH_PORTS > 0)
+#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
+ if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
+#else
+#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
+#endif
+#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
+#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
+ if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
+#else
+#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
+#endif
+#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
+#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
+ if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
+#else
+#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
+#endif
+#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
+#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
+ if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
+#else
+#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
+#endif
+#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
+#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
+ if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
+#else
+#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
+#endif
+
+
+#define SW_PORT_ID_TO_HW_PORT_ID(_port, _type, _relativePortId) \
+switch(_type) { \
+ case(e_FM_PORT_TYPE_OH_OFFLINE_PARSING): \
+ case(e_FM_PORT_TYPE_OH_HOST_COMMAND): \
+ CHECK_PORT_ID_OH_PORTS(_relativePortId); \
+ _port = (uint8_t)(BASE_OH_PORTID + (_relativePortId)); \
+ break; \
+ case(e_FM_PORT_TYPE_RX): \
+ CHECK_PORT_ID_1G_RX_PORTS(_relativePortId); \
+ _port = (uint8_t)(BASE_1G_RX_PORTID + (_relativePortId)); \
+ break; \
+ case(e_FM_PORT_TYPE_RX_10G): \
+ CHECK_PORT_ID_10G_RX_PORTS(_relativePortId); \
+ _port = (uint8_t)(BASE_10G_RX_PORTID + (_relativePortId)); \
+ break; \
+ case(e_FM_PORT_TYPE_TX): \
+ CHECK_PORT_ID_1G_TX_PORTS(_relativePortId); \
+ _port = (uint8_t)(BASE_1G_TX_PORTID + (_relativePortId)); \
+ break; \
+ case(e_FM_PORT_TYPE_TX_10G): \
+ CHECK_PORT_ID_10G_TX_PORTS(_relativePortId); \
+ _port = (uint8_t)(BASE_10G_TX_PORTID + (_relativePortId)); \
+ break; \
+ default: \
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type")); \
+ _port = 0; \
+ break; \
+}
+
+#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
+{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
+ ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
+ else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
+ ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
+ else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
+ ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
+ else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
+ ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
+ else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
+ ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
+ else { \
+ _relativePortId = (uint8_t)DUMMY_PORT_ID; \
+ ASSERT_COND(TRUE); \
+ } \
+}
+
+#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
+do { \
+ if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
+ else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
+ ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
+ else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
+ ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
+ else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
+ ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
+ else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
+ ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
+ else ASSERT_COND(FALSE); \
+} while (0)
+
+#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
+do { \
+ if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
+ else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
+ else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
+ else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
+ else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
+ else ASSERT_COND(FALSE); \
+} while (0)
+
+#define BMI_FIFO_UNITS 0x100
+
+typedef struct {
+ void (*f_Isr) (t_Handle h_Arg);
+ t_Handle h_SrcHandle;
+ uint8_t guestId;
+} t_FmIntrSrc;
+
+#define ILLEGAL_HDR_NUM 0xFF
+#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
+
+#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
+ ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
+#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
+
+#define GET_PRS_HDR_NUM(num, hdr) \
+switch(hdr) \
+{ case(HEADER_TYPE_ETH): num = 0; break; \
+ case(HEADER_TYPE_LLC_SNAP): num = 1; break; \
+ case(HEADER_TYPE_VLAN): num = 2; break; \
+ case(HEADER_TYPE_PPPoE): num = 3; break; \
+ case(HEADER_TYPE_MPLS): num = 4; break; \
+ case(HEADER_TYPE_IPv4): num = 5; break; \
+ case(HEADER_TYPE_IPv6): num = 6; break; \
+ case(HEADER_TYPE_GRE): num = 7; break; \
+ case(HEADER_TYPE_MINENCAP): num = 8; break; \
+ case(HEADER_TYPE_USER_DEFINED_L3): num = 9; break; \
+ case(HEADER_TYPE_TCP): num = 10; break; \
+ case(HEADER_TYPE_UDP): num = 11; break; \
+ case(HEADER_TYPE_IPSEC_AH): \
+ case(HEADER_TYPE_IPSEC_ESP): num = 12; break; \
+ case(HEADER_TYPE_SCTP): num = 13; break; \
+ case(HEADER_TYPE_DCCP): num = 14; break; \
+ case(HEADER_TYPE_USER_DEFINED_L4): num = 15; break; \
+ case(HEADER_TYPE_USER_DEFINED_SHIM1): \
+ case(HEADER_TYPE_USER_DEFINED_SHIM2): \
+ case(HEADER_TYPE_MACSEC): \
+ num = NO_HDR_NUM; break; \
+ default: \
+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header for parser"));\
+ num = ILLEGAL_HDR_NUM; break; \
+}
+
+/***********************************************************************/
+/* Policer defines */
+/***********************************************************************/
+#define FM_PCD_PLCR_PAR_GO 0x80000000
+#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
+#define FM_PCD_PLCR_PAR_R 0x40000000
+
+/* shifts */
+#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
+
+
+/***********************************************************************/
+/* Keygen defines */
+/***********************************************************************/
+/* maskes */
+#define KG_SCH_PP_SHIFT_HIGH 0x80000000
+#define KG_SCH_PP_NO_GEN 0x10000000
+#define KG_SCH_PP_SHIFT_LOW 0x0000F000
+#define KG_SCH_MODE_NIA_PLCR 0x40000000
+#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
+#define KG_SCH_BITMASK_MASK 0x000000FF
+#define KG_SCH_GEN_VALID 0x80000000
+#define KG_SCH_GEN_MASK 0x00FF0000
+#define FM_PCD_KG_KGAR_ERR 0x20000000
+#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
+#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
+#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
+#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
+#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
+#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
+#define KG_SCH_HASH_CONFIG_SYM 0x40000000
+
+#define FM_PCD_KG_KGAR_GO 0x80000000
+#define FM_PCD_KG_KGAR_READ 0x40000000
+#define FM_PCD_KG_KGAR_WRITE 0x00000000
+#define FM_PCD_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
+#define FM_PCD_KG_KGAR_SCHEME_WSEL_UPDATE_CNT 0x00008000
+
+
+typedef uint32_t t_KnownFieldsMasks;
+
+#define KG_SCH_KN_PORT_ID 0x80000000
+#define KG_SCH_KN_MACDST 0x40000000
+#define KG_SCH_KN_MACSRC 0x20000000
+#define KG_SCH_KN_TCI1 0x10000000
+#define KG_SCH_KN_TCI2 0x08000000
+#define KG_SCH_KN_ETYPE 0x04000000
+#define KG_SCH_KN_PPPSID 0x02000000
+#define KG_SCH_KN_PPPID 0x01000000
+#define KG_SCH_KN_MPLS1 0x00800000
+#define KG_SCH_KN_MPLS2 0x00400000
+#define KG_SCH_KN_MPLS_LAST 0x00200000
+#define KG_SCH_KN_IPSRC1 0x00100000
+#define KG_SCH_KN_IPDST1 0x00080000
+#define KG_SCH_KN_PTYPE1 0x00040000
+#define KG_SCH_KN_IPTOS_TC1 0x00020000
+#define KG_SCH_KN_IPV6FL1 0x00010000
+#define KG_SCH_KN_IPSRC2 0x00008000
+#define KG_SCH_KN_IPDST2 0x00004000
+#define KG_SCH_KN_PTYPE2 0x00002000
+#define KG_SCH_KN_IPTOS_TC2 0x00001000
+#define KG_SCH_KN_IPV6FL2 0x00000800
+#define KG_SCH_KN_GREPTYPE 0x00000400
+#define KG_SCH_KN_IPSEC_SPI 0x00000200
+#define KG_SCH_KN_IPSEC_NH 0x00000100
+#define KG_SCH_KN_L4PSRC 0x00000004
+#define KG_SCH_KN_L4PDST 0x00000002
+#define KG_SCH_KN_TFLG 0x00000001
+
+typedef uint8_t t_GenericCodes;
+
+#define KG_SCH_GEN_SHIM1 0x70
+#define KG_SCH_GEN_DEFAULT 0x10
+#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
+#define KG_SCH_GEN_START_OF_FRM 0x40
+#define KG_SCH_GEN_SHIM2 0x71
+#define KG_SCH_GEN_IP_PID_NO_V 0x72
+#define KG_SCH_GEN_ETH 0x03
+#define KG_SCH_GEN_ETH_NO_V 0x73
+#define KG_SCH_GEN_SNAP 0x04
+#define KG_SCH_GEN_SNAP_NO_V 0x74
+#define KG_SCH_GEN_VLAN1 0x05
+#define KG_SCH_GEN_VLAN1_NO_V 0x75
+#define KG_SCH_GEN_VLAN2 0x06
+#define KG_SCH_GEN_VLAN2_NO_V 0x76
+#define KG_SCH_GEN_ETH_TYPE 0x07
+#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
+#define KG_SCH_GEN_PPP 0x08
+#define KG_SCH_GEN_PPP_NO_V 0x78
+#define KG_SCH_GEN_MPLS1 0x09
+#define KG_SCH_GEN_MPLS2 0x19
+#define KG_SCH_GEN_MPLS3 0x29
+#define KG_SCH_GEN_MPLS1_NO_V 0x79
+#define KG_SCH_GEN_MPLS_LAST 0x0a
+#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
+#define KG_SCH_GEN_IPV4 0x0b
+#define KG_SCH_GEN_IPV6 0x1b
+#define KG_SCH_GEN_L3_NO_V 0x7b
+#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
+#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
+#define KG_SCH_GEN_MIN_ENCAP 0x2c
+#define KG_SCH_GEN_IP2_NO_V 0x7c
+#define KG_SCH_GEN_GRE 0x0d
+#define KG_SCH_GEN_GRE_NO_V 0x7d
+#define KG_SCH_GEN_TCP 0x0e
+#define KG_SCH_GEN_UDP 0x1e
+#define KG_SCH_GEN_IPSEC_AH 0x2e
+#define KG_SCH_GEN_SCTP 0x3e
+#define KG_SCH_GEN_DCCP 0x4e
+#define KG_SCH_GEN_IPSEC_ESP 0x6e
+#define KG_SCH_GEN_L4_NO_V 0x7e
+#define KG_SCH_GEN_NEXTHDR 0x7f
+
+/* shifts */
+#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
+#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
+#define KG_SCH_PP_MASK_SHIFT 16
+#define KG_SCH_MODE_CCOBASE_SHIFT 24
+#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
+#define KG_SCH_DEF_TCI_SHIFT 28
+#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
+#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
+#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
+#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
+#define KG_SCH_DEF_IP_ADDR_SHIFT 18
+#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
+#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
+#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
+#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
+#define KG_SCH_DEF_L4_PORT_SHIFT 8
+#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
+#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
+#define KG_SCH_GEN_MASK_SHIFT 16
+#define KG_SCH_GEN_HT_SHIFT 8
+#define KG_SCH_GEN_SIZE_SHIFT 24
+#define KG_SCH_GEN_DEF_SHIFT 29
+#define FM_PCD_KG_KGAR_NUM_SHIFT 16
+
+
+/* others */
+#define NUM_OF_SW_DEFAULTS 3
+#define MAX_PP_SHIFT 15
+#define MAX_KG_SCH_SIZE 16
+#define MASK_FOR_GENERIC_BASE_ID 0x20
+#define MAX_HASH_SHIFT 40
+#define MAX_KG_SCH_FQID_BIT_OFFSET 31
+#define MAX_KG_SCH_PP_BIT_OFFSET 15
+#define MAX_DIST_FQID_SHIFT 23
+
+#define GET_MASK_SEL_SHIFT(shift,i) \
+switch(i) { \
+ case(0):shift = 26;break; \
+ case(1):shift = 20;break; \
+ case(2):shift = 10;break; \
+ case(3):shift = 4;break; \
+ default: \
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);\
+}
+
+#define GET_MASK_OFFSET_SHIFT(shift,i) \
+switch(i) { \
+ case(0):shift = 16;break; \
+ case(1):shift = 0;break; \
+ case(2):shift = 28;break; \
+ case(3):shift = 24;break; \
+ default: \
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);\
+}
+
+#define GET_MASK_SHIFT(shift,i) \
+switch(i) { \
+ case(0):shift = 24;break; \
+ case(1):shift = 16;break; \
+ case(2):shift = 8;break; \
+ case(3):shift = 0;break; \
+ default: \
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);\
+}
+
+#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
+
+typedef struct {
+ uint16_t num;
+ uint8_t hardwarePortId;
+ uint16_t plcrProfilesBase;
+} t_FmPortPcdInterModulePlcrParams;
+
+/**************************************************************************//**
+ @Description A structure for initializing a keygen classification plan group
+*//***************************************************************************/
+typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
+ uint8_t netEnvId; /* IN */
+ bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
+ uint8_t clsPlanGrpId; /* OUT */
+ bool emptyClsPlanGrp; /* OUT */
+ uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
+ protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
+ /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
+ uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
+ /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
+} t_FmPcdKgInterModuleClsPlanGrpParams;
+
+typedef struct t_FmInterModulePortRxPoolsParams
+{
+ uint8_t numOfPools;
+ uint16_t secondLargestBufSize;
+ uint16_t largestBufSize;
+} t_FmInterModulePortRxPoolsParams;
+
+
+typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
+ t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
+
+
+t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
+uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
+uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
+uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
+void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
+void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
+void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
+uint32_t FmPcdLock(t_Handle h_FmPcd);
+void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
+bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
+bool FmPcdIsIpFrag(t_Handle h_FmPcd, uint8_t netEnvId);
+
+t_Error FmPcdCcReleaseModifiedDataStructure(t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, t_List *h_FmPcdNewPointersLst, uint16_t numOfGoodChanges, t_Handle *h_Params);
+uint32_t FmPcdCcGetNodeAddrOffset(t_Handle h_FmPcd, t_Handle h_Pointer);
+t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams);
+t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_Params);
+t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams);
+t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams);
+t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams);
+t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, t_List *h_OldLst, t_List *h_NewLst, t_Handle *h_AdditionalParams);
+t_Error FmPcdCcModiyNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, uint8_t keyIndex,t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,t_List *h_OldPointer, t_List *h_NewPointer,t_Handle *h_AdditionalParams);
+uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
+t_Error FmPcdCcTreeTryLock(t_Handle h_FmPcdCcTree);
+t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
+void FmPcdCcTreeReleaseLock(t_Handle h_FmPcdCcTree);
+void FmPcdCcNodeTreeReleaseLock(t_List *p_List);
+t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree, uint8_t manipIndx);
+void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams, uint8_t manipIndx);
+
+bool FmPcdKgIsSchemeValidSw(t_Handle h_FmPcd, uint8_t schemeId);
+uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
+uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
+
+t_Error FmPcdKgBuildScheme(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme, t_FmPcdKgInterModuleSchemeRegs *p_SchemeRegs);
+t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
+uint8_t FmPcdKgGetNumOfPartitionSchemes(t_Handle h_FmPcd);
+uint8_t FmPcdKgGetPhysicalSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
+uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
+void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
+void FmPcdKgValidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId);
+void FmPcdKgInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId);
+t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_FmPcd, uint8_t schemeId);
+t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
+void FmPcdKgIncSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort);
+void FmPcdKgDecSchemeOwners(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort);
+bool FmPcdKgIsDriverClsPlan(t_Handle h_FmPcd);
+bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
+uint32_t FmPcdKgBuildCppReg(t_Handle h_FmPcd, uint8_t clsPlanGrpId);
+uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
+uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
+uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
+uint32_t FmPcdKgBuildReadClsPlanBlockActionReg(uint8_t grpId);
+uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
+uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
+uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
+uint8_t FmPcdKgGetSchemeSwId(t_Handle h_FmPcd, uint8_t schemeHwId);
+t_Error FmPcdKgSchemeTryLock(t_Handle h_FmPcd, uint8_t schemeId, bool intr);
+void FmPcdKgReleaseSchemeLock(t_Handle h_FmPcd, uint8_t schemeId);
+void FmPcdKgUpatePointedOwner(t_Handle h_FmPcd, uint8_t schemeId, bool add);
+
+t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
+t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
+uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
+uint32_t FmPcdKgGetPointedOwners(t_Handle h_FmPcd, uint8_t schemeId);
+e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
+e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
+void FmPcdKgUpdateRequiredAction(t_Handle h_FmPcd, uint8_t schemeId, uint32_t requiredAction);
+bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
+bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
+uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
+
+/* FM-PCD parser API routines */
+t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
+
+/* FM-PCD policer API routines */
+t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
+t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
+bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
+uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
+uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
+uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
+uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
+uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
+uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
+t_Error FmPcdPlcrBuildProfile(t_Handle h_FmPcd, t_FmPcdPlcrProfileParams *p_Profile, t_FmPcdPlcrInterModuleProfileRegs *p_PlcrRegs);
+t_Error FmPcdPlcrGetAbsoluteProfileId(t_Handle h_FmPcd,
+ e_FmPcdProfileTypeSelection profileType,
+ t_Handle h_FmPort,
+ uint16_t relativeProfile,
+ uint16_t *p_AbsoluteId);
+void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
+void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
+bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
+t_Error FmPcdPlcrProfileTryLock(t_Handle h_FmPcd, uint16_t profileId, bool intr);
+void FmPcdPlcrReleaseProfileLock(t_Handle h_FmPcd, uint16_t profileId);
+uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
+uint32_t FmPcdPlcrGetPointedOwners(t_Handle h_FmPcd, uint16_t absoluteProfileId);
+void FmPcdPlcrUpatePointedOwner(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool add);
+uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
+void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
+
+/* FM-PCD Coarse-Classification API routines */
+uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
+uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
+
+t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify);
+t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
+uint32_t FmPcdManipGetRequiredAction (t_Handle h_Manip);
+t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
+t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
+
+t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
+t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction);
+
+uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
+uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
+uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
+void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
+t_Error FmPortAttachPCD(t_Handle h_FmPort);
+t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
+t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
+
+
+/**************************************************************************//**
+ @Function FmRegisterIntr
+
+ @Description Used to register an inter-module event handler to be processed by FM
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] mod The module that causes the event
+ @Param[in] modId Module id - if more than 1 instansiation of this
+ mode exists,0 otherwise.
+ @Param[in] intrType Interrupt type (error/normal) selection.
+ @Param[in] f_Isr The interrupt service routine.
+ @Param[in] h_Arg Argument to be passed to f_Isr.
+
+ @Return None.
+*//***************************************************************************/
+void FmRegisterIntr(t_Handle h_Fm,
+ e_FmEventModules mod,
+ uint8_t modId,
+ e_FmIntrType intrType,
+ void (*f_Isr) (t_Handle h_Arg),
+ t_Handle h_Arg);
+
+/**************************************************************************//**
+ @Function FmUnregisterIntr
+
+ @Description Used to un-register an inter-module event handler that was processed by FM
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] mod The module that causes the event
+ @Param[in] modId Module id - if more than 1 instansiation of this
+ mode exists,0 otherwise.
+ @Param[in] intrType Interrupt type (error/normal) selection.
+
+ @Return None.
+*//***************************************************************************/
+void FmUnregisterIntr(t_Handle h_Fm,
+ e_FmEventModules mod,
+ uint8_t modId,
+ e_FmIntrType intrType);
+
+/**************************************************************************//**
+ @Function FmRegisterFmCtlIntr
+
+ @Description Used to register to one of the fmCtl events in the FM module
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] eventRegId FmCtl event id (0-7).
+ @Param[in] f_Isr The interrupt service routine.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
+
+
+/**************************************************************************//**
+ @Description enum for defining MAC types
+*//***************************************************************************/
+typedef enum e_FmMacType {
+ e_FM_MAC_10G = 0, /**< 10G MAC */
+ e_FM_MAC_1G /**< 1G MAC */
+} e_FmMacType;
+
+/**************************************************************************//**
+ @Description Structure for port-FM communication during FM_PORT_Init.
+ Fields commented 'IN' are passed by the port module to be used
+ by the FM module.
+ Fields commented 'OUT' will be filled by FM before returning to port.
+ Some fields are optional (depending on configuration) and
+ will be analized by the port and FM modules accordingly.
+*//***************************************************************************/
+typedef struct t_FmInterModulePortInitParams {
+ uint8_t hardwarePortId; /**< IN. port Id */
+ e_FmPortType portType; /**< IN. Port type */
+ bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
+ uint16_t liodnOffset; /**< IN. Port's requested resource */
+ uint8_t numOfTasks; /**< IN. Port's requested resource */
+ uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
+ uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
+ uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
+ uint32_t sizeOfFifo; /**< IN. Port's requested resource */
+ uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
+ uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
+ LIODN base for this port, to be
+ used together with LIODN offset. */
+ t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
+} t_FmInterModulePortInitParams;
+
+/**************************************************************************//**
+ @Description Structure for port-FM communication during FM_PORT_Free.
+*//***************************************************************************/
+typedef struct t_FmInterModulePortFreeParams {
+ uint8_t hardwarePortId; /**< IN. port Id */
+ e_FmPortType portType; /**< IN. Port type */
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+} t_FmInterModulePortFreeParams;
+
+/**************************************************************************//**
+ @Function FmGetPcdPrsBaseAddr
+
+ @Description Get the base address of the Parser from the FM module
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return Base address.
+*//***************************************************************************/
+uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FmGetPcdKgBaseAddr
+
+ @Description Get the base address of the Keygen from the FM module
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return Base address.
+*//***************************************************************************/
+uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FmGetPcdPlcrBaseAddr
+
+ @Description Get the base address of the Policer from the FM module
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return Base address.
+*//***************************************************************************/
+uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FmGetMuramHandle
+
+ @Description Get the handle of the MURAM from the FM module
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return MURAM module handle.
+*//***************************************************************************/
+t_Handle FmGetMuramHandle(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FmGetPhysicalMuramBase
+
+ @Description Get the physical base address of the MURAM from the FM module
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] fmPhysAddr Physical MURAM base
+
+ @Return Physical base address.
+*//***************************************************************************/
+void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
+
+/**************************************************************************//**
+ @Function FmGetTimeStampScale
+
+ @Description Used internally by other modules in order to get the timeStamp
+ period as requested by the application.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return TimeStamp period in nanoseconds.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+uint32_t FmGetTimeStampScale(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FmResumeStalledPort
+
+ @Description Used internally by FM port to release a stalled port.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] hardwarePortId HW port id.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
+
+/**************************************************************************//**
+ @Function FmIsPortStalled
+
+ @Description Used internally by FM port to read the port's status.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] hardwarePortId HW port id.
+ @Param[in] p_IsStalled A pointer to the boolean port stalled state
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
+
+/**************************************************************************//**
+ @Function FmResetMac
+
+ @Description Used by MAC driver to reset the MAC registers
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] type MAC type.
+ @Param[in] macId MAC id - according to type.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
+
+/**************************************************************************//**
+ @Function FmGetClockFreq
+
+ @Description Used by MAC driver to get the FM clock frequency
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return clock-freq on success; 0 otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+uint16_t FmGetClockFreq(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FmGetId
+
+ @Description Used by PCD driver to read rhe FM id
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+uint8_t FmGetId(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FmGetSetPortParams
+
+ @Description Used by FM-PORT driver to pass and receive parameters between
+ PORT and FM modules.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in,out] p_PortParams A structure of FM Port parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
+
+/**************************************************************************//**
+ @Function FmFreePortParams
+
+ @Description Used by FM-PORT driver to free port's resources within the FM.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in,out] p_PortParams A structure of FM Port parameters.
+
+ @Return None.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
+
+/**************************************************************************//**
+ @Function FmSetPortToWorkWithOneRiscOnly
+
+ @Description Used by FM-PORT driver to pass parameter between
+ PORT and FM modules for working with number of RISC..
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in,out] p_PortParams A structure of FM Port parameters.
+
+ @Return None.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls);
+
+
+void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
+void FmUnregisterPcd(t_Handle h_Fm);
+t_Handle FmGetPcdHandle(t_Handle h_Fm);
+bool FmRamsEccIsExternalCtl(t_Handle h_Fm);
+t_Error FmEnableRamsEcc(t_Handle h_Fm);
+t_Error FmDisableRamsEcc(t_Handle h_Fm);
+void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
+t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
+void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
+void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
+uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
+void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
+void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
+t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
+bool FmIsMaster(t_Handle h_Fm);
+uint8_t FmGetGuestId(t_Handle h_Fm);
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+
+void FmMuramClear(t_Handle h_FmMuram);
+t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
+ uint8_t hardwarePortId,
+ uint8_t numOfOpenDmas,
+ uint8_t numOfExtraOpenDmas,
+ bool initialConfig);
+t_Error FmSetNumOfTasks(t_Handle h_Fm,
+ uint8_t hardwarePortId,
+ uint8_t numOfTasks,
+ uint8_t numOfExtraTasks,
+ bool initialConfig);
+t_Error FmSetSizeOfFifo(t_Handle h_Fm,
+ uint8_t hardwarePortId,
+ e_FmPortType portType,
+ bool independentMode,
+ uint32_t *p_SizeOfFifo,
+ uint32_t extraSizeOfFifo,
+ uint8_t deqPipelineDepth,
+ t_FmInterModulePortRxPoolsParams *p_RxPoolsParams,
+ bool initialConfig);
+
+
+#endif /* __FM_COMMON_H */
diff --git a/sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h b/sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h
new file mode 100644
index 0000000..bbcc83c
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/FM/inc/fm_hc.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FM_HC_H
+#define __FM_HC_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+
+
+#define __ERR_MODULE__ MODULE_FM_PCD
+
+
+typedef struct t_FmHcParams {
+ t_Handle h_Fm;
+ t_Handle h_FmPcd;
+ t_FmPcdHcParams params;
+} t_FmHcParams;
+
+
+t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
+void FmHcFree(t_Handle h_FmHc);
+t_Error FmHcDumpRegs(t_Handle h_FmHc);
+
+void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
+
+t_Handle FmHcPcdKgSetScheme(t_Handle h_FmHc, t_FmPcdKgSchemeParams *p_Scheme);
+t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
+t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
+t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
+t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
+
+t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
+uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
+
+t_Error FmHcPcdCcModifyTreeNextEngine(t_Handle h_FmHc, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
+t_Error FmHcPcdCcModifyNodeNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
+t_Error FmHcPcdCcModifyNodeMissNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
+t_Error FmHcPcdCcRemoveKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex);
+t_Error FmHcPcdCcAddKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams);
+t_Error FmHcPcdCcModifyKeyAndNextEngine(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams);
+t_Error FmHcPcdCcModifyKey(t_Handle h_FmHc, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask);
+
+t_Handle FmHcPcdPlcrSetProfile(t_Handle h_FmHc,t_FmPcdPlcrProfileParams *p_Profile);
+t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
+
+t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
+uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
+
+t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
+t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
+
+t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction);
+t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
+
+
+#endif /* __FM_HC_H */
diff --git a/sys/contrib/ncsw/Peripherals/QM/fsl_qman.h b/sys/contrib/ncsw/Peripherals/QM/fsl_qman.h
new file mode 100644
index 0000000..42573f6
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/QM/fsl_qman.h
@@ -0,0 +1,1097 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File fsl_qman.h
+
+ @Description QM header
+*//***************************************************************************/
+#ifndef __FSL_QMAN_H
+#define __FSL_QMAN_H
+
+#include "std_ext.h"
+#include "string_ext.h"
+#include "qm_ext.h"
+
+
+/*************************************************/
+/* QMan s/w corenet portal, low-level i/face */
+/*************************************************/
+typedef enum {
+ e_QmPortalPCI = 0, /* PI index, cache-inhibited */
+ e_QmPortalPCE, /* PI index, cache-enabled */
+ e_QmPortalPVB /* valid-bit */
+} e_QmPortalProduceMode;
+
+typedef enum {
+ e_QmPortalEqcrCCI = 0, /* CI index, cache-inhibited */
+ e_QmPortalEqcrCCE /* CI index, cache-enabled */
+} e_QmPortalEqcrConsumeMode;
+
+typedef enum {
+ e_QmPortalDqrrCCI = 0, /* CI index, cache-inhibited */
+ e_QmPortalDqrrCCE, /* CI index, cache-enabled */
+ e_QmPortalDqrrDCA /* Discrete Consumption Acknowledgment */
+} e_QmPortalDqrrConsumeMode;
+
+typedef enum {
+ e_QmPortalMrCCI = 0, /* CI index, cache-inhibited */
+ e_QmPortalMrCCE /* CI index, cache-enabled */
+} e_QmPortalMrConsumeMode;
+
+typedef enum {
+ e_QmPortalDequeuePushMode = 0, /* SDQCR + VDQCR */
+ e_QmPortalDequeuePullMode /* PDQCR */
+} e_QmPortalDequeueMode;
+
+/* Portal constants */
+#define QM_EQCR_SIZE 8
+#define QM_DQRR_SIZE 16
+#define QM_MR_SIZE 8
+
+/* Hardware constants */
+
+enum qm_isr_reg {
+ qm_isr_status = 0,
+ qm_isr_enable = 1,
+ qm_isr_disable = 2,
+ qm_isr_inhibit = 3
+};
+enum qm_dc_portal {
+ qm_dc_portal_fman0 = 0,
+ qm_dc_portal_fman1 = 1,
+ qm_dc_portal_caam = 2,
+ qm_dc_portal_pme = 3
+};
+
+/* Represents s/w corenet portal mapped data structures */
+struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
+struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
+struct qm_mr_entry; /* MR (Message Ring) entries */
+struct qm_mc_command; /* MC (Management Command) command */
+struct qm_mc_result; /* MC result */
+
+/* This type represents a s/w corenet portal space, and is used for creating the
+ * portal objects within it (EQCR, DQRR, etc) */
+struct qm_portal;
+
+/* When iterating the available portals, this is the exposed config structure */
+struct qm_portal_config {
+ /* If the caller enables DQRR stashing (and thus wishes to operate the
+ * portal from only one cpu), this is the logical CPU that the portal
+ * will stash to. Whether stashing is enabled or not, this setting is
+ * also used for any "core-affine" portals, ie. default portals
+ * associated to the corresponding cpu. -1 implies that there is no core
+ * affinity configured. */
+ int cpu;
+ /* portal interrupt line */
+ int irq;
+ /* The portal's dedicated channel id, use this value for initializing
+ * frame queues to target this portal when scheduled. */
+ e_QmFQChannel channel;
+ /* A mask of which pool channels this portal has dequeue access to
+ * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
+ uint32_t pools;
+ /* which portal sub-interfaces are already bound (ie. "in use") */
+ uint8_t bound;
+};
+/* qm_portal_config::bound uses these bit masks */
+#define QM_BIND_EQCR 0x01
+#define QM_BIND_DQRR 0x02
+#define QM_BIND_MR 0x04
+#define QM_BIND_MC 0x08
+#define QM_BIND_ISR 0x10
+
+/* This struct represents a pool channel */
+struct qm_pool_channel {
+ /* The QM_SDQCR_CHANNELS_POOL(n) bit that corresponds to this channel */
+ uint32_t pool;
+ /* The channel id, used for initialising frame queues to target this
+ * channel. */
+ e_QmFQChannel channel;
+ /* Bitmask of portal (logical-, not cell-)indices that have dequeue
+ * access to this channel;
+ * 0x001 -> qm_portal_get(0)
+ * 0x002 -> qm_portal_get(1)
+ * 0x004 -> qm_portal_get(2)
+ * ...
+ * 0x200 -> qm_portal_get(9)
+ */
+ uint32_t portals;
+};
+
+/* ------------------------------ */
+/* --- Portal enumeration API --- */
+
+/* Obtain the number of portals available */
+uint8_t qm_portal_num(void);
+
+/* Obtain a portal handle and configuration information about it */
+struct qm_portal *qm_portal_get(uint8_t idx);
+
+
+/* ------------------------------------ */
+/* --- Pool channel enumeration API --- */
+
+/* Obtain a mask of the available pool channels, expressed using
+ * QM_SDQCR_CHANNELS_POOL(n). */
+uint32_t qm_pools(void);
+
+/* Retrieve a pool channel configuration, given a QM_SDQCR_CHANNEL_POOL(n)
+ * bit-mask (the least significant bit of 'mask' is used if more than one bit is
+ * set). */
+const struct qm_pool_channel *qm_pool_channel(uint32_t mask);
+
+/* Flags to qm_fq_free_flags() */
+#define QM_FQ_FREE_WAIT 0x00000001 /* wait if RCR is full */
+#define QM_FQ_FREE_WAIT_INT 0x00000002 /* if wait, interruptible? */
+#define QM_FQ_FREE_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
+
+
+#define QM_SDQCR_SOURCE_CHANNELS 0x0
+#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
+#define QM_SDQCR_COUNT_EXACT1 0x0
+#define QM_SDQCR_COUNT_UPTO3 0x20000000
+#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
+#define QM_SDQCR_TYPE_MASK 0x03000000
+#define QM_SDQCR_TYPE_NULL 0x0
+#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
+#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
+#define QM_SDQCR_TYPE_ACTIVE 0x03000000
+#define QM_SDQCR_TYPE_SET(v) (((v) & 0x03) << (31-7))
+#define QM_SDQCR_TOKEN_MASK 0x00ff0000
+#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
+#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
+#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
+#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
+#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
+#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
+#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
+#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
+#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
+
+/* For qm_dqrr_vdqcr_set(); Choose one PRECEDENCE. EXACT is optional. Use
+ * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
+ * FQID(n) to fill in the frame queue ID. */
+#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
+#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
+#define QM_VDQCR_EXACT 0x40000000
+#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
+#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
+#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
+#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
+#define QM_VDQCR_FQID_MASK 0x00ffffff
+#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
+
+/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
+ * If MODE==SCHEDULED
+ * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
+ * If CHANNELS,
+ * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
+ * You can choose DEDICATED_PRECEDENCE if the portal channel should have
+ * priority.
+ * If SPECIFICWQ,
+ * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
+ * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
+ * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
+ * same value.
+ * If MODE==UNSCHEDULED
+ * Choose FQID().
+ */
+#define QM_PDQCR_MODE_SCHEDULED 0x0
+#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
+#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
+#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
+#define QM_PDQCR_COUNT_EXACT1 0x0
+#define QM_PDQCR_COUNT_UPTO3 0x20000000
+#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
+#define QM_PDQCR_TYPE_MASK 0x03000000
+#define QM_PDQCR_TYPE_NULL 0x0
+#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
+#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
+#define QM_PDQCR_TYPE_ACTIVE 0x03000000
+#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
+#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
+#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
+#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
+#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
+#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
+#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
+
+/* ------------------------------------- */
+/* --- Portal interrupt register API --- */
+
+/* Quick explanation of the Qman interrupt model. Each bit has a source
+ * condition, that source is asserted iff the condition is true. Eg. Each
+ * DQAVAIL source bit tracks whether the corresponding channel's work queues
+ * contain any truly scheduled frame queues. That source exists "asserted" if
+ * and while there are truly-scheduled FQs available, it is deasserted as/when
+ * there are no longer any truly-scheduled FQs available. The same is true for
+ * the various other interrupt source conditions (QM_PIRQ_***). The following
+ * steps indicate what those source bits affect;
+ * 1. if the corresponding bit is set in the disable register, the source
+ * bit is masked off, we never see any effect from it.
+ * 2. otherwise, the corresponding bit is set in the status register. Once
+ * asserted in the status register, it must be write-1-to-clear'd - the
+ * status register bit will stay set even if the source condition
+ * deasserts.
+ * 3. if a bit is set in the status register but *not* set in the enable
+ * register, it will not cause the interrupt to assert. Other bits may
+ * still cause the interrupt to assert of course, and a read of the
+ * status register can still reveal un-enabled bits - this is why the
+ * enable and disable registers aren't strictly speaking "opposites".
+ * "Un-enabled" means it won't, on its own, trigger an interrupt.
+ * "Disabled" means it won't even show up in the status register.
+ * 4. if a bit is set in the status register *and* the enable register, the
+ * interrupt line will assert if and only if the inhibit register is
+ * zero. The inhibit register is the only interrupt-related register that
+ * does not share the bit definitions - it is a boolean on/off register.
+ */
+
+/* Create/destroy */
+
+/* Used by all portal interrupt registers except 'inhibit' */
+#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
+#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
+#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
+#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
+#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
+/* The DQAVAIL interrupt fields break down into these bits; */
+#define QM_PIRQ_DQAVAIL 0x0000ffff /* Channels with frame availability */
+#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
+#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
+
+/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
+ * the disable register" rather than "disable the ability to write". */
+#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
+#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
+#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
+#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
+#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
+#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
+#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
+#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
+
+/* ------------------------------------------------------- */
+/* --- Qman data structures (and associated constants) --- */
+
+/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
+#define QM_FD_FORMAT_SG 0x4
+#define QM_FD_FORMAT_LONG 0x2
+#define QM_FD_FORMAT_COMPOUND 0x1
+enum qm_fd_format {
+ /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
+ * scatter-gather table. 'big' implies a 29-bit length with no offset
+ * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
+ * implies a s/g-like table, where each entry itself represents a frame
+ * (contiguous or scatter-gather) and the 29-bit "length" is
+ * interpreted purely for congestion calculations, ie. a "congestion
+ * weight". */
+ qm_fd_contig = 0,
+ qm_fd_contig_big = QM_FD_FORMAT_LONG,
+ qm_fd_sg = QM_FD_FORMAT_SG,
+ qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
+ qm_fd_compound = QM_FD_FORMAT_COMPOUND
+};
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+ _Packed struct qm_fqd_stashing {
+ /* See QM_STASHING_EXCL_<...> */
+ volatile uint8_t exclusive;
+ volatile uint8_t reserved1:2;
+ /* Numbers of cachelines */
+ volatile uint8_t annotation_cl:2;
+ volatile uint8_t data_cl:2;
+ volatile uint8_t context_cl:2;
+} _PackedType;
+
+typedef _Packed union {
+ /* Treat it as 64-bit opaque */
+ _Packed struct {
+ volatile uint32_t hi;
+ volatile uint32_t lo;
+ } _PackedType;
+ /* Treat it as s/w portal stashing config */
+ /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
+ _Packed struct {
+ struct qm_fqd_stashing stashing;
+ volatile uint8_t reserved1;
+ /* 40-bit address of FQ context to
+ * stash, must be cacheline-aligned */
+ volatile uint8_t context_hi;
+ volatile uint32_t context_lo;
+ } _PackedType;
+} _PackedType u_QmFqdContextA;
+
+/* See 1.5.1.1: "Frame Descriptor (FD)" */
+_Packed struct qm_fd {
+ volatile uint8_t dd:2; /* dynamic debug */
+ volatile uint8_t liodn_offset:6; /* aka. "Partition ID" in rev1.0 */
+ volatile uint8_t bpid; /* Buffer Pool ID */
+ volatile uint8_t eliodn_offset:4;
+ volatile uint8_t reserved:4;
+ volatile uint8_t addr_hi; /* high 8-bits of 40-bit address */
+ volatile uint32_t addr_lo; /* low 32-bits of 40-bit address */
+ /* The 'format' field indicates the interpretation of the remaining 29
+ * bits of the 32-bit word. For packing reasons, it is duplicated in the
+ * other union elements. */
+ _Packed union {
+ /* If 'format' is _contig or _sg, 20b length and 9b offset */
+ _Packed struct {
+ volatile enum qm_fd_format format:3;
+ volatile uint16_t offset:9;
+ volatile uint32_t length20:20;
+ } _PackedType;
+ /* If 'format' is _contig_big or _sg_big, 29b length */
+ _Packed struct {
+ volatile enum qm_fd_format _format1:3;
+ volatile uint32_t length29:29;
+ } _PackedType;
+ /* If 'format' is _compound, 29b "congestion weight" */
+ _Packed struct {
+ volatile enum qm_fd_format _format2:3;
+ volatile uint32_t cong_weight:29;
+ } _PackedType;
+ /* For easier/faster copying of this part of the fd (eg. from a
+ * DQRR entry to an EQCR entry) copy 'opaque' */
+ volatile uint32_t opaque;
+ } _PackedType;
+ _Packed union {
+ volatile uint32_t cmd;
+ volatile uint32_t status;
+ }_PackedType;
+} _PackedType;
+
+#define QM_FD_DD_NULL 0x00
+#define QM_FD_PID_MASK 0x3f
+
+/* See 1.5.8.1: "Enqueue Command" */
+_Packed struct qm_eqcr_entry {
+ volatile uint8_t __dont_write_directly__verb;
+ volatile uint8_t dca;
+ volatile uint16_t seqnum;
+ volatile uint32_t orp; /* 24-bit */
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint32_t tag;
+ volatile struct qm_fd fd;
+ volatile uint8_t reserved3[32];
+} _PackedType;
+
+#define QM_EQCR_VERB_VBIT 0x80
+#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
+#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
+#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
+#define QM_EQCR_VERB_COLOUR_GREEN 0x00
+#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
+#define QM_EQCR_VERB_COLOUR_RED 0x10
+#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
+#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
+#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
+#define QM_EQCR_DCA_ENABLE 0x80
+#define QM_EQCR_DCA_PARK 0x40
+#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
+#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
+#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
+#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
+#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
+
+/* See 1.5.8.2: "Frame Dequeue Response" */
+_Packed struct qm_dqrr_entry {
+ volatile uint8_t verb;
+ volatile uint8_t stat;
+ volatile uint16_t seqnum; /* 15-bit */
+ volatile uint8_t tok;
+ volatile uint8_t reserved2[3];
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint32_t contextB;
+ volatile struct qm_fd fd;
+ volatile uint8_t reserved4[32];
+} _PackedType;
+
+#define QM_DQRR_VERB_VBIT 0x80
+#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
+#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
+#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
+#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
+#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
+#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
+#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
+#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
+
+#define VDQCR_DONE (QM_DQRR_STAT_UNSCHEDULED | QM_DQRR_STAT_DQCR_EXPIRED)
+
+
+/* See 1.5.8.3: "ERN Message Response" */
+/* See 1.5.8.4: "FQ State Change Notification" */
+_Packed struct qm_mr_entry {
+ volatile uint8_t verb;
+ _Packed union {
+ _Packed struct {
+ volatile uint8_t dca;
+ volatile uint16_t seqnum;
+ volatile uint8_t rc; /* Rejection Code */
+ volatile uint32_t orp:24;
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint32_t tag;
+ volatile struct qm_fd fd;
+ } _PackedType ern;
+ _Packed struct {
+ volatile uint8_t colour:2; /* See QM_MR_DCERN_COLOUR_* */
+ volatile uint8_t reserved1:3;
+ volatile enum qm_dc_portal portal:3;
+ volatile uint16_t reserved2;
+ volatile uint8_t rc; /* Rejection Code */
+ volatile uint32_t reserved3:24;
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint32_t tag;
+ volatile struct qm_fd fd;
+ } _PackedType dcern;
+ _Packed struct {
+ volatile uint8_t fqs; /* Frame Queue Status */
+ volatile uint8_t reserved1[6];
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint32_t contextB;
+ volatile uint8_t reserved2[16];
+ } _PackedType fq; /* FQRN/FQRNI/FQRL/FQPN */
+ } _PackedType;
+ volatile uint8_t reserved2[32];
+} _PackedType;
+
+#define QM_MR_VERB_VBIT 0x80
+/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
+ * originating from direct-connect portals ("dcern") use 0x20 as a verb which
+ * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
+ * the other MR types by noting if the 0x20 bit is unset. */
+#define QM_MR_VERB_TYPE_MASK 0x23
+#define QM_MR_VERB_DC_ERN 0x20
+#define QM_MR_VERB_FQRN 0x21
+#define QM_MR_VERB_FQRNI 0x22
+#define QM_MR_VERB_FQRL 0x23
+#define QM_MR_VERB_FQPN 0x24
+#define QM_MR_RC_MASK 0xf0 /* contains one of; */
+#define QM_MR_RC_CGR_TAILDROP 0x00
+#define QM_MR_RC_WRED 0x10
+#define QM_MR_RC_ERROR 0x20
+#define QM_MR_RC_ORPWINDOW_EARLY 0x30
+#define QM_MR_RC_ORPWINDOW_LATE 0x40
+#define QM_MR_RC_FQ_TAILDROP 0x50
+#define QM_MR_RC_ORP_RETIRED 0x60
+#define QM_MR_RC_ORP_DISABLE 0x70
+#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
+#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
+#define QM_MR_DCERN_COLOUR_GREEN 0x00
+#define QM_MR_DCERN_COLOUR_YELLOW 0x01
+#define QM_MR_DCERN_COLOUR_RED 0x02
+#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
+
+/* This identical structure of FQD fields is present in the "Init FQ" command
+ * and the "Query FQ" result. It's suctioned out here into its own struct. It's
+ * also used as the qman_query_fq() result structure in the high-level API. */
+
+/* TODO What about OAC for intra-class? */
+#define QM_FQD_TD_THRESH_OAC_EN 0x4000
+
+_Packed struct qm_fqd {
+ _Packed union {
+ volatile uint8_t orpc;
+ _Packed struct {
+ volatile uint8_t reserved1:2;
+ volatile uint8_t orprws:3;
+ volatile uint8_t oa:1;
+ volatile uint8_t olws:2;
+ } _PackedType;
+ } _PackedType;
+ volatile uint8_t cgid;
+ volatile uint16_t fq_ctrl; /* See QM_FQCTRL_<...> */
+ _Packed union {
+ volatile uint16_t dest_wq;
+ _Packed struct {
+ volatile uint16_t channel:13; /* enum qm_channel */
+ volatile uint16_t wq:3;
+ } _PackedType dest;
+ } _PackedType;
+ volatile uint16_t reserved2:1;
+ volatile uint16_t ics_cred:15;
+ _Packed union {
+ volatile uint16_t td_thresh;
+ _Packed struct {
+ volatile uint16_t reserved1:3;
+ volatile uint16_t mant:8;
+ volatile uint16_t exp:5;
+ } _PackedType td;
+ } _PackedType;
+ volatile uint32_t context_b;
+ volatile u_QmFqdContextA context_a;
+} _PackedType;
+
+/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
+/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
+#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
+#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
+#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
+#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
+#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
+#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
+#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
+#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
+#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
+#define QM_FQCTRL_LOCKINCACHE 0x0001 /* Aggressively cache FQD */
+
+/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
+/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
+#define QM_STASHING_EXCL_ANNOTATION 0x04
+#define QM_STASHING_EXCL_DATA 0x02
+#define QM_STASHING_EXCL_CONTEXT 0x01
+
+/* See 1.5.8.4: "FQ State Change Notification" */
+/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
+ * and associated commands/responses. The WRED parameters are calculated from
+ * these fields as follows;
+ * MaxTH = MA * (2 ^ Mn)
+ * Slope = SA / (2 ^ Sn)
+ * MaxP = 4 * (Pn + 1)
+ */
+_Packed struct qm_cgr_wr_parm {
+ _Packed union {
+ volatile uint32_t word;
+ _Packed struct {
+ volatile uint32_t MA:8;
+ volatile uint32_t Mn:5;
+ volatile uint32_t SA:7; /* must be between 64-127 */
+ volatile uint32_t Sn:6;
+ volatile uint32_t Pn:6;
+ } _PackedType;
+ } _PackedType;
+} _PackedType;
+
+/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
+ * management commands, this is padded to a 16-bit structure field, so that's
+ * how we represent it here. The congestion state threshold is calculated from
+ * these fields as follows;
+ * CS threshold = TA * (2 ^ Tn)
+ */
+_Packed struct qm_cgr_cs_thres {
+ volatile uint16_t reserved:3;
+ volatile uint16_t TA:8;
+ volatile uint16_t Tn:5;
+} _PackedType;
+
+/* This identical structure of CGR fields is present in the "Init/Modify CGR"
+ * commands and the "Query CGR" result. It's suctioned out here into its own
+ * struct. */
+_Packed struct __qm_mc_cgr {
+ volatile struct qm_cgr_wr_parm wr_parm_g;
+ volatile struct qm_cgr_wr_parm wr_parm_y;
+ volatile struct qm_cgr_wr_parm wr_parm_r;
+ volatile uint8_t wr_en_g; /* boolean, use QM_CGR_EN */
+ volatile uint8_t wr_en_y; /* boolean, use QM_CGR_EN */
+ volatile uint8_t wr_en_r; /* boolean, use QM_CGR_EN */
+ volatile uint8_t cscn_en; /* boolean, use QM_CGR_EN */
+ volatile uint32_t cscn_targ; /* use QM_CGR_TARG_* */
+ volatile uint8_t cstd_en; /* boolean, use QM_CGR_EN */
+ volatile uint8_t cs; /* boolean, only used in query response */
+ volatile struct qm_cgr_cs_thres cs_thres;
+ volatile uint8_t frame_mode; /* boolean, use QM_CGR_EN */
+} _PackedType;
+
+#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en, frame_mode */
+
+/* See 1.5.8.5.1: "Initialize FQ" */
+/* See 1.5.8.5.2: "Query FQ" */
+/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
+/* See 1.5.8.5.4: "Alter FQ State Commands " */
+/* See 1.5.8.6.1: "Initialize/Modify CGR" */
+/* See 1.5.8.6.2: "Query CGR" */
+/* See 1.5.8.6.3: "Query Congestion Group State" */
+_Packed struct qm_mc_command {
+ volatile uint8_t __dont_write_directly__verb;
+ _Packed union {
+ _Packed struct qm_mcc_initfq {
+ volatile uint8_t reserved1;
+ volatile uint16_t we_mask; /* Write Enable Mask */
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint16_t count; /* Initialises 'count+1' FQDs */
+ volatile struct qm_fqd fqd; /* the FQD fields go here */
+ volatile uint8_t reserved3[32];
+ } _PackedType initfq;
+ _Packed struct qm_mcc_queryfq {
+ volatile uint8_t reserved1[3];
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint8_t reserved2[56];
+ } _PackedType queryfq;
+ _Packed struct qm_mcc_queryfq_np {
+ volatile uint8_t reserved1[3];
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint8_t reserved2[56];
+ } _PackedType queryfq_np;
+ _Packed struct qm_mcc_alterfq {
+ volatile uint8_t reserved1[3];
+ volatile uint32_t fqid; /* 24-bit */
+ volatile uint8_t reserved2[12];
+ volatile uint32_t context_b;
+ volatile uint8_t reserved3[40];
+ } _PackedType alterfq;
+ _Packed struct qm_mcc_initcgr {
+ volatile uint8_t reserved1;
+ volatile uint16_t we_mask; /* Write Enable Mask */
+ volatile struct __qm_mc_cgr cgr; /* CGR fields */
+ volatile uint8_t reserved2[2];
+ volatile uint8_t cgid;
+ volatile uint8_t reserved4[32];
+ } _PackedType initcgr;
+ _Packed struct qm_mcc_querycgr {
+ volatile uint8_t reserved1[30];
+ volatile uint8_t cgid;
+ volatile uint8_t reserved2[32];
+ } _PackedType querycgr;
+ _Packed struct qm_mcc_querycongestion {
+ volatile uint8_t reserved[63];
+ } _PackedType querycongestion;
+ _Packed struct qm_mcc_querywq {
+ volatile uint8_t reserved;
+ /* select channel if verb != QUERYWQ_DEDICATED */
+ _Packed union {
+ volatile uint16_t channel_wq; /* ignores wq (3 lsbits) */
+ _Packed struct {
+ volatile uint16_t id:13; /* enum qm_channel */
+ volatile uint16_t reserved1:3;
+ } _PackedType channel;
+ } _PackedType;
+ volatile uint8_t reserved2[60];
+ } _PackedType querywq;
+ } _PackedType;
+} _PackedType;
+
+#define QM_MCC_VERB_VBIT 0x80
+#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
+#define QM_MCC_VERB_INITFQ_PARKED 0x40
+#define QM_MCC_VERB_INITFQ_SCHED 0x41
+#define QM_MCC_VERB_QUERYFQ 0x44
+#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
+#define QM_MCC_VERB_QUERYWQ 0x46
+#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
+#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
+#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
+#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
+#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
+#define QM_MCC_VERB_ALTER_RETIRE_CTXB 0x4c /* Retire FQ with contextB*/
+#define QM_MCC_VERB_INITCGR 0x50
+#define QM_MCC_VERB_MODIFYCGR 0x51
+#define QM_MCC_VERB_QUERYCGR 0x58
+#define QM_MCC_VERB_QUERYCONGESTION 0x59
+/* INITFQ-specific flags */
+#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
+#define QM_INITFQ_WE_OAC 0x0100
+#define QM_INITFQ_WE_ORPC 0x0080
+#define QM_INITFQ_WE_CGID 0x0040
+#define QM_INITFQ_WE_FQCTRL 0x0020
+#define QM_INITFQ_WE_DESTWQ 0x0010
+#define QM_INITFQ_WE_ICSCRED 0x0008
+#define QM_INITFQ_WE_TDTHRESH 0x0004
+#define QM_INITFQ_WE_CONTEXTB 0x0002
+#define QM_INITFQ_WE_CONTEXTA 0x0001
+/* INITCGR/MODIFYCGR-specific flags */
+#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
+#define QM_CGR_WE_WR_PARM_G 0x0400
+#define QM_CGR_WE_WR_PARM_Y 0x0200
+#define QM_CGR_WE_WR_PARM_R 0x0100
+#define QM_CGR_WE_WR_EN_G 0x0080
+#define QM_CGR_WE_WR_EN_Y 0x0040
+#define QM_CGR_WE_WR_EN_R 0x0020
+#define QM_CGR_WE_CSCN_EN 0x0010
+#define QM_CGR_WE_CSCN_TARG 0x0008
+#define QM_CGR_WE_CSTD_EN 0x0004
+#define QM_CGR_WE_CS_THRES 0x0002
+#define QM_CGR_WE_MODE 0x0001
+
+/* See 1.5.8.5.1: "Initialize FQ" */
+/* See 1.5.8.5.2: "Query FQ" */
+/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
+/* See 1.5.8.5.4: "Alter FQ State Commands " */
+/* See 1.5.8.6.1: "Initialize/Modify CGR" */
+/* See 1.5.8.6.2: "Query CGR" */
+/* See 1.5.8.6.3: "Query Congestion Group State" */
+_Packed struct qm_mc_result {
+ volatile uint8_t verb;
+ volatile uint8_t result;
+ _Packed union {
+ _Packed struct qm_mcr_initfq {
+ volatile uint8_t reserved1[62];
+ } _PackedType initfq;
+ _Packed struct qm_mcr_queryfq {
+ volatile uint8_t reserved1[8];
+ volatile struct qm_fqd fqd; /* the FQD fields are here */
+ volatile uint16_t oac;
+ volatile uint8_t reserved2[30];
+ } _PackedType queryfq;
+ _Packed struct qm_mcr_queryfq_np {
+ volatile uint8_t reserved1;
+ volatile uint8_t state; /* QM_MCR_NP_STATE_*** */
+ volatile uint8_t reserved2;
+ volatile uint32_t fqd_link:24;
+ volatile uint16_t odp_seq;
+ volatile uint16_t orp_nesn;
+ volatile uint16_t orp_ea_hseq;
+ volatile uint16_t orp_ea_tseq;
+ volatile uint8_t reserved3;
+ volatile uint32_t orp_ea_hptr:24;
+ volatile uint8_t reserved4;
+ volatile uint32_t orp_ea_tptr:24;
+ volatile uint8_t reserved5;
+ volatile uint32_t pfdr_hptr:24;
+ volatile uint8_t reserved6;
+ volatile uint32_t pfdr_tptr:24;
+ volatile uint8_t reserved7[5];
+ volatile uint8_t reserved8:7;
+ volatile uint8_t is:1;
+ volatile uint16_t ics_surp;
+ volatile uint32_t byte_cnt;
+ volatile uint8_t reserved9;
+ volatile uint32_t frm_cnt:24;
+ volatile uint32_t reserved10;
+ volatile uint16_t ra1_sfdr; /* QM_MCR_NP_RA1_*** */
+ volatile uint16_t ra2_sfdr; /* QM_MCR_NP_RA2_*** */
+ volatile uint16_t reserved11;
+ volatile uint16_t od1_sfdr; /* QM_MCR_NP_OD1_*** */
+ volatile uint16_t od2_sfdr; /* QM_MCR_NP_OD2_*** */
+ volatile uint16_t od3_sfdr; /* QM_MCR_NP_OD3_*** */
+ } _PackedType queryfq_np;
+ _Packed struct qm_mcr_alterfq {
+ volatile uint8_t fqs; /* Frame Queue Status */
+ volatile uint8_t reserved1[61];
+ } _PackedType alterfq;
+ _Packed struct qm_mcr_initcgr {
+ volatile uint8_t reserved1[62];
+ } _PackedType initcgr;
+ _Packed struct qm_mcr_querycgr {
+ volatile uint16_t reserved1;
+ volatile struct __qm_mc_cgr cgr; /* CGR fields */
+ volatile uint8_t reserved2[3];
+ volatile uint32_t reserved3:24;
+ volatile uint32_t i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
+ volatile uint32_t i_bcnt_lo; /* low 32-bits of 40-bit */
+ volatile uint32_t reserved4:24;
+ volatile uint32_t a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
+ volatile uint32_t a_bcnt_lo; /* low 32-bits of 40-bit */
+ volatile uint32_t lgt; /* Last Group Tick */
+ volatile uint8_t reserved5[12];
+ } _PackedType querycgr;
+ _Packed struct qm_mcr_querycongestion {
+ volatile uint8_t reserved[30];
+ /* Access this struct using QM_MCR_QUERYCONGESTION() */
+ _Packed struct __qm_mcr_querycongestion {
+ volatile uint32_t __state[8];
+ } _PackedType state;
+ } _PackedType querycongestion;
+ _Packed struct qm_mcr_querywq {
+ _Packed union {
+ volatile uint16_t channel_wq; /* ignores wq (3 lsbits) */
+ _Packed struct {
+ volatile uint16_t id:13; /* enum qm_channel */
+ volatile uint16_t reserved:3;
+ } _PackedType channel;
+ } _PackedType;
+ volatile uint8_t reserved[28];
+ volatile uint32_t wq_len[8];
+ } _PackedType querywq;
+ } _PackedType;
+} _PackedType;
+
+#define QM_MCR_VERB_RRID 0x80
+#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
+#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
+#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
+#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
+#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
+#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
+#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
+#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
+#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
+#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
+#define QM_MCR_VERB_ALTER_RETIRE_CTXB QM_MCC_VERB_ALTER_RETIRE_CTXB
+#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
+#define QM_MCR_RESULT_NULL 0x00
+#define QM_MCR_RESULT_OK 0xf0
+#define QM_MCR_RESULT_ERR_FQID 0xf1
+#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
+#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
+#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
+#define QM_MCR_RESULT_PENDING 0xf8
+#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
+#define QM_MCR_NP_STATE_FE 0x10
+#define QM_MCR_NP_STATE_R 0x08
+#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
+#define QM_MCR_NP_STATE_OOS 0x00
+#define QM_MCR_NP_STATE_RETIRED 0x01
+#define QM_MCR_NP_STATE_TEN_SCHED 0x02
+#define QM_MCR_NP_STATE_TRU_SCHED 0x03
+#define QM_MCR_NP_STATE_PARKED 0x04
+#define QM_MCR_NP_STATE_ACTIVE 0x05
+#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
+#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
+#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
+#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
+#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
+#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
+#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/* This extracts the state for congestion group 'n' from a query response.
+ * Eg.
+ * uint8_t cgr = [...];
+ * struct qm_mc_result *res = [...];
+ * printf("congestion group %d congestion state: %d\n", cgr,
+ * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
+ */
+#define __CGR_WORD(num) (num >> 5)
+#define __CGR_SHIFT(num) (num & 0x1f)
+static __inline__ int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
+ uint8_t cgr)
+{
+ return (int)(p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr)));
+}
+
+
+/*********************/
+/* Utility interface */
+/*********************/
+
+/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
+ * spinlock them yourself if needed. */
+struct qman_fqid_pool;
+
+/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
+ * always succeeds, but returns non-zero if there were "leaked" FQID
+ * allocations. */
+struct qman_fqid_pool *qman_fqid_pool_create(uint32_t fqid_start, uint32_t num);
+int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
+/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
+int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, uint32_t *fqid);
+void qman_fqid_pool_free(struct qman_fqid_pool *pool, uint32_t fqid);
+uint32_t qman_fqid_pool_used(struct qman_fqid_pool *pool);
+
+/*******************************************************************/
+/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
+/*******************************************************************/
+
+ /* Congestion Groups */
+ /* ----------------- */
+/* This wrapper represents a bit-array for the state of the 256 Qman congestion
+ * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
+ * those that don't concern us. We harness the structure and accessor details
+ * already used in the management command to query congestion groups. */
+struct qman_cgrs {
+ struct __qm_mcr_querycongestion q;
+};
+static __inline__ void QMAN_CGRS_INIT(struct qman_cgrs *c)
+{
+ memset(c, 0, sizeof(*c));
+}
+static __inline__ int QMAN_CGRS_GET(struct qman_cgrs *c, int num)
+{
+ return QM_MCR_QUERYCONGESTION(&c->q, (uint8_t)num);
+}
+static __inline__ void QMAN_CGRS_SET(struct qman_cgrs *c, int num)
+{
+ c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
+}
+static __inline__ void QMAN_CGRS_UNSET(struct qman_cgrs *c, int num)
+{
+ c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
+}
+
+ /* Portal and Frame Queues */
+ /* ----------------------- */
+
+/* This object type represents Qman frame queue descriptors (FQD), and is
+ * stored within a cacheline passed to qman_new_fq(). */
+struct qman_fq;
+
+/* This enum, and the callback type that returns it, are used when handling
+ * dequeued frames via DQRR. Note that for "null" callbacks registered with the
+ * portal object (for handling dequeues that do not demux because contextB is
+ * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
+enum qman_cb_dqrr_result {
+ /* DQRR entry can be consumed */
+ qman_cb_dqrr_consume,
+ /* DQRR entry cannot be consumed now, pause until next poll request */
+ qman_cb_dqrr_pause,
+ /* Like _consume, but requests parking - FQ must be held-active */
+ qman_cb_dqrr_park,
+ /* Does not consume, for DCA mode only. This allows out-of-order
+ * consumes by explicit calls to qman_dca() and/or the use of implicit
+ * DCA via EQCR entries. */
+ qman_cb_dqrr_defer
+};
+
+/*typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(t_Handle h_Arg,
+ t_Handle h_QmPortal,
+ struct qman_fq *fq,
+ const struct qm_dqrr_entry *dqrr);*/
+typedef t_QmReceivedFrameCallback * qman_cb_dqrr;
+typedef t_QmReceivedFrameCallback * qman_cb_fqs;
+typedef t_QmRejectedFrameCallback * qman_cb_ern;
+/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
+ * are always consumed after the callback returns. */
+typedef void (*qman_cb_mr)(t_Handle h_Arg,
+ t_Handle h_QmPortal,
+ struct qman_fq *fq,
+ const struct qm_mr_entry *msg);
+
+struct qman_fq_cb {
+ qman_cb_dqrr dqrr; /* for dequeued frames */
+ qman_cb_ern ern; /* for s/w ERNs */
+ qman_cb_mr dc_ern; /* for diverted h/w ERNs */
+ qman_cb_mr fqs; /* frame-queue state changes*/
+};
+
+enum qman_fq_state {
+ qman_fq_state_oos,
+ qman_fq_state_waiting_parked,
+ qman_fq_state_parked,
+ qman_fq_state_sched,
+ qman_fq_state_retired
+};
+
+/* Flags to qman_create_portal() */
+#define QMAN_PORTAL_FLAG_IRQ 0x00000001 /* use interrupt handler */
+#define QMAN_PORTAL_FLAG_IRQ_FAST 0x00000002 /* ... for fast-path too! */
+#define QMAN_PORTAL_FLAG_IRQ_SLOW 0x00000003 /* ... for slow-path too! */
+#define QMAN_PORTAL_FLAG_DCA 0x00000004 /* use DCA */
+#define QMAN_PORTAL_FLAG_LOCKED 0x00000008 /* multi-core locking */
+#define QMAN_PORTAL_FLAG_NOTAFFINE 0x00000010 /* not cpu-default portal */
+#define QMAN_PORTAL_FLAG_RSTASH 0x00000020 /* enable DQRR entry stashing */
+#define QMAN_PORTAL_FLAG_DSTASH 0x00000040 /* enable data stashing */
+#define QMAN_PORTAL_FLAG_RECOVER 0x00000080 /* recovery mode */
+#define QMAN_PORTAL_FLAG_WAIT 0x00000100 /* for recovery; can wait */
+#define QMAN_PORTAL_FLAG_WAIT_INT 0x00000200 /* for wait; interruptible */
+#define QMAN_PORTAL_FLAG_CACHE 0x00000400 /* use cachable area for EQCR/DQRR */
+
+/* Flags to qman_create_fq() */
+#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
+#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
+#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
+#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
+#define QMAN_FQ_FLAG_RECOVER 0x00000010 /* recovery mode */
+#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
+
+/* Flags to qman_destroy_fq() */
+#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
+
+/* Flags from qman_fq_state() */
+#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
+#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
+#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
+#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
+#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
+#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
+
+/* Flags to qman_init_fq() */
+#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
+#define QMAN_INITFQ_FLAG_NULL 0x00000002 /* zero 'contextB', no demux */
+#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
+
+/* Flags to qman_volatile_dequeue() */
+#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000001 /* if we wait, interruptible? */
+#define QMAN_VOLATILE_FLAG_WAIT 0x00000002 /* wait if VDQCR is in use */
+#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
+
+/* Flags to qman_enqueue(). NB, the strange numbering is to align with
+ * hardware, bit-wise. */
+#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
+#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
+#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00040000 /* if wait, until consumed? */
+#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
+#define QMAN_ENQUEUE_FLAG_INTERRUPT 0x00000004 /* on command consumption */
+#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
+#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
+#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
+ (((uint32_t)(p) << 2) & 0x00000f00)
+#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
+#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
+#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
+#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
+/* For the ORP-specific qman_enqueue_orp() variant, this flag indicates "Not
+ * Last In Sequence", ie. a non-terminating fragment. */
+#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
+/* - this flag performs no enqueue but fills in an ORP sequence number that
+ * would otherwise block it (eg. if a frame has been dropped). */
+#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
+/* - this flag performs no enqueue but advances NESN to the given sequence
+ * number. */
+#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
+
+ /* FQ management */
+ /* ------------- */
+/**
+ * qman_free_fq - Deallocates a FQ
+ * @fq: the frame queue object to release
+ * @flags: bit-mask of QMAN_FQ_FREE_*** options
+ *
+ * The memory for this frame queue object ('mem' provided in qman_new_fq()) is
+ * not deallocated but the caller regains ownership, to do with as desired. The
+ * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
+ * is specified, in which case it may also be in the 'parked' state.
+ */
+void qman_free_fq(struct qman_fq *fq, uint32_t flags);
+
+/**
+ * qman_fq_fqid - Queries the frame queue ID of a FQ object
+ * @fq: the frame queue object to query
+ */
+uint32_t qman_fq_fqid(struct qman_fq *fq);
+
+/**
+ * qman_fq_state - Queries the state of a FQ object
+ * @fq: the frame queue object to query
+ * @state: pointer to state enum to return the FQ scheduling state
+ * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
+ *
+ * Queries the state of the FQ object, without performing any h/w commands.
+ * This captures the state, as seen by the driver, at the time the function
+ * executes.
+ */
+void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, uint32_t *flags);
+
+#endif /* __FSL_QMAN_H */
diff --git a/sys/contrib/ncsw/Peripherals/QM/qm.c b/sys/contrib/ncsw/Peripherals/QM/qm.c
new file mode 100644
index 0000000..d1d7032
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/QM/qm.c
@@ -0,0 +1,1266 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File qm.c
+
+ @Description QM & Portal implementation
+*//***************************************************************************/
+#include "error_ext.h"
+#include "std_ext.h"
+#include "string_ext.h"
+#include "sprint_ext.h"
+#include "mm_ext.h"
+#include "core_ext.h"
+#include "debug_ext.h"
+
+#include "qm.h"
+
+
+static volatile bool blockingFlag = FALSE;
+static void QmIpcMsgCompletionCB(t_Handle h_Module,
+ uint8_t *p_Msg,
+ uint8_t *p_Reply,
+ uint32_t replyLength,
+ t_Error status)
+{
+ SANITY_CHECK_RETURN(h_Module, E_INVALID_HANDLE);
+
+ UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);UNUSED(h_Module);
+ blockingFlag = FALSE;
+}
+
+static t_Error QmHandleIpcMsgCB(t_Handle h_Qm,
+ uint8_t *p_Msg,
+ uint32_t msgLength,
+ uint8_t *p_Reply,
+ uint32_t *p_ReplyLength)
+{
+ t_Qm *p_Qm = (t_Qm*)h_Qm;
+ t_QmIpcMsg *p_IpcMsg = (t_QmIpcMsg*)p_Msg;
+ t_QmIpcReply *p_IpcReply = (t_QmIpcReply *)p_Reply;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
+
+#ifdef DISABLE_SANITY_CHECKS
+ UNUSED(msgLength);
+#endif /* DISABLE_SANITY_CHECKS */
+
+ ASSERT_COND(p_IpcMsg);
+
+ memset(p_IpcReply, 0, (sizeof(uint8_t) * QM_IPC_MAX_REPLY_SIZE));
+ *p_ReplyLength = 0;
+
+ switch(p_IpcMsg->msgId)
+ {
+ case (QM_MASTER_IS_ALIVE):
+ *(uint8_t*)p_IpcReply->replyBody = 1;
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ break;
+ case (QM_FORCE_FQID):
+ {
+ t_QmIpcFqidParams ipcFqid;
+ uint32_t fqid;
+
+ memcpy((uint8_t*)&ipcFqid, p_IpcMsg->msgBody, sizeof(t_QmIpcFqidParams));
+ fqid = QmFqidGet(p_Qm, ipcFqid.size, 1, TRUE, ipcFqid.fqid);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&fqid, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (QM_PUT_FQID):
+ {
+ t_Error err;
+ t_QmIpcFqidParams ipcFqid;
+
+ memcpy((uint8_t*)&ipcFqid, p_IpcMsg->msgBody, sizeof(t_QmIpcFqidParams));
+ if ((err = QmFqidPut(p_Qm, ipcFqid.fqid)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (QM_GET_COUNTER):
+ {
+ t_QmIpcGetCounter ipcCounter;
+ uint32_t count;
+
+ memcpy((uint8_t*)&ipcCounter, p_IpcMsg->msgBody, sizeof(t_QmIpcGetCounter));
+ count = QmGetCounter(p_Qm, (e_QmInterModuleCounters)ipcCounter.enumId);
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&count, sizeof(uint32_t));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ break;
+ }
+ case (QM_GET_SET_PORTAL_PARAMS):
+ {
+ t_Error err;
+ t_QmIpcPortalInitParams ipcPortalInitParams;
+ t_QmInterModulePortalInitParams portalInitParams;
+
+ memcpy((uint8_t*)&ipcPortalInitParams, p_IpcMsg->msgBody, sizeof(t_QmIpcPortalInitParams));
+ portalInitParams.portalId = ipcPortalInitParams.portalId;
+ portalInitParams.stashDestQueue = ipcPortalInitParams.stashDestQueue;
+ portalInitParams.liodn = ipcPortalInitParams.liodn;
+ portalInitParams.dqrrLiodn = ipcPortalInitParams.dqrrLiodn;
+ portalInitParams.fdFqLiodn = ipcPortalInitParams.fdFqLiodn;
+ if ((err = QmGetSetPortalParams(p_Qm, &portalInitParams)) != E_OK)
+ REPORT_ERROR(MINOR, err, NO_MSG);
+ break;
+ }
+ case (QM_GET_REVISION):
+ {
+ t_QmRevisionInfo revInfo;
+ t_QmIpcRevisionInfo ipcRevInfo;
+
+ p_IpcReply->error = (uint32_t)QmGetRevision(h_Qm, &revInfo);
+ ipcRevInfo.majorRev = revInfo.majorRev;
+ ipcRevInfo.minorRev = revInfo.minorRev;
+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_QmIpcRevisionInfo));
+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_QmIpcRevisionInfo);
+ break;
+ }
+ default:
+ *p_ReplyLength = 0;
+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
+ }
+ return E_OK;
+}
+
+static t_Error CheckQmParameters(t_Qm *p_Qm)
+{
+ if ((p_Qm->p_QmDriverParams->partFqidBase + p_Qm->p_QmDriverParams->partNumOfFqids) > QM_MAX_NUM_OF_FQIDS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partFqidBase+partNumOfFqids out of range!!!"));
+ if ((p_Qm->partCgsBase + p_Qm->partNumOfCgs) > QM_MAX_NUM_OF_CGS)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partCgsBase+partNumOfCgs out of range!!!"));
+
+ if (p_Qm->guestId == NCSW_MASTER_ID)
+ {
+ uint64_t phyAddr;
+
+ phyAddr = XX_VirtToPhys(UINT_TO_PTR(p_Qm->p_QmDriverParams->swPortalsBaseAddress));
+
+ if (phyAddr & 0x00000000001fffffLL)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("swPortalsBaseAddress isn't properly aligned"));
+ if (!p_Qm->p_QmDriverParams->rtFramesDepth)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rtFramesDepth must be larger than '0'!!!"));
+ if (p_Qm->p_QmDriverParams->rtFramesDepth > ((16*MEGABYTE)*3))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("rtFramesDepth must be equal or smaller than 48MB!!!"));
+ if (!p_Qm->p_QmDriverParams->totalNumOfFqids)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfFqids must be larger than '0'!!!"));
+ if (p_Qm->p_QmDriverParams->totalNumOfFqids > (16*MEGABYTE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfFqids must be equal or smaller than 16MB!!!"));
+ if(!p_Qm->f_Exception)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
+ }
+
+ return E_OK;
+}
+
+static t_Error QmInitPfdr(t_Qm *p_Qm, uint32_t pfdr_start, uint32_t num)
+{
+ uint8_t rslt;
+ uint32_t timeout = 100000;
+
+ ASSERT_COND(p_Qm);
+
+ ASSERT_COND(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
+
+ /* Make sure te command interface is 'idle' */
+ rslt = MCR_get_rslt(GET_UINT32(p_Qm->p_QmRegs->mcr));
+ if (!MCR_rslt_idle(rslt))
+ RETURN_ERROR(CRITICAL,E_INVALID_STATE,("QMAN_MCR isn't idle"));
+
+ /* Write the MCR command params then the verb */
+ WRITE_UINT32(p_Qm->p_QmRegs->mcp0, pfdr_start);
+ /* TODO: remove this - it's a workaround for a model bug that is
+ * corrected in more recent versions. We use the workaround until
+ * everyone has upgraded. */
+ WRITE_UINT32(p_Qm->p_QmRegs->mcp1, (pfdr_start + num - 16));
+ WRITE_UINT32(p_Qm->p_QmRegs->mcp1, (pfdr_start + num - 1));
+
+ CORE_MemoryBarrier();
+ WRITE_UINT32(p_Qm->p_QmRegs->mcr, MCR_INIT_PFDR);
+
+ /* Poll for the result */
+ do {
+ XX_UDelay(1);
+ rslt = MCR_get_rslt(GET_UINT32(p_Qm->p_QmRegs->mcr));
+ } while(!MCR_rslt_idle(rslt) && --timeout);
+
+ if (MCR_rslt_ok(rslt))
+ return E_OK;
+ WRITE_UINT32(p_Qm->p_QmRegs->mcr, 0);
+ if (!timeout)
+ RETURN_ERROR(MAJOR, E_TIMEOUT, NO_MSG);
+ if (MCR_rslt_eaccess(rslt))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ if (MCR_rslt_inval(rslt))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt));
+}
+
+static __inline__ void QmSetWqScheduling(t_Qm *p_Qm,
+ e_QmWqClass wqClass,
+ uint8_t csElev,
+ uint8_t csw2,
+ uint8_t csw3,
+ uint8_t csw4,
+ uint8_t csw5,
+ uint8_t csw6,
+ uint8_t csw7)
+{
+ ASSERT_COND(p_Qm);
+
+ WRITE_UINT32(p_Qm->p_QmRegs->wq_cs_cfg[wqClass],
+ (uint32_t)(((csElev & 0xff) << 24) |
+ ((csw2 & 0x7) << 20) |
+ ((csw3 & 0x7) << 16) |
+ ((csw4 & 0x7) << 12) |
+ ((csw5 & 0x7) << 8) |
+ ((csw6 & 0x7) << 4) |
+ (csw7 & 0x7)));
+}
+
+static uint32_t ReserveFqids(t_Qm *p_Qm, uint32_t size, uint32_t alignment, bool force, uint32_t base)
+{
+ uint64_t ans;
+ uint32_t intFlags;
+
+ intFlags = XX_LockIntrSpinlock(p_Qm->lock);
+ if (force)
+ ans = MM_GetForce(p_Qm->h_FqidMm,
+ (uint64_t)base,
+ (uint64_t)size,
+ "QM FQID MEM");
+ else
+ ans = MM_Get(p_Qm->h_FqidMm,
+ (uint64_t)size,
+ alignment,
+ "QM FQID MEM");
+ if (ans == ILLEGAL_BASE)
+ {
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+ return (uint32_t)ans;
+ }
+ base = (uint32_t)ans;
+ ans = MM_GetForce(p_Qm->h_RsrvFqidMm,
+ (uint64_t)base,
+ (uint64_t)size,
+ "QM rsrv FQID MEM");
+ if (ans == ILLEGAL_BASE)
+ {
+ MM_Put(p_Qm->h_FqidMm, (uint64_t)base);
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+ return (uint32_t)ans;
+ }
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+
+ return (uint32_t)base;
+}
+
+static void FreeInitResources(t_Qm *p_Qm)
+{
+ if (p_Qm->p_FqdBase)
+ XX_FreeSmart(p_Qm->p_FqdBase);
+ if (p_Qm->p_PfdrBase)
+ XX_FreeSmart(p_Qm->p_PfdrBase);
+ if (p_Qm->h_Session)
+ XX_IpcFreeSession(p_Qm->h_Session);
+ if (p_Qm->h_RsrvFqidMm)
+ MM_Free(p_Qm->h_RsrvFqidMm);
+ if (p_Qm->h_FqidMm)
+ MM_Free(p_Qm->h_FqidMm);
+}
+
+
+/****************************************/
+/* Inter-Module functions */
+/****************************************/
+
+uint32_t QmGetCounter(t_Handle h_Qm, e_QmInterModuleCounters counter)
+{
+ t_Qm *p_Qm = (t_Qm*)h_Qm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Qm, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE((((p_Qm->guestId == NCSW_MASTER_ID) && p_Qm->p_QmRegs) ||
+ (p_Qm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE, 0);
+
+ if ((p_Qm->guestId == NCSW_MASTER_ID) ||
+ (!p_Qm->h_Session && p_Qm->p_QmRegs))
+ {
+ switch(counter)
+ {
+ case(e_QM_IM_COUNTERS_SFDR_IN_USE):
+ return GET_UINT32(p_Qm->p_QmRegs->sfdr_in_use);
+ case(e_QM_IM_COUNTERS_PFDR_IN_USE):
+ return (p_Qm->numOfPfdr - GET_UINT32(p_Qm->p_QmRegs->pfdr_fpc));
+ case(e_QM_IM_COUNTERS_PFDR_FREE_POOL):
+ return (GET_UINT32(p_Qm->p_QmRegs->pfdr_fpc) - GET_UINT32(p_Qm->p_QmRegs->pfdr_cfg));
+ default:
+ break;
+ }
+ /* should never get here */
+ ASSERT_COND(FALSE);
+ }
+ else if (p_Qm->h_Session)
+ {
+ t_QmIpcMsg msg;
+ t_QmIpcReply reply;
+ t_QmIpcGetCounter ipcCounter;
+ uint32_t replyLength, count;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_QmIpcMsg));
+ memset(&reply, 0, sizeof(t_QmIpcReply));
+ ipcCounter.enumId = (uint32_t)counter;
+ msg.msgId = QM_GET_COUNTER;
+ memcpy(msg.msgBody, &ipcCounter, sizeof(t_QmIpcGetCounter));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_QmIpcGetCounter),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MAJOR, errCode, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ if ((errCode == E_OK) && (replyLength == (sizeof(uint32_t) + sizeof(uint32_t))))
+ {
+ memcpy((uint8_t*)&count, reply.replyBody, sizeof(uint32_t));
+ return count;
+ }
+ }
+ else
+ REPORT_ERROR(WARNING, E_NOT_SUPPORTED,
+ ("In 'guest', either IPC or 'baseAddress' is required!"));
+
+ return 0;
+}
+
+t_Error QmGetRevision(t_Handle h_Qm, t_QmRevisionInfo *p_QmRevisionInfo)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_QmRevisionInfo, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR((((p_Qm->guestId == NCSW_MASTER_ID) && p_Qm->p_QmRegs) ||
+ (p_Qm->guestId != NCSW_MASTER_ID)), E_INVALID_STATE);
+
+ if ((p_Qm->guestId == NCSW_MASTER_ID) ||
+ (!p_Qm->h_Session && p_Qm->p_QmRegs))
+ {
+ /* read revision register 1 */
+ tmpReg = GET_UINT32(p_Qm->p_QmRegs->ip_rev_1);
+ p_QmRevisionInfo->majorRev = (uint8_t)((tmpReg & REV1_MAJOR_MASK) >> REV1_MAJOR_SHIFT);
+ p_QmRevisionInfo->minorRev = (uint8_t)((tmpReg & REV1_MINOR_MASK) >> REV1_MINOR_SHIFT);
+ }
+ else if (p_Qm->h_Session)
+ {
+ t_QmIpcMsg msg;
+ t_QmIpcReply reply;
+ t_QmIpcRevisionInfo ipcRevInfo;
+ uint32_t replyLength;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_QmIpcMsg));
+ memset(&reply, 0, sizeof(reply));
+ msg.msgId = QM_GET_REVISION;
+ replyLength = sizeof(uint32_t) + sizeof(t_QmIpcRevisionInfo);
+ if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(t_QmIpcRevisionInfo)))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_QmIpcRevisionInfo));
+ p_QmRevisionInfo->majorRev = ipcRevInfo.majorRev;
+ p_QmRevisionInfo->minorRev = ipcRevInfo.minorRev;
+
+ return (t_Error)(reply.error);
+ }
+ else
+ RETURN_ERROR(WARNING, E_NOT_SUPPORTED,
+ ("In 'guest', either IPC or 'baseAddress' is required!"));
+
+ return E_OK;
+}
+
+t_Error QmGetSetPortalParams(t_Handle h_Qm, t_QmInterModulePortalInitParams *p_PortalParams)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+ t_QmRevisionInfo revInfo;
+ uint32_t lioReg,ioReg;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_PortalParams, E_NULL_POINTER);
+
+ if (p_Qm->guestId == NCSW_MASTER_ID)
+ {
+ QmGetRevision(p_Qm, &revInfo);
+
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ lioReg = (uint32_t)(p_PortalParams->stashDestQueue << 24) |
+ (p_PortalParams->liodn << 16) |
+ (p_PortalParams->dqrrLiodn);
+ ioReg = (p_PortalParams->fdFqLiodn);
+ }
+ else
+ {
+ lioReg = (uint32_t)(p_PortalParams->liodn << 16) |
+ (p_PortalParams->dqrrLiodn);
+ ioReg = (uint32_t)(p_PortalParams->stashDestQueue << 16) |
+ (p_PortalParams->fdFqLiodn);
+ }
+
+ WRITE_UINT32(p_Qm->p_QmRegs->swpConfRegs[p_PortalParams->portalId].lio_cfg, lioReg);
+ WRITE_UINT32(p_Qm->p_QmRegs->swpConfRegs[p_PortalParams->portalId].io_cfg, ioReg);
+ }
+ else if (p_Qm->h_Session)
+ {
+ t_QmIpcMsg msg;
+ t_QmIpcPortalInitParams portalParams;
+ t_Error errCode;
+
+ memset(&msg, 0, sizeof(t_QmIpcMsg));
+ portalParams.portalId = p_PortalParams->portalId;
+ portalParams.stashDestQueue = p_PortalParams->stashDestQueue;
+ portalParams.liodn = p_PortalParams->liodn;
+ portalParams.dqrrLiodn = p_PortalParams->dqrrLiodn;
+ portalParams.fdFqLiodn = p_PortalParams->fdFqLiodn;
+ msg.msgId = QM_GET_SET_PORTAL_PARAMS;
+ memcpy(msg.msgBody, &portalParams, sizeof(t_QmIpcPortalInitParams));
+ XX_LockSpinlock(p_Qm->lock);
+ if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_QmIpcPortalInitParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ {
+ XX_UnlockSpinlock(p_Qm->lock);
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ }
+ XX_UnlockSpinlock(p_Qm->lock);
+ }
+ else
+ DBG(WARNING, ("Can't set portal parameters (e.g. liodns). " \
+ "probably QM is running in guest-mode with no IPC!"));
+
+ return E_OK;
+}
+
+uint32_t QmFqidGet(t_Qm *p_Qm, uint32_t size, uint32_t alignment, bool force, uint32_t base)
+{
+ uint64_t ans;
+ uint32_t intFlags;
+
+ intFlags = XX_LockIntrSpinlock(p_Qm->lock);
+ if (force)
+ {
+ ans = MM_GetForce(p_Qm->h_FqidMm,
+ (uint64_t)base,
+ (uint64_t)size,
+ "QM FQID MEM");
+ if (ans == ILLEGAL_BASE)
+ {
+ ans = MM_GetForce(p_Qm->h_RsrvFqidMm,
+ (uint64_t)base,
+ (uint64_t)size,
+ "QM rsrv FQID MEM");
+ if (ans == ILLEGAL_BASE)
+ ans = base;
+ else if (p_Qm->h_Session)
+ {
+ t_QmIpcMsg msg;
+ t_QmIpcReply reply;
+ uint32_t replyLength;
+ t_QmIpcFqidParams ipcFqid;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_QmIpcMsg));
+ memset(&reply, 0, sizeof(t_QmIpcReply));
+ ipcFqid.fqid = base;
+ ipcFqid.size = size;
+ msg.msgId = QM_FORCE_FQID;
+ memcpy(msg.msgBody, &ipcFqid, sizeof(t_QmIpcFqidParams));
+ replyLength = sizeof(uint32_t) + sizeof(uint32_t);
+ if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_QmIpcFqidParams),
+ (uint8_t*)&reply,
+ &replyLength,
+ NULL,
+ NULL)) != E_OK)
+ REPORT_ERROR(MAJOR, errCode, NO_MSG);
+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+
+ if ((errCode != E_OK) ||
+ (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))))
+ ans = ILLEGAL_BASE;
+ else
+ memcpy((uint8_t*)&ans, reply.replyBody, sizeof(uint32_t));
+ }
+ else
+ {
+ DBG(WARNING, ("No Ipc - can't validate fqid."));
+ ans = base;
+ }
+ }
+ }
+ else
+ ans = MM_Get(p_Qm->h_FqidMm,
+ size,
+ alignment,
+ "QM FQID MEM");
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+
+ return (uint32_t)ans;
+}
+
+t_Error QmFqidPut(t_Qm *p_Qm, uint32_t base)
+{
+ uint32_t intFlags;
+
+ intFlags = XX_LockIntrSpinlock(p_Qm->lock);
+ /* Check maybe this fqid was reserved in the past */
+ if (MM_GetForce(p_Qm->h_RsrvFqidMm,
+ (uint64_t)base,
+ (uint64_t)1,
+ "QM rsrv FQID MEM") == ILLEGAL_BASE)
+ {
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+ return E_OK;
+ }
+ else
+ MM_PutForce(p_Qm->h_RsrvFqidMm,
+ (uint64_t)base,
+ (uint64_t)1);
+ if (MM_InRange(p_Qm->h_FqidMm, (uint64_t)base))
+ {
+ if (MM_Put(p_Qm->h_FqidMm, (uint64_t)base) != 0)
+ {
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+ return E_OK;
+ }
+ else
+ {
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+ return ERROR_CODE(E_NOT_FOUND);
+ }
+ }
+ else if (p_Qm->h_Session)
+ {
+ t_QmIpcMsg msg;
+ t_QmIpcFqidParams ipcFqid;
+ t_Error errCode = E_OK;
+
+ memset(&msg, 0, sizeof(t_QmIpcMsg));
+ ipcFqid.fqid = (uint8_t)base;
+ ipcFqid.size = 0;
+ msg.msgId = QM_PUT_FQID;
+ memcpy(msg.msgBody, &ipcFqid, sizeof(t_QmIpcFqidParams));
+ if ((errCode = XX_IpcSendMessage(p_Qm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId) + sizeof(t_QmIpcFqidParams),
+ NULL,
+ NULL,
+ NULL,
+ NULL)) != E_OK)
+ {
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ }
+ }
+ else
+ DBG(WARNING, ("No Ipc - can't validate fqid."));
+ XX_UnlockIntrSpinlock(p_Qm->lock, intFlags);
+
+ return E_OK;
+}
+
+t_Error QmGetCgId(t_Handle h_Qm, uint8_t *p_CgId)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+ uint16_t i;
+
+ for(i = p_Qm->partCgsBase;i<p_Qm->partCgsBase+p_Qm->partNumOfCgs;i++)
+ if (!p_Qm->cgsUsed[i])
+ {
+ p_Qm->cgsUsed[i] = (uint8_t)TRUE;
+ *p_CgId = (uint8_t)i;
+ break;
+ }
+ if(i == (p_Qm->partCgsBase+p_Qm->partNumOfCgs))
+ RETURN_ERROR(MINOR, E_BUSY, ("No available CG"));
+ else
+ return E_OK;
+}
+
+t_Error QmFreeCgId(t_Handle h_Qm, uint8_t cgId)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+
+ if (!p_Qm->cgsUsed[cgId])
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("CG is not in use"));
+ else
+ p_Qm->cgsUsed[cgId] = (uint8_t)FALSE;
+
+ return E_OK;
+}
+
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+
+t_Handle QM_Config(t_QmParam *p_QmParam)
+{
+ t_Qm *p_Qm;
+ uint8_t i;
+
+ SANITY_CHECK_RETURN_VALUE(p_QmParam, E_INVALID_HANDLE, NULL);
+
+ p_Qm = (t_Qm *)XX_Malloc(sizeof(t_Qm));
+ if (!p_Qm)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM obj!!!"));
+ return NULL;
+ }
+ memset(p_Qm, 0, sizeof(t_Qm));
+ p_Qm->p_QmDriverParams = (t_QmDriverParams *)XX_Malloc(sizeof(t_QmDriverParams));
+ if (!p_Qm->p_QmDriverParams)
+ {
+ XX_Free(p_Qm);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Qm driver parameters"));
+ return NULL;
+ }
+ memset(p_Qm->p_QmDriverParams, 0, sizeof(t_QmDriverParams));
+
+ p_Qm->guestId = p_QmParam->guestId;
+ p_Qm->p_QmDriverParams->partFqidBase = p_QmParam->partFqidBase;
+ p_Qm->p_QmDriverParams->partNumOfFqids = p_QmParam->partNumOfFqids;
+ p_Qm->partCgsBase = p_QmParam->partCgsBase;
+ p_Qm->partNumOfCgs = p_QmParam->partNumOfCgs;
+ p_Qm->p_QmRegs = (t_QmRegs *)UINT_TO_PTR(p_QmParam->baseAddress);
+
+ if (p_Qm->guestId == NCSW_MASTER_ID)
+ {
+ p_Qm->exceptions = DEFAULT_exceptions;
+ p_Qm->f_Exception = p_QmParam->f_Exception;
+ p_Qm->h_App = p_QmParam->h_App;
+ p_Qm->errIrq = p_QmParam->errIrq;
+ p_Qm->p_QmDriverParams->liodn = p_QmParam->liodn;
+ p_Qm->p_QmDriverParams->rtFramesDepth = DEFAULT_rtFramesDepth;
+ p_Qm->p_QmDriverParams->fqdMemPartitionId = p_QmParam->fqdMemPartitionId;
+ p_Qm->p_QmDriverParams->pfdrMemPartitionId = p_QmParam->pfdrMemPartitionId;
+ p_Qm->p_QmDriverParams->swPortalsBaseAddress = p_QmParam->swPortalsBaseAddress;
+ p_Qm->p_QmDriverParams->totalNumOfFqids = p_QmParam->totalNumOfFqids;
+ p_Qm->p_QmDriverParams->pfdrThreshold = DEFAULT_pfdrThreshold;
+ p_Qm->p_QmDriverParams->sfdrThreshold = DEFAULT_sfdrThreshold;
+ p_Qm->p_QmDriverParams->pfdrBaseConstant = DEFAULT_pfdrBaseConstant;
+ for(i= 0;i<DPAA_MAX_NUM_OF_DC_PORTALS;i++)
+ p_Qm->p_QmDriverParams->dcPortalsParams[i].sendToSw =
+ (bool)((i < e_DPAA_DCPORTAL2) ? FALSE : TRUE);
+
+#ifdef QMAN_SFDR_LEAK_ERRATA_QMAN5
+ {
+#define WORKAROUND_TMP_VAL 0x00000003
+ t_QmRevisionInfo revInfo;
+ QmGetRevision(p_Qm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ uint32_t *tmp = (uint32_t *)UINT_TO_PTR(p_QmParam->baseAddress + 0xbf0);
+ uint32_t tmpReg = WORKAROUND_TMP_VAL;
+ WRITE_UINT32(*tmp, tmpReg);
+ while ((tmpReg = GET_UINT32(*tmp)) != WORKAROUND_TMP_VAL) ;
+ }
+ }
+#endif /* QMAN_SFDR_LEAK_ERRATA_QMAN5 */
+ }
+
+ /* build the QM partition IPC address */
+ memset(p_Qm->moduleName, 0, MODULE_NAME_SIZE);
+ if(Sprint (p_Qm->moduleName, "QM_0_%d",p_Qm->guestId) != (p_Qm->guestId<10 ? 6:7))
+ {
+ XX_Free(p_Qm->p_QmDriverParams);
+ XX_Free(p_Qm);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ return NULL;
+ }
+
+ return p_Qm;
+}
+
+t_Error QM_Init(t_Handle h_Qm)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+ t_QmDriverParams *p_QmDriverParams;
+ t_Error err;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
+
+ CHECK_INIT_PARAMETERS(p_Qm, CheckQmParameters);
+
+ p_QmDriverParams = p_Qm->p_QmDriverParams;
+
+ if (p_QmDriverParams->partNumOfFqids)
+ {
+ if (MM_Init(&p_Qm->h_FqidMm, p_QmDriverParams->partFqidBase, p_QmDriverParams->partNumOfFqids) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("QM-FQIDS-MEM partition!!!"));
+ if (MM_Init(&p_Qm->h_RsrvFqidMm, p_QmDriverParams->partFqidBase, p_QmDriverParams->partNumOfFqids) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("QM-Reserve-FQIDS-MEM partition!!!"));
+ }
+
+ if (p_Qm->guestId == NCSW_MASTER_ID)
+ {
+ uint64_t phyAddr;
+ t_QmRevisionInfo revInfo;
+ uint32_t dsSize, exp, i;
+
+ QmGetRevision(p_Qm, &revInfo);
+ DBG(TRACE, ("Qman ver:%02x,%02x", revInfo.majorRev, revInfo.minorRev));
+
+ phyAddr = XX_VirtToPhys(UINT_TO_PTR(p_QmDriverParams->swPortalsBaseAddress));
+ WRITE_UINT32(p_Qm->p_QmRegs->qcsp_bare, ((uint32_t)(phyAddr >> 32) & 0x000000ff));
+ WRITE_UINT32(p_Qm->p_QmRegs->qcsp_bar, (uint32_t)phyAddr);
+ WRITE_UINT32(p_Qm->p_QmRegs->liodnr, (uint16_t)p_QmDriverParams->liodn);
+
+ /* FQD memory */
+ dsSize = (uint32_t)(p_QmDriverParams->totalNumOfFqids * FQD_ENTRY_SIZE);
+ LOG2(dsSize, exp);
+ if (!POWER_OF_2(dsSize)) (exp++);
+ dsSize = (uint32_t)(1 << exp);
+ if (dsSize < (4*KILOBYTE))
+ {
+ dsSize = (4*KILOBYTE);
+ LOG2(dsSize, exp);
+ }
+ p_Qm->p_FqdBase = XX_MallocSmart(dsSize, (int)p_QmDriverParams->fqdMemPartitionId, dsSize);
+ if (!p_Qm->p_FqdBase)
+ {
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FQD obj!!!"));
+ }
+ memset(p_Qm->p_FqdBase, 0, dsSize);
+ CORE_MemoryBarrier();
+ for (i=0; i<dsSize; i+=64)
+ dcbf(PTR_MOVE(p_Qm->p_FqdBase, i));
+ CORE_MemoryBarrier();
+
+ phyAddr = XX_VirtToPhys(p_Qm->p_FqdBase);
+ WRITE_UINT32(p_Qm->p_QmRegs->fqd_bare, ((uint32_t)(phyAddr >> 32) & 0x000000ff));
+ WRITE_UINT32(p_Qm->p_QmRegs->fqd_bar, (uint32_t)phyAddr);
+ WRITE_UINT32(p_Qm->p_QmRegs->fqd_ar, AR_ENABLE | (exp - 1));
+
+ /* PFDR memory */
+ dsSize = (uint32_t)(p_QmDriverParams->rtFramesDepth * (PFDR_ENTRY_SIZE/3));
+ LOG2(dsSize, exp);
+ if (!POWER_OF_2(dsSize)) (exp++);
+ dsSize = (uint32_t)(1 << exp);
+ if (dsSize < (4*KILOBYTE))
+ {
+ dsSize = (4*KILOBYTE);
+ LOG2(dsSize, exp);
+ }
+
+ p_Qm->p_PfdrBase = XX_MallocSmart(dsSize, (int)p_QmDriverParams->pfdrMemPartitionId, dsSize);
+ if (!p_Qm->p_PfdrBase)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("PFDR obj!!!"));
+
+ phyAddr = XX_VirtToPhys(p_Qm->p_PfdrBase);
+ WRITE_UINT32(p_Qm->p_QmRegs->pfdr_bare, ((uint32_t)(phyAddr >> 32) & 0x000000ff));
+ WRITE_UINT32(p_Qm->p_QmRegs->pfdr_bar, (uint32_t)phyAddr);
+ WRITE_UINT32(p_Qm->p_QmRegs->pfdr_ar, AR_ENABLE | (exp - 1));
+
+ if (QmInitPfdr(p_Qm, 8, dsSize / 64 - 8) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("PFDR init failed!!!"));
+
+ /* thresholds */
+ WRITE_UINT32(p_Qm->p_QmRegs->pfdr_fp_lwit, (p_Qm->p_QmDriverParams->pfdrThreshold & 0xffffff));
+ WRITE_UINT32(p_Qm->p_QmRegs->pfdr_cfg, p_Qm->p_QmDriverParams->pfdrBaseConstant);
+ WRITE_UINT32(p_Qm->p_QmRegs->sfdr_cfg, (p_Qm->p_QmDriverParams->sfdrThreshold & 0x3ff));
+
+ p_Qm->numOfPfdr = GET_UINT32(p_Qm->p_QmRegs->pfdr_fpc);
+
+ /* corenet initiator settings */
+ WRITE_UINT32(p_Qm->p_QmRegs->ci_sched_cfg,
+ (CI_SCHED_CFG_EN |
+ (DEFAULT_initiatorSrcciv << CI_SCHED_CFG_SRCCIV_SHIFT) |
+ (DEFAULT_initiatorSrqW << CI_SCHED_CFG_SRQ_W_SHIFT) |
+ (DEFAULT_initiatorRwW << CI_SCHED_CFG_RW_W_SHIFT) |
+ (DEFAULT_initiatorBmanW << CI_SCHED_CFG_BMAN_W_SHIFT)));
+
+ /* HID settings */
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ /* offset 0x0bf0 */
+ WRITE_UINT32(p_Qm->p_QmRegs->res23[144], 0x3);
+ else
+ WRITE_UINT32(p_Qm->p_QmRegs->res23[144], 0x0);
+
+ for(i=0;i<DPAA_MAX_NUM_OF_DC_PORTALS;i++)
+ {
+ if(p_Qm->p_QmDriverParams->dcPortalsParams[i].sendToSw)
+ WRITE_UINT32(p_Qm->p_QmRegs->dcpConfRegs[i].cfg,
+ p_Qm->p_QmDriverParams->dcPortalsParams[i].swPortalId);
+ else
+ WRITE_UINT32(p_Qm->p_QmRegs->dcpConfRegs[i].cfg, QM_DCP_CFG_ED);
+ }
+
+#ifdef QMAN_WQ_CS_CFG_ERRATA_QMAN4
+ {
+ t_QmRevisionInfo revInfo;
+ QmGetRevision(p_Qm, &revInfo);
+ if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
+ {
+ QmSetWqScheduling(p_Qm, e_QM_WQ_SW_PORTALS,0,1,1,1,1,1,1);
+ QmSetWqScheduling(p_Qm, e_QM_WQ_POOLS,0,1,1,1,1,1,1);
+ QmSetWqScheduling(p_Qm, e_QM_WQ_DCP0,0,1,1,1,1,1,1);
+ QmSetWqScheduling(p_Qm, e_QM_WQ_DCP1,0,1,1,1,1,1,1);
+ QmSetWqScheduling(p_Qm, e_QM_WQ_DCP2,0,1,1,1,1,1,1);
+ QmSetWqScheduling(p_Qm, e_QM_WQ_DCP3,0,1,1,1,1,1,1);
+ }
+ }
+#endif /* QMAN_WQ_CS_CFG_ERRATA_QMAN4 */
+
+ WRITE_UINT32(p_Qm->p_QmRegs->err_isr, p_Qm->exceptions);
+ WRITE_UINT32(p_Qm->p_QmRegs->err_ier, p_Qm->exceptions);
+ WRITE_UINT32(p_Qm->p_QmRegs->err_isdr, 0x0);
+ if (p_Qm->errIrq != NO_IRQ)
+ {
+ XX_SetIntr(p_Qm->errIrq, QM_ErrorIsr, p_Qm);
+ XX_EnableIntr(p_Qm->errIrq);
+ }
+ if ((err = XX_IpcRegisterMsgHandler(p_Qm->moduleName, QmHandleIpcMsgCB, p_Qm, QM_IPC_MAX_REPLY_SIZE)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+ }
+ else /* guest mode */
+ {
+ char masterModuleName[MODULE_NAME_SIZE];
+
+ memset(masterModuleName, 0, MODULE_NAME_SIZE);
+ if(Sprint (masterModuleName, "QM_0_%d", NCSW_MASTER_ID) != (NCSW_MASTER_ID<10 ? 6:7))
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
+ }
+
+ p_Qm->h_Session = XX_IpcInitSession(masterModuleName, p_Qm->moduleName);
+ if (p_Qm->h_Session)
+ {
+ t_QmIpcMsg msg;
+ uint8_t isMasterAlive = 0;
+ t_QmIpcReply reply;
+ uint32_t replyLength;
+
+ memset(&msg, 0, sizeof(t_QmIpcMsg));
+ memset(&reply, 0, sizeof(t_QmIpcReply));
+ msg.msgId = QM_MASTER_IS_ALIVE;
+ do
+ {
+ blockingFlag = TRUE;
+ replyLength = sizeof(uint32_t) + sizeof(uint8_t);
+ if ((err = XX_IpcSendMessage(p_Qm->h_Session,
+ (uint8_t*)&msg,
+ sizeof(msg.msgId),
+ (uint8_t*)&reply,
+ &replyLength,
+ QmIpcMsgCompletionCB,
+ p_Qm)) != E_OK)
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ while(blockingFlag) ;
+ if(replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
+ isMasterAlive = *(uint8_t*)(reply.replyBody);
+ } while (!isMasterAlive);
+ }
+ }
+
+ p_Qm->lock = XX_InitSpinlock();
+ XX_Free(p_Qm->p_QmDriverParams);
+ p_Qm->p_QmDriverParams = NULL;
+
+ return E_OK;
+}
+
+t_Error QM_Free(t_Handle h_Qm)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+
+ if (p_Qm->lock)
+ XX_FreeSpinlock(p_Qm->lock);
+
+ if (p_Qm->guestId == NCSW_MASTER_ID)
+ {
+ XX_IpcUnregisterMsgHandler(p_Qm->moduleName);
+ if (p_Qm->errIrq != NO_IRQ)
+ {
+ XX_DisableIntr(p_Qm->errIrq);
+ XX_FreeIntr(p_Qm->errIrq);
+ }
+ }
+ FreeInitResources(p_Qm);
+
+ if (p_Qm->p_QmDriverParams)
+ XX_Free(p_Qm->p_QmDriverParams);
+
+ XX_Free(p_Qm);
+
+ return E_OK;
+}
+
+t_Error QM_ConfigRTFramesDepth(t_Handle h_Qm, uint32_t rtFramesDepth)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
+
+ p_Qm->p_QmDriverParams->rtFramesDepth = rtFramesDepth;
+
+ return E_OK;
+}
+
+t_Error QM_ConfigPfdrThreshold(t_Handle h_Qm, uint32_t threshold)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
+
+ p_Qm->p_QmDriverParams->pfdrThreshold = threshold;
+
+ return E_OK;
+}
+
+t_Error QM_ConfigSfdrReservationThreshold(t_Handle h_Qm, uint32_t threshold)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
+
+ p_Qm->p_QmDriverParams->sfdrThreshold = threshold;
+
+ return E_OK;
+}
+
+
+t_Error QM_ConfigErrorRejectionNotificationDest(t_Handle h_Qm, e_DpaaDcPortal id, t_QmDcPortalParams *p_Params)
+{
+ UNUSED(h_Qm); UNUSED(id); UNUSED(p_Params);
+
+ RETURN_ERROR(INFO, E_NOT_SUPPORTED, ("Only default ERN destination available."));
+}
+
+
+t_Error QM_Poll(t_Handle h_Qm, e_QmPortalPollSource source)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+ t_QmPortal *p_QmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ p_QmPortal = QmGetPortalHandle(p_Qm);
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+
+ return QM_PORTAL_Poll(p_QmPortal, source);
+}
+
+uint32_t QM_GetCounter(t_Handle h_Qm, e_QmCounters counter)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+
+ SANITY_CHECK_RETURN_VALUE(p_Qm, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE(!p_Qm->p_QmDriverParams, E_INVALID_STATE, 0);
+
+ switch(counter)
+ {
+ case(e_QM_COUNTERS_SFDR_IN_USE):
+ return QmGetCounter(p_Qm, e_QM_IM_COUNTERS_SFDR_IN_USE);
+ case(e_QM_COUNTERS_PFDR_IN_USE):
+ return QmGetCounter(p_Qm, e_QM_IM_COUNTERS_PFDR_IN_USE);
+ case(e_QM_COUNTERS_PFDR_FREE_POOL):
+ return QmGetCounter(p_Qm, e_QM_IM_COUNTERS_PFDR_FREE_POOL);
+ default:
+ break;
+ }
+ /* should never get here */
+ ASSERT_COND(FALSE);
+
+ return 0;
+}
+
+void QM_ErrorIsr(t_Handle h_Qm)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+ uint32_t tmpReg;
+
+ SANITY_CHECK_RETURN(p_Qm, E_INVALID_HANDLE);
+
+ if (p_Qm->guestId != NCSW_MASTER_ID)
+ {
+ REPORT_ERROR(WARNING, E_INVALID_OPERATION, ("Master Only"));
+ return;
+ }
+
+ tmpReg = GET_UINT32(p_Qm->p_QmRegs->err_isr);
+ tmpReg &= GET_UINT32(p_Qm->p_QmRegs->err_ier);
+ WRITE_UINT32(p_Qm->p_QmRegs->err_isr, tmpReg);
+
+ if (tmpReg & QM_EX_CORENET_INITIATOR_DATA)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_CORENET_INITIATOR_DATA);
+ if (tmpReg & QM_EX_CORENET_TARGET_DATA)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_CORENET_TARGET_DATA);
+ if (tmpReg & QM_EX_CORENET_INVALID_TARGET_TRANSACTION)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_CORENET_INVALID_TARGET_TRANSACTION);
+ if (tmpReg & QM_EX_PFDR_THRESHOLD)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_PFDR_THRESHOLD);
+ if (tmpReg & QM_EX_MULTI_ECC)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_MULTI_ECC);
+ if (tmpReg & QM_EX_SINGLE_ECC)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_SINGLE_ECC);
+ if (tmpReg & QM_EX_PFDR_ENQUEUE_BLOCKED)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_PFDR_ENQUEUE_BLOCKED);
+ if (tmpReg & QM_EX_INVALID_COMMAND)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_INVALID_COMMAND);
+ if (tmpReg & QM_EX_DEQUEUE_DCP)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_DCP);
+ if (tmpReg & QM_EX_DEQUEUE_FQ)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_FQ);
+ if (tmpReg & QM_EX_DEQUEUE_SOURCE)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_SOURCE);
+ if (tmpReg & QM_EX_DEQUEUE_QUEUE)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_DEQUEUE_QUEUE);
+ if (tmpReg & QM_EX_ENQUEUE_OVERFLOW)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_OVERFLOW);
+ if (tmpReg & QM_EX_ENQUEUE_STATE)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_STATE);
+ if (tmpReg & QM_EX_ENQUEUE_CHANNEL)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_CHANNEL);
+ if (tmpReg & QM_EX_ENQUEUE_QUEUE)
+ p_Qm->f_Exception(p_Qm->h_App, e_QM_EX_ENQUEUE_QUEUE);
+}
+
+t_Error QM_SetException(t_Handle h_Qm, e_QmExceptions exception, bool enable)
+{
+ t_Qm *p_Qm = (t_Qm*)h_Qm;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
+
+ if ((err = SetException(p_Qm, exception, enable)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+
+ WRITE_UINT32(p_Qm->p_QmRegs->err_ier, p_Qm->exceptions);
+
+ return E_OK;
+}
+
+t_Error QM_GetRevision(t_Handle h_Qm, t_QmRevisionInfo *p_QmRevisionInfo)
+{
+ t_Qm *p_Qm = (t_Qm*)h_Qm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_QmRevisionInfo, E_NULL_POINTER);
+
+ return QmGetRevision(p_Qm, p_QmRevisionInfo);
+}
+
+t_Error QM_ReserveQueues(t_Handle h_Qm, t_QmRsrvFqrParams *p_QmFqrParams, uint32_t *p_BaseFqid)
+{
+ t_Qm *p_Qm = (t_Qm*)h_Qm;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
+
+ *p_BaseFqid = ReserveFqids(p_Qm,
+ (uint32_t)((p_QmFqrParams->useForce && !p_QmFqrParams->numOfFqids) ?
+ 1 : p_QmFqrParams->numOfFqids),
+ p_QmFqrParams->qs.nonFrcQs.align,
+ p_QmFqrParams->useForce,
+ p_QmFqrParams->qs.frcQ.fqid);
+ if (*p_BaseFqid == ILLEGAL_BASE)
+ RETURN_ERROR(CRITICAL,E_INVALID_STATE,("can't allocate a fqid"));
+
+ return E_OK;
+}
+
+t_Error QM_GetErrorInformation(t_Handle h_Qm, t_QmErrorInfo *p_errInfo)
+{
+ uint32_t ecsr, ecir;
+ t_Qm *p_Qm = (t_Qm*)h_Qm;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_errInfo, E_NULL_POINTER);
+
+ ecsr = GET_UINT32(p_Qm->p_QmRegs->ecsr);
+ ecir = GET_UINT32(p_Qm->p_QmRegs->ecir);
+ if ((ecsr & QM_EX_MULTI_ECC) ||
+ (ecsr & QM_EX_SINGLE_ECC))
+ {
+ err = E_NOT_SUPPORTED;
+ REPORT_ERROR(INFO, E_NOT_SUPPORTED, ("single and multi ecc, use QM_DumpRegs"));
+ }
+ if ((ecsr & QM_EX_ENQUEUE_QUEUE) ||
+ (ecsr & QM_EX_ENQUEUE_STATE) ||
+ (ecsr & QM_EX_ENQUEUE_OVERFLOW) ||
+ (ecsr & QM_EX_DEQUEUE_DCP) ||
+ (ecsr & QM_EX_DEQUEUE_FQ) ||
+ (ecsr & QM_EX_DEQUEUE_QUEUE) ||
+ (ecsr & QM_EX_DEQUEUE_SOURCE) ||
+ (ecsr & QM_EX_INVALID_COMMAND))
+ {
+ p_errInfo->portalValid = TRUE;
+ p_errInfo->hwPortal = (bool)(ecir & ECIR_PORTAL_TYPE);
+ if (p_errInfo->hwPortal)
+ p_errInfo->dcpId = (e_DpaaDcPortal)((ecir & ECIR_PORTAL_MASK) >> ECIR_PORTAL_SHIFT);
+ else
+ p_errInfo->swPortalId = (e_DpaaSwPortal)((ecir & ECIR_PORTAL_MASK) >> ECIR_PORTAL_SHIFT);
+ }
+
+ if ((ecsr & QM_EX_ENQUEUE_QUEUE) ||
+ (ecsr & QM_EX_ENQUEUE_STATE) ||
+ (ecsr & QM_EX_ENQUEUE_OVERFLOW) ||
+ (ecsr & QM_EX_ENQUEUE_CHANNEL) ||
+ (ecsr & QM_EX_DEQUEUE_QUEUE) ||
+ (ecsr & QM_EX_DEQUEUE_FQ))
+ {
+ p_errInfo->fqidValid = TRUE;
+ p_errInfo->fqid = ((ecir & ECIR_FQID_MASK) >> ECIR_FQID_SHIFT);
+ }
+
+ WRITE_UINT32(p_Qm->p_QmRegs->ecsr, ecsr);
+
+ return ERROR_CODE(err);
+}
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+t_Error QM_DumpRegs(t_Handle h_Qm)
+{
+ t_Qm *p_Qm = (t_Qm *)h_Qm;
+ uint8_t i = 0;
+
+ DECLARE_DUMP;
+
+ SANITY_CHECK_RETURN_ERROR(p_Qm, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(!p_Qm->p_QmDriverParams, E_INVALID_STATE);
+
+ DUMP_SUBTITLE(("\n"));
+ DUMP_TITLE(p_Qm->p_QmRegs, ("QmRegs Regs"));
+
+ DUMP_SUBSTRUCT_ARRAY(i, QM_NUM_OF_SWP)
+ {
+ DUMP_VAR(&p_Qm->p_QmRegs->swpConfRegs[i], lio_cfg);
+ DUMP_VAR(&p_Qm->p_QmRegs->swpConfRegs[i], io_cfg);
+ DUMP_VAR(&p_Qm->p_QmRegs->swpConfRegs[i], dd_cfg);
+ }
+ DUMP_VAR(p_Qm->p_QmRegs, qman_dd_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, qcsp_dd_ihrsr);
+ DUMP_VAR(p_Qm->p_QmRegs, qcsp_dd_ihrfr);
+ DUMP_VAR(p_Qm->p_QmRegs, qcsp_dd_hasr);
+ DUMP_VAR(p_Qm->p_QmRegs, dcp_dd_ihrsr);
+ DUMP_VAR(p_Qm->p_QmRegs, dcp_dd_ihrfr);
+ DUMP_VAR(p_Qm->p_QmRegs, dcp_dd_hasr);
+ DUMP_SUBSTRUCT_ARRAY(i, QM_NUM_OF_DCP)
+ {
+ DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], cfg);
+ DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], dd_cfg);
+ DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], dlm_cfg);
+ DUMP_VAR(&p_Qm->p_QmRegs->dcpConfRegs[i], dlm_avg);
+ }
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_fpc);
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_fp_head);
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_fp_tail);
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_fp_lwit);
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, sfdr_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, sfdr_in_use);
+ DUMP_ARR(p_Qm->p_QmRegs, wq_cs_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, wq_def_enq_wqid);
+ DUMP_ARR(p_Qm->p_QmRegs, wq_sc_dd_cfg);
+ DUMP_ARR(p_Qm->p_QmRegs, wq_pc_dd_cs_cfg);
+ DUMP_ARR(p_Qm->p_QmRegs, wq_dc0_dd_cs_cfg);
+ DUMP_ARR(p_Qm->p_QmRegs, wq_dc1_dd_cs_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, wq_dc2_dd_cs_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, wq_dc3_dd_cs_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, cm_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, ecsr);
+ DUMP_VAR(p_Qm->p_QmRegs, ecir);
+ DUMP_VAR(p_Qm->p_QmRegs, eadr);
+ DUMP_ARR(p_Qm->p_QmRegs, edata);
+ DUMP_VAR(p_Qm->p_QmRegs, sbet);
+ DUMP_ARR(p_Qm->p_QmRegs, sbec);
+ DUMP_VAR(p_Qm->p_QmRegs, mcr);
+ DUMP_VAR(p_Qm->p_QmRegs, mcp0);
+ DUMP_VAR(p_Qm->p_QmRegs, mcp1);
+ DUMP_ARR(p_Qm->p_QmRegs, mr);
+ DUMP_VAR(p_Qm->p_QmRegs, idle_stat);
+ DUMP_VAR(p_Qm->p_QmRegs, ip_rev_1);
+ DUMP_VAR(p_Qm->p_QmRegs, ip_rev_2);
+ DUMP_VAR(p_Qm->p_QmRegs, fqd_bare);
+ DUMP_VAR(p_Qm->p_QmRegs, fqd_bar);
+ DUMP_VAR(p_Qm->p_QmRegs, fqd_ar);
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_bare);
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_bar);
+ DUMP_VAR(p_Qm->p_QmRegs, pfdr_ar);
+ DUMP_VAR(p_Qm->p_QmRegs, qcsp_bare);
+ DUMP_VAR(p_Qm->p_QmRegs, qcsp_bar);
+ DUMP_VAR(p_Qm->p_QmRegs, ci_sched_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, srcidr);
+ DUMP_VAR(p_Qm->p_QmRegs, liodnr);
+ DUMP_VAR(p_Qm->p_QmRegs, ci_rlm_cfg);
+ DUMP_VAR(p_Qm->p_QmRegs, ci_rlm_avg);
+ DUMP_VAR(p_Qm->p_QmRegs, err_isr);
+ DUMP_VAR(p_Qm->p_QmRegs, err_ier);
+ DUMP_VAR(p_Qm->p_QmRegs, err_isdr);
+ DUMP_VAR(p_Qm->p_QmRegs, err_iir);
+ DUMP_VAR(p_Qm->p_QmRegs, err_her);
+
+ return E_OK;
+}
+#endif /* (defined(DEBUG_ERRORS) && ... */
diff --git a/sys/contrib/ncsw/Peripherals/QM/qm.h b/sys/contrib/ncsw/Peripherals/QM/qm.h
new file mode 100644
index 0000000..68af185
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/QM/qm.h
@@ -0,0 +1,651 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File qm.h
+
+ @Description QM header
+*//***************************************************************************/
+#ifndef __QM_H
+#define __QM_H
+
+#include "std_ext.h"
+#include "list_ext.h"
+#include "qm_ext.h"
+#include "qman_private.h"
+#include "qm_ipc.h"
+
+
+#define __ERR_MODULE__ MODULE_QM
+
+#define QM_NUM_OF_SWP 10
+#define QM_NUM_OF_DCP 5
+
+#define CACHELINE_SIZE 64
+#define QM_CONTEXTA_MAX_STASH_SIZE (3 * CACHELINE_SIZE)
+
+/**************************************************************************//**
+ @Description Exceptions
+*//***************************************************************************/
+#define QM_EX_CORENET_INITIATOR_DATA 0x20000000
+#define QM_EX_CORENET_TARGET_DATA 0x10000000
+#define QM_EX_CORENET_INVALID_TARGET_TRANSACTION 0x08000000
+#define QM_EX_PFDR_THRESHOLD 0x04000000
+#define QM_EX_MULTI_ECC 0x02000000
+#define QM_EX_SINGLE_ECC 0x01000000
+#define QM_EX_PFDR_ENQUEUE_BLOCKED 0x00800000
+#define QM_EX_INVALID_COMMAND 0x00010000
+#define QM_EX_DEQUEUE_DCP 0x00000800
+#define QM_EX_DEQUEUE_FQ 0x00000400
+#define QM_EX_DEQUEUE_SOURCE 0x00000200
+#define QM_EX_DEQUEUE_QUEUE 0x00000100
+#define QM_EX_ENQUEUE_OVERFLOW 0x00000008
+#define QM_EX_ENQUEUE_STATE 0x00000004
+#define QM_EX_ENQUEUE_CHANNEL 0x00000002
+#define QM_EX_ENQUEUE_QUEUE 0x00000001
+
+#define GET_EXCEPTION_FLAG(bitMask, exception) switch(exception){ \
+ case e_QM_EX_CORENET_INITIATOR_DATA: \
+ bitMask = QM_EX_CORENET_INITIATOR_DATA; break; \
+ case e_QM_EX_CORENET_TARGET_DATA: \
+ bitMask = QM_EX_CORENET_TARGET_DATA; break; \
+ case e_QM_EX_CORENET_INVALID_TARGET_TRANSACTION: \
+ bitMask = QM_EX_CORENET_INVALID_TARGET_TRANSACTION; break; \
+ case e_QM_EX_PFDR_THRESHOLD: \
+ bitMask = QM_EX_PFDR_THRESHOLD; break; \
+ case e_QM_EX_PFDR_ENQUEUE_BLOCKED: \
+ bitMask = QM_EX_PFDR_ENQUEUE_BLOCKED; break; \
+ case e_QM_EX_SINGLE_ECC: \
+ bitMask = QM_EX_SINGLE_ECC; break; \
+ case e_QM_EX_MULTI_ECC: \
+ bitMask = QM_EX_MULTI_ECC; break; \
+ case e_QM_EX_INVALID_COMMAND: \
+ bitMask = QM_EX_INVALID_COMMAND; break; \
+ case e_QM_EX_DEQUEUE_DCP: \
+ bitMask = QM_EX_DEQUEUE_DCP; break; \
+ case e_QM_EX_DEQUEUE_FQ: \
+ bitMask = QM_EX_DEQUEUE_FQ; break; \
+ case e_QM_EX_DEQUEUE_SOURCE: \
+ bitMask = QM_EX_DEQUEUE_SOURCE; break; \
+ case e_QM_EX_DEQUEUE_QUEUE: \
+ bitMask = QM_EX_DEQUEUE_QUEUE; break; \
+ case e_QM_EX_ENQUEUE_OVERFLOW: \
+ bitMask = QM_EX_ENQUEUE_OVERFLOW; break; \
+ case e_QM_EX_ENQUEUE_STATE: \
+ bitMask = QM_EX_ENQUEUE_STATE; break; \
+ case e_QM_EX_ENQUEUE_CHANNEL: \
+ bitMask = QM_EX_ENQUEUE_CHANNEL; break; \
+ case e_QM_EX_ENQUEUE_QUEUE: \
+ bitMask = QM_EX_ENQUEUE_QUEUE; break; \
+ default: bitMask = 0;break;}
+
+/**************************************************************************//**
+ @Description defaults
+*//***************************************************************************/
+/* QM defaults */
+#define DEFAULT_exceptions ((uint32_t)(QM_EX_CORENET_INITIATOR_DATA | \
+ QM_EX_CORENET_TARGET_DATA | \
+ QM_EX_CORENET_INVALID_TARGET_TRANSACTION | \
+ QM_EX_PFDR_THRESHOLD | \
+ QM_EX_SINGLE_ECC | \
+ QM_EX_MULTI_ECC | \
+ QM_EX_PFDR_ENQUEUE_BLOCKED | \
+ QM_EX_INVALID_COMMAND | \
+ QM_EX_DEQUEUE_DCP | \
+ QM_EX_DEQUEUE_FQ | \
+ QM_EX_DEQUEUE_SOURCE | \
+ QM_EX_DEQUEUE_QUEUE | \
+ QM_EX_ENQUEUE_OVERFLOW | \
+ QM_EX_ENQUEUE_STATE | \
+ QM_EX_ENQUEUE_CHANNEL | \
+ QM_EX_ENQUEUE_QUEUE ))
+#define DEFAULT_rtFramesDepth 30000
+#define DEFAULT_pfdrThreshold 0
+#define DEFAULT_sfdrThreshold 0
+#define DEFAULT_pfdrBaseConstant 64
+/* Corenet initiator settings. Stash request queues are 4-deep to match cores'
+ ability to snart. Stash priority is 3, other priorities are 2. */
+#define DEFAULT_initiatorSrcciv 0
+#define DEFAULT_initiatorSrqW 3
+#define DEFAULT_initiatorRwW 2
+#define DEFAULT_initiatorBmanW 2
+
+
+/* QM-Portal defaults */
+#define DEFAULT_dequeueDcaMode FALSE
+#define DEFAULT_dequeueUpToThreeFrames TRUE
+#define DEFAULT_dequeueCommandType e_QM_PORTAL_PRIORITY_PRECEDENCE_INTRA_CLASS_SCHEDULING
+#define DEFAULT_dequeueUserToken 0xab
+#define DEFAULT_dequeueSpecifiedWq FALSE
+#define DEFAULT_dequeueDedicatedChannel TRUE
+#define DEFAULT_dequeuePoolChannelId 0
+#define DEFAULT_dequeueWqId 0
+#define DEFAULT_dequeueDedicatedChannelHasPrecedenceOverPoolChannels TRUE
+#define DEFAULT_dqrrSize DQRR_MAXFILL
+#define DEFAULT_pullMode FALSE
+#define DEFAULT_portalExceptions ((uint32_t)(QM_PIRQ_EQCI | \
+ QM_PIRQ_EQRI | \
+ QM_PIRQ_DQRI | \
+ QM_PIRQ_MRI | \
+ QM_PIRQ_CSCI))
+
+/**************************************************************************//**
+ @Description Memory Mapped Registers
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct
+{
+ /* QMan Software Portal Configuration Registers */
+ _Packed struct {
+ volatile uint32_t lio_cfg; /**< QMan Software Portal LIO Configuration */
+ volatile uint32_t io_cfg; /**< QMan Software Portal 0 IO Configuration */
+ volatile uint8_t res1[4]; /**< reserved */
+ volatile uint32_t dd_cfg; /**< Software Portal Dynamic Debug Configuration */
+ } _PackedType swpConfRegs[QM_NUM_OF_SWP];
+ volatile uint8_t res1[352]; /**< reserved */
+
+ /* Dynamic Debug (DD) Configuration Registers */
+ volatile uint32_t qman_dd_cfg; /**< QMan Dynamic Debug (DD) Configuration */
+ volatile uint8_t res2[12]; /**< reserved */
+ volatile uint32_t qcsp_dd_ihrsr; /**< Software Portal DD Internal Halt Request Status */
+ volatile uint32_t qcsp_dd_ihrfr; /**< Software Portal DD Internal Halt Request Force */
+ volatile uint32_t qcsp_dd_hasr; /**< Software Portal DD Halt Acknowledge Status */
+ volatile uint8_t res3[4]; /**< reserved */
+ volatile uint32_t dcp_dd_ihrsr; /**< DCP DD Internal Halt Request Status */
+ volatile uint32_t dcp_dd_ihrfr; /**< DCP DD Internal Halt Request Force */
+ volatile uint32_t dcp_dd_hasr; /**< DCP DD Halt Acknowledge Status */
+ volatile uint8_t res4[212]; /**< reserved */
+
+ /* Direct Connect Portal (DCP) Configuration Registers */
+ _Packed struct {
+ volatile uint32_t cfg; /**< DCP Configuration */
+ volatile uint32_t dd_cfg; /**< DCP Dynamic Debug Configuration */
+ volatile uint32_t dlm_cfg; /**< DCP Dequeue Latency Monitor Configuration */
+ volatile uint32_t dlm_avg; /**< DCP Dequeue Latency Monitor Average */
+ } _PackedType dcpConfRegs[QM_NUM_OF_DCP];
+ volatile uint8_t res5[176]; /**< reserved */
+
+ /* Packed Frame Descriptor Record (PFDR) Manager Query Registers */
+ volatile uint32_t pfdr_fpc; /**< PFDR Free Pool Count */
+ volatile uint32_t pfdr_fp_head; /**< PFDR Free Pool Head Pointer */
+ volatile uint32_t pfdr_fp_tail; /**< PFDR Free Pool Tail Pointer */
+ volatile uint8_t res6[4]; /**< reserved */
+ volatile uint32_t pfdr_fp_lwit; /**< PFDR Free Pool Low Watermark Interrupt Threshold */
+ volatile uint32_t pfdr_cfg; /**< PFDR Configuration */
+ volatile uint8_t res7[232]; /**< reserved */
+
+ /* Single Frame Descriptor Record (SFDR) Manager Registers */
+ volatile uint32_t sfdr_cfg; /**< SFDR Configuration */
+ volatile uint32_t sfdr_in_use; /**< SFDR In Use Register */
+ volatile uint8_t res8[248]; /**< reserved */
+
+ /* Work Queue Semaphore and Context Manager Registers */
+ volatile uint32_t wq_cs_cfg[6]; /**< Work Queue Class Scheduler Configuration */
+ volatile uint8_t res9[24]; /**< reserved */
+ volatile uint32_t wq_def_enq_wqid; /**< Work Queue Default Enqueue WQID */
+ volatile uint8_t res10[12]; /**< reserved */
+ volatile uint32_t wq_sc_dd_cfg[5]; /**< WQ S/W Channel Dynamic Debug Config */
+ volatile uint8_t res11[44]; /**< reserved */
+ volatile uint32_t wq_pc_dd_cs_cfg[8]; /**< WQ Pool Channel Dynamic Debug Config */
+ volatile uint8_t res12[32]; /**< reserved */
+ volatile uint32_t wq_dc0_dd_cs_cfg[6]; /**< WQ DCP0 Chan. Dynamic Debug Config */
+ volatile uint8_t res13[40]; /**< reserved */
+ volatile uint32_t wq_dc1_dd_cs_cfg[6]; /**< WQ DCP1 Chan. Dynamic Debug Config */
+ volatile uint8_t res14[40]; /**< reserved */
+ volatile uint32_t wq_dc2_dd_cs_cfg; /**< WQ DCP2 Chan. Dynamic Debug Config */
+ volatile uint8_t res15[60]; /**< reserved */
+ volatile uint32_t wq_dc3_dd_cs_cfg; /**< WQ DCP3 Chan. Dynamic Debug Config */
+ volatile uint8_t res16[124]; /**< reserved */
+
+ /* Congestion Manager (CM) Registers */
+ volatile uint32_t cm_cfg; /**< CM Configuration Register */
+ volatile uint8_t res17[508]; /**< reserved */
+
+ /* QMan Error Capture Registers */
+ volatile uint32_t ecsr; /**< QMan Error Capture Status Register */
+ volatile uint32_t ecir; /**< QMan Error Capture Information Register */
+ volatile uint32_t eadr; /**< QMan Error Capture Address Register */
+ volatile uint8_t res18[4]; /**< reserved */
+ volatile uint32_t edata[16]; /**< QMan ECC Error Data Register */
+ volatile uint8_t res19[32]; /**< reserved */
+ volatile uint32_t sbet; /**< QMan Single Bit ECC Error Threshold Register */
+ volatile uint8_t res20[12]; /**< reserved */
+ volatile uint32_t sbec[7]; /**< QMan Single Bit ECC Error Count Register */
+ volatile uint8_t res21[100]; /**< reserved */
+
+ /* QMan Initialization and Debug Control Registers */
+ volatile uint32_t mcr; /**< QMan Management Command/Result Register */
+ volatile uint32_t mcp0; /**< QMan Management Command Parameter 0 Register */
+ volatile uint32_t mcp1; /**< QMan Management Command Parameter 1 Register */
+ volatile uint8_t res22[20]; /**< reserved */
+ volatile uint32_t mr[16]; /**< QMan Management Return Register */
+ volatile uint8_t res23[148]; /**< reserved */
+ volatile uint32_t idle_stat; /**< QMan Idle Status Register */
+
+ /* QMan ID/Revision Registers */
+ volatile uint32_t ip_rev_1; /**< QMan IP Block Revision 1 register */
+ volatile uint32_t ip_rev_2; /**< QMan IP Block Revision 2 register */
+
+ /* QMan Initiator Interface Memory Window Configuration Registers */
+ volatile uint32_t fqd_bare; /**< FQD Extended Base Address Register */
+ volatile uint32_t fqd_bar; /**< Frame Queue Descriptor (FQD) Base Address Register */
+ volatile uint8_t res24[8]; /**< reserved */
+ volatile uint32_t fqd_ar; /**< FQD Attributes Register */
+ volatile uint8_t res25[12]; /**< reserved */
+ volatile uint32_t pfdr_bare; /**< PFDR Extended Base Address Register */
+ volatile uint32_t pfdr_bar; /**< Packed Frame Descriptor Record (PFDR) Base Addr */
+ volatile uint8_t res26[8]; /**< reserved */
+ volatile uint32_t pfdr_ar; /**< PFDR Attributes Register */
+ volatile uint8_t res27[76]; /**< reserved */
+ volatile uint32_t qcsp_bare; /**< QCSP Extended Base Address */
+ volatile uint32_t qcsp_bar; /**< QMan Software Portal Base Address */
+ volatile uint8_t res28[120]; /**< reserved */
+ volatile uint32_t ci_sched_cfg; /**< Initiator Scheduling Configuration */
+ volatile uint32_t srcidr; /**< QMan Source ID Register */
+ volatile uint32_t liodnr; /**< QMan Logical I/O Device Number Register */
+ volatile uint8_t res29[4]; /**< reserved */
+ volatile uint32_t ci_rlm_cfg; /**< Initiator Read Latency Monitor Configuration */
+ volatile uint32_t ci_rlm_avg; /**< Initiator Read Latency Monitor Average */
+ volatile uint8_t res30[232]; /**< reserved */
+
+ /* QMan Interrupt and Error Registers */
+ volatile uint32_t err_isr; /**< QMan Error Interrupt Status Register */
+ volatile uint32_t err_ier; /**< QMan Error Interrupt Enable Register */
+ volatile uint32_t err_isdr; /**< QMan Error Interrupt Status Disable Register */
+ volatile uint32_t err_iir; /**< QMan Error Interrupt Inhibit Register */
+ volatile uint8_t res31[4]; /**< reserved */
+ volatile uint32_t err_her; /**< QMan Error Halt Enable Register */
+
+} _PackedType t_QmRegs;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/**************************************************************************//**
+ @Description General defines
+*//***************************************************************************/
+
+#define MODULE_NAME_SIZE 30
+
+#define PORTALS_OFFSET_CE(portal) (0x4000 * portal)
+#define PORTALS_OFFSET_CI(portal) (0x1000 * portal)
+
+#define PFDR_ENTRY_SIZE 64 /* 64 bytes */
+#define FQD_ENTRY_SIZE 64 /* 64 bytes */
+
+/* Compilation constants */
+#define DQRR_MAXFILL 15
+#define EQCR_THRESH 1 /* reread h/w CI when running out of space */
+
+/**************************************************************************//**
+ @Description Register defines
+*//***************************************************************************/
+
+/* Assists for QMAN_MCR */
+#define MCR_INIT_PFDR 0x01000000
+#define MCR_get_rslt(v) (uint8_t)((v) >> 24)
+#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
+#define MCR_rslt_ok(r) (rslt == 0xf0)
+#define MCR_rslt_eaccess(r) (rslt == 0xf8)
+#define MCR_rslt_inval(r) (rslt == 0xff)
+
+/* masks */
+#define REV1_MAJOR_MASK 0x0000FF00
+#define REV1_MINOR_MASK 0x000000FF
+
+#define REV2_INTEG_MASK 0x00FF0000
+#define REV2_ERR_MASK 0x0000FF00
+#define REV2_CFG_MASK 0x000000FF
+
+#define AR_ENABLE 0x80000000
+#define AR_PRIORITY 0x40000000
+#define AR_STASH 0x20000000
+#define AR_SIZE_MASK 0x0000003f
+
+#define ECIR_PORTAL_TYPE 0x20000000
+#define ECIR_PORTAL_MASK 0x1f000000
+#define ECIR_FQID_MASK 0x00ffffff
+
+#define CI_SCHED_CFG_EN 0x80000000
+/* shifts */
+#define REV1_MAJOR_SHIFT 8
+#define REV1_MINOR_SHIFT 0
+
+#define REV2_INTEG_SHIFT 16
+#define REV2_ERR_SHIFT 8
+#define REV2_CFG_SHIFT 0
+
+#define AR_SIZE_SHIFT 0
+
+#define ECIR_PORTAL_SHIFT 24
+#define ECIR_FQID_SHIFT 0
+
+#define CI_SCHED_CFG_SRCCIV_SHIFT 24
+#define CI_SCHED_CFG_SRQ_W_SHIFT 8
+#define CI_SCHED_CFG_RW_W_SHIFT 4
+#define CI_SCHED_CFG_BMAN_W_SHIFT 0
+
+
+/********* CGR ******************************/
+#define QM_CGR_TARG_FIRST_SWPORTAL 0x80000000
+#define QM_CGR_TARG_FIRST_DCPORTAL 0x00200000
+#define QM_CGR_TARGET_SWP(portlaId) (QM_CGR_TARG_FIRST_SWPORTAL >> portlaId)
+#define QM_CGR_TARGET_DCP(portlaId) (QM_CGR_TARG_FIRST_DCPORTAL >> portlaId)
+
+
+#define QM_DCP_CFG_ED 0x00000100
+/*
+#define CGR_VALID 0x80
+#define CGR_VERB_INIT 0x50
+#define CGR_VERB_MODIFY 0x51
+#define CGR_WRITE_ALL 0x07FF
+#define CGR_WRITE_ENABLE_CSCN 0x0010
+#define CGR_WRITE_ENABLE_GREEN_MODIFY 0x0380
+#define CGR_WRITE_ENABLE_YELLOW_MODIFY 0x0240
+#define CGR_WRITE_ENABLE_RED_MODIFY 0x0120
+
+
+#define CGR_MODE_BYTE 0x00
+#define CGR_MODE_FRAME 0x01
+#define GCR_ENABLE_WRED 0x01
+#define GCR_ENABLE_TD 0x01
+#define GCR_ENABLE_CSCN 0x01
+*/
+
+
+/* Lock/unlock frame queues, subject to the "UNLOCKED" flag. This is about
+ * inter-processor locking only. */
+#define FQLOCK(fq) \
+ do { \
+ if (fq->flags & QMAN_FQ_FLAG_LOCKED) \
+ XX_LockSpinlock(&fq->fqlock); \
+ } while(0)
+#define FQUNLOCK(fq) \
+ do { \
+ if (fq->flags & QMAN_FQ_FLAG_LOCKED) \
+ XX_UnlockSpinlock(&fq->fqlock); \
+ } while(0)
+
+/* Lock/unlock portals, subject to "UNLOCKED" flag. This is about disabling
+ * interrupts/preemption and, if FLAG_UNLOCKED isn't defined, inter-processor
+ * locking as well. */
+#define NCSW_PLOCK(p) ((t_QmPortal*)(p))->irq_flags = XX_DisableAllIntr()
+#define PUNLOCK(p) XX_RestoreAllIntr(((t_QmPortal*)(p))->irq_flags)
+
+
+typedef void (t_QmLoopDequeueRing)(t_Handle h_QmPortal);
+
+/* Follows WQ_CS_CFG0-5 */
+typedef enum {
+ e_QM_WQ_SW_PORTALS = 0,
+ e_QM_WQ_POOLS,
+ e_QM_WQ_DCP0,
+ e_QM_WQ_DCP1,
+ e_QM_WQ_DCP2,
+ e_QM_WQ_DCP3
+} e_QmWqClass;
+
+typedef enum {
+ e_QM_PORTAL_NO_DEQUEUES = 0,
+ e_QM_PORTAL_PRIORITY_PRECEDENCE_INTRA_CLASS_SCHEDULING,
+ e_QM_PORTAL_ACTIVE_FQ_PRECEDENCE_INTRA_CLASS_SCHEDULING,
+ e_QM_PORTAL_ACTIVE_FQ_PRECEDENCE_OVERRIDE_INTRA_CLASS_SCHEDULING
+} e_QmPortalDequeueCommandType;
+
+typedef enum e_QmInterModuleCounters {
+ e_QM_IM_COUNTERS_SFDR_IN_USE = 0,
+ e_QM_IM_COUNTERS_PFDR_IN_USE,
+ e_QM_IM_COUNTERS_PFDR_FREE_POOL
+} e_QmInterModuleCounters;
+
+typedef struct t_QmInterModulePortalInitParams {
+ uint8_t portalId;
+ uint8_t stashDestQueue;
+ uint16_t liodn;
+ uint16_t dqrrLiodn;
+ uint16_t fdFqLiodn;
+} t_QmInterModulePortalInitParams;
+
+typedef struct t_QmCg {
+ t_Handle h_Qm;
+ t_Handle h_QmPortal;
+ t_QmExceptionsCallback *f_Exception;
+ t_Handle h_App;
+ uint8_t id;
+} t_QmCg;
+
+typedef struct {
+ uintptr_t swPortalsBaseAddress; /**< QM Software Portals Base Address (virtual) */
+ uint32_t partFqidBase;
+ uint32_t partNumOfFqids;
+ uint32_t totalNumOfFqids;
+ uint32_t rtFramesDepth;
+ uint32_t fqdMemPartitionId;
+ uint32_t pfdrMemPartitionId;
+ uint32_t pfdrThreshold;
+ uint32_t sfdrThreshold;
+ uint32_t pfdrBaseConstant;
+ uint16_t liodn;
+ t_QmDcPortalParams dcPortalsParams[DPAA_MAX_NUM_OF_DC_PORTALS];
+} t_QmDriverParams;
+
+typedef struct {
+ uint8_t guestId;
+ t_Handle h_RsrvFqidMm;
+ t_Handle h_FqidMm;
+ t_Handle h_Session;
+ char moduleName[MODULE_NAME_SIZE];
+ t_Handle h_Portals[DPAA_MAX_NUM_OF_SW_PORTALS];
+ t_QmRegs *p_QmRegs;
+ uint32_t *p_FqdBase;
+ uint32_t *p_PfdrBase;
+ uint32_t exceptions;
+ t_QmExceptionsCallback *f_Exception;
+ t_Handle h_App;
+ int errIrq; /**< error interrupt line; NO_IRQ if interrupts not used */
+ uint32_t numOfPfdr;
+ uint16_t partNumOfCgs;
+ uint16_t partCgsBase;
+ uint8_t cgsUsed[QM_MAX_NUM_OF_CGS];
+t_Handle lock;
+ t_QmDriverParams *p_QmDriverParams;
+} t_Qm;
+
+typedef struct {
+ uint32_t hwExtStructsMemAttr;
+ uint8_t dqrrSize;
+ bool pullMode;
+ bool dequeueDcaMode;
+ bool dequeueUpToThreeFrames;
+ e_QmPortalDequeueCommandType commandType;
+ uint8_t userToken;
+ bool specifiedWq;
+ bool dedicatedChannel;
+ bool dedicatedChannelHasPrecedenceOverPoolChannels;
+ uint8_t poolChannels[QM_MAX_NUM_OF_POOL_CHANNELS];
+ uint8_t poolChannelId;
+ uint8_t wqId;
+ uint16_t fdLiodnOffset;
+ uint8_t stashDestQueue;
+ uint8_t eqcr;
+ bool eqcrHighPri;
+ bool dqrr;
+ uint16_t dqrrLiodn;
+ bool dqrrHighPri;
+ bool fdFq;
+ uint16_t fdFqLiodn;
+ bool fdFqHighPri;
+ bool fdFqDrop;
+} t_QmPortalDriverParams;
+
+/*typedef struct t_QmPortalCgs{
+ uint32_t cgsMask[QM_MAX_NUM_OF_CGS/32];
+}t_QmPortalCgs;
+*/
+typedef struct t_QmPortal {
+ t_Handle h_Qm;
+ struct qm_portal *p_LowQmPortal;
+ uint32_t bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
+ t_Handle h_App;
+ t_QmLoopDequeueRing *f_LoopDequeueRingCB;
+ bool pullMode;
+ /* To avoid overloading the term "flags", we use these 2; */
+ uint32_t options; /* QMAN_PORTAL_FLAG_*** - static, caller-provided */
+ uint32_t irq_flags;
+ /* The wrap-around eq_[prod|cons] counters are used to support
+ * QMAN_ENQUEUE_FLAG_WAIT_SYNC. */
+ uint32_t eqProd;
+ volatile int disable_count;
+ struct qman_cgrs cgrs[2]; /* 2-element array. cgrs[0] is mask, cgrs[1] is previous snapshot. */
+ /* If we receive a DQRR or MR ring entry for a "null" FQ, ie. for which
+ * FQD::contextB is NULL rather than pointing to a FQ object, we use
+ * these handlers. (This is not considered a fast-path mechanism.) */
+ t_Handle cgsHandles[QM_MAX_NUM_OF_CGS];
+ struct qman_fq_cb *p_NullCB;
+ t_QmReceivedFrameCallback *f_DfltFrame;
+ t_QmRejectedFrameCallback *f_RejectedFrame;
+ t_QmPortalDriverParams *p_QmPortalDriverParams;
+} t_QmPortal;
+
+struct qman_fq {
+ struct qman_fq_cb cb;
+ t_Handle h_App;
+ t_Handle h_QmFqr;
+ t_Handle fqlock;
+ uint32_t fqid;
+ uint32_t fqidOffset;
+ uint32_t flags;
+ /* s/w-visible states. Ie. tentatively scheduled + truly scheduled +
+ * active + held-active + held-suspended are just "sched". Things like
+ * 'retired' will not be assumed until it is complete (ie.
+ * QMAN_FQ_STATE_CHANGING is set until then, to indicate it's completing
+ * and to gate attempts to retry the retire command). Note, park
+ * commands do not set QMAN_FQ_STATE_CHANGING because it's technically
+ * impossible in the case of enqueue DCAs (which refer to DQRR ring
+ * index rather than the FQ that ring entry corresponds to), so repeated
+ * park commands are allowed (if you're silly enough to try) but won't
+ * change FQ state, and the resulting park notifications move FQs from
+ * 'sched' to 'parked'. */
+ enum qman_fq_state state;
+ int cgr_groupid;
+};
+
+typedef struct {
+ t_Handle h_Qm;
+ t_Handle h_QmPortal;
+ e_QmFQChannel channel;
+ uint8_t workQueue;
+ bool shadowMode;
+ uint32_t fqidBase;
+ uint32_t numOfFqids;
+ t_QmFqrDrainedCompletionCB *f_CompletionCB;
+ t_Handle h_App;
+ uint32_t numOfDrainedFqids;
+ bool *p_DrainedFqs;
+ struct qman_fq **p_Fqs;
+} t_QmFqr;
+
+
+/****************************************/
+/* Inter-Module functions */
+/****************************************/
+uint32_t QmGetCounter(t_Handle h_Qm, e_QmInterModuleCounters counter);
+t_Error QmGetRevision(t_Handle h_Qm, t_QmRevisionInfo *p_QmRevisionInfo);
+t_Error QmGetSetPortalParams(t_Handle h_Qm, t_QmInterModulePortalInitParams *p_PortalParams);
+t_Error QmFreeDcPortal(t_Handle h_Qm, e_DpaaDcPortal dcPortalId);
+uint32_t QmFqidGet(t_Qm *p_Qm, uint32_t size, uint32_t alignment, bool force, uint32_t base);
+t_Error QmFqidPut(t_Qm *p_Qm, uint32_t base);
+t_Error QmGetCgId(t_Handle h_Qm, uint8_t *p_CgId);
+t_Error QmFreeCgId(t_Handle h_Qm, uint8_t cgId);
+
+
+static __inline__ void QmSetPortalHandle(t_Handle h_Qm, t_Handle h_Portal, e_DpaaSwPortal portalId)
+{
+ ASSERT_COND(!((t_Qm*)h_Qm)->h_Portals[portalId] || !h_Portal);
+ ((t_Qm*)h_Qm)->h_Portals[portalId] = h_Portal;
+}
+
+static __inline__ t_Handle QmGetPortalHandle(t_Handle h_Qm)
+{
+ t_Qm *p_Qm = (t_Qm*)h_Qm;
+
+ ASSERT_COND(p_Qm);
+ return p_Qm->h_Portals[CORE_GetId()];
+}
+
+static __inline__ uint32_t GenerateCgrThresh(uint64_t val, int roundup)
+{
+ uint32_t e = 0; /* co-efficient, exponent */
+ uint32_t oddbit = 0;
+ while(val > 0xff) {
+ oddbit = (uint32_t)val & 1;
+ val >>= 1;
+ e++;
+ if(roundup && oddbit)
+ val++;
+ }
+ return (uint32_t)((val << 5) | e);
+}
+
+static __inline__ t_Error SetException(t_Qm *p_Qm, e_QmExceptions exception, bool enable)
+{
+ uint32_t bitMask = 0;
+
+ ASSERT_COND(p_Qm);
+
+ GET_EXCEPTION_FLAG(bitMask, exception);
+ if(bitMask)
+ {
+ if (enable)
+ p_Qm->exceptions |= bitMask;
+ else
+ p_Qm->exceptions &= ~bitMask;
+ }
+ else
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
+
+ return E_OK;
+}
+
+
+#endif /* __QM_H */
diff --git a/sys/contrib/ncsw/Peripherals/QM/qm_ipc.h b/sys/contrib/ncsw/Peripherals/QM/qm_ipc.h
new file mode 100644
index 0000000..763d034
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/QM/qm_ipc.h
@@ -0,0 +1,125 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/**************************************************************************//**
+ @File QM_ipc.h
+
+ @Description QM Inter-Partition prototypes, structures and definitions.
+*//***************************************************************************/
+#ifndef __QM_IPC_H
+#define __QM_IPC_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group QM_grp Frame Manager API
+
+ @Description QM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group QM_IPC_grp Qm Inter-Partition messaging Unit
+
+ @Description QM Inter-Partition messaging unit API definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+#define QM_FORCE_FQID 1
+#define QM_PUT_FQID 2
+#define QM_GET_COUNTER 3
+#define QM_GET_SET_PORTAL_PARAMS 4
+#define QM_GET_REVISION 5
+#define QM_MASTER_IS_ALIVE 6
+
+#define QM_IPC_MAX_REPLY_BODY_SIZE 16
+#define QM_IPC_MAX_REPLY_SIZE (QM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
+#define QM_IPC_MAX_MSG_SIZE 30
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+typedef _Packed struct t_QmIpcMsg
+{
+ uint32_t msgId;
+ uint8_t msgBody[QM_IPC_MAX_MSG_SIZE];
+} _PackedType t_QmIpcMsg;
+
+typedef _Packed struct t_QmIpcReply
+{
+ uint32_t error;
+ uint8_t replyBody[QM_IPC_MAX_REPLY_BODY_SIZE];
+} _PackedType t_QmIpcReply;
+
+typedef _Packed struct t_QmIpcGetCounter
+{
+ uint32_t enumId; /**< IN */
+} _PackedType t_QmIpcGetCounter;
+
+typedef _Packed struct t_QmIpcFqidParams
+{
+ uint32_t fqid; /**< IN */
+ uint32_t size; /**< IN */
+} _PackedType t_QmIpcFqidParams;
+
+typedef _Packed struct t_QmIpcPortalInitParams {
+ uint8_t portalId; /**< IN */
+ uint8_t stashDestQueue; /**< IN */
+ uint16_t liodn; /**< IN */
+ uint16_t dqrrLiodn; /**< IN */
+ uint16_t fdFqLiodn; /**< IN */
+} _PackedType t_QmIpcPortalInitParams;
+
+typedef _Packed struct t_QmIpcRevisionInfo {
+ uint8_t majorRev; /**< OUT: Major revision */
+ uint8_t minorRev; /**< OUT: Minor revision */
+} _PackedType t_QmIpcRevisionInfo;
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+/** @} */ /* end of QM_IPC_grp group */
+/** @} */ /* end of QM_grp group */
+
+
+#endif /* __QM_IPC_H */
diff --git a/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c b/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c
new file mode 100644
index 0000000..0211394
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/QM/qm_portal_fqr.c
@@ -0,0 +1,2701 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File qm.c
+
+ @Description QM & Portal implementation
+*//***************************************************************************/
+#include "error_ext.h"
+#include "std_ext.h"
+#include "string_ext.h"
+#include "mm_ext.h"
+#include "qm.h"
+#include "qman_low.h"
+
+
+/****************************************/
+/* static functions */
+/****************************************/
+
+#define SLOW_POLL_IDLE 1000
+#define SLOW_POLL_BUSY 10
+
+
+static t_Error qman_volatile_dequeue(t_QmPortal *p_QmPortal,
+ struct qman_fq *p_Fq,
+ uint32_t vdqcr)
+{
+ ASSERT_COND((p_Fq->state == qman_fq_state_parked) ||
+ (p_Fq->state == qman_fq_state_retired));
+ ASSERT_COND(!(vdqcr & QM_VDQCR_FQID_MASK));
+ ASSERT_COND(!(p_Fq->flags & QMAN_FQ_STATE_VDQCR));
+
+ vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | p_Fq->fqid;
+ NCSW_PLOCK(p_QmPortal);
+ FQLOCK(p_Fq);
+ p_Fq->flags |= QMAN_FQ_STATE_VDQCR;
+ qm_dqrr_vdqcr_set(p_QmPortal->p_LowQmPortal, vdqcr);
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
+static const char *mcr_result_str(uint8_t result)
+{
+ switch (result) {
+ case QM_MCR_RESULT_NULL:
+ return "QM_MCR_RESULT_NULL";
+ case QM_MCR_RESULT_OK:
+ return "QM_MCR_RESULT_OK";
+ case QM_MCR_RESULT_ERR_FQID:
+ return "QM_MCR_RESULT_ERR_FQID";
+ case QM_MCR_RESULT_ERR_FQSTATE:
+ return "QM_MCR_RESULT_ERR_FQSTATE";
+ case QM_MCR_RESULT_ERR_NOTEMPTY:
+ return "QM_MCR_RESULT_ERR_NOTEMPTY";
+ case QM_MCR_RESULT_PENDING:
+ return "QM_MCR_RESULT_PENDING";
+ }
+ return "<unknown MCR result>";
+}
+
+static t_Error qman_create_fq(t_QmPortal *p_QmPortal,
+ uint32_t fqid,
+ uint32_t flags,
+ struct qman_fq *p_Fq)
+{
+ struct qm_fqd fqd;
+ struct qm_mcr_queryfq_np np;
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+
+ p_Fq->fqid = fqid;
+ p_Fq->flags = flags;
+ p_Fq->state = qman_fq_state_oos;
+ p_Fq->cgr_groupid = 0;
+ if (!(flags & QMAN_FQ_FLAG_RECOVER) ||
+ (flags & QMAN_FQ_FLAG_NO_MODIFY))
+ return E_OK;
+ /* Everything else is RECOVER support */
+ NCSW_PLOCK(p_QmPortal);
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->queryfq.fqid = fqid;
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYFQ);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
+ if (p_Mcr->result != QM_MCR_RESULT_OK) {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("QUERYFQ failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+ fqd = p_Mcr->queryfq.fqd;
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->queryfq_np.fqid = fqid;
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYFQ_NP);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
+ if (p_Mcr->result != QM_MCR_RESULT_OK) {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("UERYFQ_NP failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+ np = p_Mcr->queryfq_np;
+ /* Phew, have queryfq and queryfq_np results, stitch together
+ * the FQ object from those. */
+ p_Fq->cgr_groupid = fqd.cgid;
+ switch (np.state & QM_MCR_NP_STATE_MASK) {
+ case QM_MCR_NP_STATE_OOS:
+ break;
+ case QM_MCR_NP_STATE_RETIRED:
+ p_Fq->state = qman_fq_state_retired;
+ if (np.frm_cnt)
+ p_Fq->flags |= QMAN_FQ_STATE_NE;
+ break;
+ case QM_MCR_NP_STATE_TEN_SCHED:
+ case QM_MCR_NP_STATE_TRU_SCHED:
+ case QM_MCR_NP_STATE_ACTIVE:
+ p_Fq->state = qman_fq_state_sched;
+ if (np.state & QM_MCR_NP_STATE_R)
+ p_Fq->flags |= QMAN_FQ_STATE_CHANGING;
+ break;
+ case QM_MCR_NP_STATE_PARKED:
+ p_Fq->state = qman_fq_state_parked;
+ break;
+ default:
+ ASSERT_COND(FALSE);
+ }
+ if (fqd.fq_ctrl & QM_FQCTRL_CGE)
+ p_Fq->state |= QMAN_FQ_STATE_CGR_EN;
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
+static void qman_destroy_fq(struct qman_fq *p_Fq, uint32_t flags)
+{
+ /* We don't need to lock the FQ as it is a pre-condition that the FQ be
+ * quiesced. Instead, run some checks. */
+ UNUSED(flags);
+ switch (p_Fq->state) {
+ case qman_fq_state_parked:
+ ASSERT_COND(flags & QMAN_FQ_DESTROY_PARKED);
+ case qman_fq_state_oos:
+ return;
+ default:
+ break;
+ }
+ ASSERT_COND(FALSE);
+}
+
+static t_Error qman_init_fq(t_QmPortal *p_QmPortal,
+ struct qman_fq *p_Fq,
+ uint32_t flags,
+ struct qm_mcc_initfq *p_Opts)
+{
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ uint8_t res, myverb = (uint8_t)((flags & QMAN_INITFQ_FLAG_SCHED) ?
+ QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED);
+
+ SANITY_CHECK_RETURN_ERROR((p_Fq->state == qman_fq_state_oos) ||
+ (p_Fq->state == qman_fq_state_parked),
+ E_INVALID_STATE);
+
+ if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
+ return ERROR_CODE(E_INVALID_VALUE);
+ /* Issue an INITFQ_[PARKED|SCHED] management command */
+ NCSW_PLOCK(p_QmPortal);
+ FQLOCK(p_Fq);
+ if ((p_Fq->flags & QMAN_FQ_STATE_CHANGING) ||
+ ((p_Fq->state != qman_fq_state_oos) &&
+ (p_Fq->state != qman_fq_state_parked))) {
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ return ERROR_CODE(E_BUSY);
+ }
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ Mem2IOCpy32((void*)&p_Mcc->initfq, p_Opts, sizeof(struct qm_mcc_initfq));
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, myverb);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == myverb);
+ res = p_Mcr->result;
+ if (res != QM_MCR_RESULT_OK) {
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE,("INITFQ failed: %s", mcr_result_str(res)));
+ }
+
+ if (p_Mcc->initfq.we_mask & QM_INITFQ_WE_FQCTRL) {
+ if (p_Mcc->initfq.fqd.fq_ctrl & QM_FQCTRL_CGE)
+ p_Fq->flags |= QMAN_FQ_STATE_CGR_EN;
+ else
+ p_Fq->flags &= ~QMAN_FQ_STATE_CGR_EN;
+ }
+ if (p_Mcc->initfq.we_mask & QM_INITFQ_WE_CGID)
+ p_Fq->cgr_groupid = p_Mcc->initfq.fqd.cgid;
+ p_Fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
+ qman_fq_state_sched : qman_fq_state_parked;
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ return E_OK;
+}
+
+static t_Error qman_retire_fq(t_QmPortal *p_QmPortal,
+ struct qman_fq *p_Fq,
+ uint32_t *p_Flags,
+ bool drain)
+{
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ t_Error err = E_OK;
+ uint8_t res;
+
+ SANITY_CHECK_RETURN_ERROR((p_Fq->state == qman_fq_state_parked) ||
+ (p_Fq->state == qman_fq_state_sched),
+ E_INVALID_STATE);
+
+ if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
+ return E_INVALID_VALUE;
+ NCSW_PLOCK(p_QmPortal);
+ FQLOCK(p_Fq);
+ if ((p_Fq->flags & QMAN_FQ_STATE_CHANGING) ||
+ (p_Fq->state == qman_fq_state_retired) ||
+ (p_Fq->state == qman_fq_state_oos)) {
+ err = E_BUSY;
+ goto out;
+ }
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->alterfq.fqid = p_Fq->fqid;
+ if (drain)
+ p_Mcc->alterfq.context_b = (uint32_t)PTR_TO_UINT(p_Fq);
+ qm_mc_commit(p_QmPortal->p_LowQmPortal,
+ (uint8_t)((drain)?QM_MCC_VERB_ALTER_RETIRE_CTXB:QM_MCC_VERB_ALTER_RETIRE));
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) ==
+ (drain)?QM_MCR_VERB_ALTER_RETIRE_CTXB:QM_MCR_VERB_ALTER_RETIRE);
+ res = p_Mcr->result;
+ if (res == QM_MCR_RESULT_OK)
+ {
+ /* Process 'fq' right away, we'll ignore FQRNI */
+ if (p_Mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
+ p_Fq->flags |= QMAN_FQ_STATE_NE;
+ if (p_Mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
+ p_Fq->flags |= QMAN_FQ_STATE_ORL;
+ p_Fq->state = qman_fq_state_retired;
+ }
+ else if (res == QM_MCR_RESULT_PENDING)
+ p_Fq->flags |= QMAN_FQ_STATE_CHANGING;
+ else {
+ XX_Print("ALTER_RETIRE failed: %s\n",
+ mcr_result_str(res));
+ err = E_INVALID_STATE;
+ }
+ if (p_Flags)
+ *p_Flags = p_Fq->flags;
+out:
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ return err;
+}
+
+static t_Error qman_oos_fq(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq)
+{
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ uint8_t res;
+
+ ASSERT_COND(p_Fq->state == qman_fq_state_retired);
+ if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
+ return ERROR_CODE(E_INVALID_VALUE);
+ NCSW_PLOCK(p_QmPortal);
+ FQLOCK(p_Fq);
+ if ((p_Fq->flags & QMAN_FQ_STATE_BLOCKOOS) ||
+ (p_Fq->state != qman_fq_state_retired)) {
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ return ERROR_CODE(E_BUSY);
+ }
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->alterfq.fqid = p_Fq->fqid;
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_ALTER_OOS);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
+ res = p_Mcr->result;
+ if (res != QM_MCR_RESULT_OK) {
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("ALTER_OOS failed: %s\n", mcr_result_str(res)));
+ }
+ p_Fq->state = qman_fq_state_oos;
+
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ return E_OK;
+}
+
+static t_Error qman_schedule_fq(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq)
+{
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ uint8_t res;
+
+ ASSERT_COND(p_Fq->state == qman_fq_state_parked);
+ if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
+ return ERROR_CODE(E_INVALID_VALUE);
+ /* Issue a ALTERFQ_SCHED management command */
+ NCSW_PLOCK(p_QmPortal);
+ FQLOCK(p_Fq);
+ if ((p_Fq->flags & QMAN_FQ_STATE_CHANGING) ||
+ (p_Fq->state != qman_fq_state_parked)) {
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ return ERROR_CODE(E_BUSY);
+ }
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->alterfq.fqid = p_Fq->fqid;
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_ALTER_SCHED);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
+ res = p_Mcr->result;
+ if (res != QM_MCR_RESULT_OK) {
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("ALTER_SCHED failed: %s\n", mcr_result_str(res)));
+ }
+ p_Fq->state = qman_fq_state_sched;
+
+ FQUNLOCK(p_Fq);
+ PUNLOCK(p_QmPortal);
+ return E_OK;
+}
+
+/* Inline helper to reduce nesting in LoopMessageRing() */
+static __inline__ void fq_state_change(struct qman_fq *p_Fq,
+ struct qm_mr_entry *p_Msg,
+ uint8_t verb)
+{
+ FQLOCK(p_Fq);
+ switch(verb) {
+ case QM_MR_VERB_FQRL:
+ ASSERT_COND(p_Fq->flags & QMAN_FQ_STATE_ORL);
+ p_Fq->flags &= ~QMAN_FQ_STATE_ORL;
+ break;
+ case QM_MR_VERB_FQRN:
+ ASSERT_COND((p_Fq->state == qman_fq_state_parked) ||
+ (p_Fq->state == qman_fq_state_sched));
+ ASSERT_COND(p_Fq->flags & QMAN_FQ_STATE_CHANGING);
+ p_Fq->flags &= ~QMAN_FQ_STATE_CHANGING;
+ if (p_Msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
+ p_Fq->flags |= QMAN_FQ_STATE_NE;
+ if (p_Msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
+ p_Fq->flags |= QMAN_FQ_STATE_ORL;
+ p_Fq->state = qman_fq_state_retired;
+ break;
+ case QM_MR_VERB_FQPN:
+ ASSERT_COND(p_Fq->state == qman_fq_state_sched);
+ ASSERT_COND(p_Fq->flags & QMAN_FQ_STATE_CHANGING);
+ p_Fq->state = qman_fq_state_parked;
+ }
+ FQUNLOCK(p_Fq);
+}
+
+static t_Error freeDrainedFq(struct qman_fq *p_Fq)
+{
+ t_QmFqr *p_QmFqr;
+ uint32_t i;
+
+ ASSERT_COND(p_Fq);
+ p_QmFqr = (t_QmFqr *)p_Fq->h_QmFqr;
+ ASSERT_COND(p_QmFqr);
+
+ ASSERT_COND(!p_QmFqr->p_DrainedFqs[p_Fq->fqidOffset]);
+ p_QmFqr->p_DrainedFqs[p_Fq->fqidOffset] = TRUE;
+ p_QmFqr->numOfDrainedFqids++;
+ if (p_QmFqr->numOfDrainedFqids == p_QmFqr->numOfFqids)
+ {
+ for (i=0;i<p_QmFqr->numOfFqids;i++)
+ {
+ if ((p_QmFqr->p_Fqs[i]->state == qman_fq_state_retired) &&
+ (qman_oos_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i]) != E_OK))
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_oos_fq() failed!"));
+ qman_destroy_fq(p_QmFqr->p_Fqs[i], 0);
+ XX_FreeSmart(p_QmFqr->p_Fqs[i]);
+ }
+ XX_Free(p_QmFqr->p_DrainedFqs);
+ p_QmFqr->p_DrainedFqs = NULL;
+
+ if (p_QmFqr->f_CompletionCB)
+ {
+ p_QmFqr->f_CompletionCB(p_QmFqr->h_App, p_QmFqr);
+ XX_Free(p_QmFqr->p_Fqs);
+ if (p_QmFqr->fqidBase)
+ QmFqidPut(p_QmFqr->h_Qm, p_QmFqr->fqidBase);
+ XX_Free(p_QmFqr);
+ }
+ }
+
+ return E_OK;
+}
+
+static t_Error drainRetiredFq(struct qman_fq *p_Fq)
+{
+ t_QmFqr *p_QmFqr;
+
+ ASSERT_COND(p_Fq);
+ p_QmFqr = (t_QmFqr *)p_Fq->h_QmFqr;
+ ASSERT_COND(p_QmFqr);
+
+ if (p_Fq->flags & QMAN_FQ_STATE_NE)
+ {
+ if (qman_volatile_dequeue(p_QmFqr->h_QmPortal, p_Fq,
+ (QM_VDQCR_PRECEDENCE_VDQCR | QM_VDQCR_NUMFRAMES_TILLEMPTY)) != E_OK)
+
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("drain with volatile failed"));
+ return E_OK;
+ }
+ else
+ return freeDrainedFq(p_Fq);
+}
+
+static e_RxStoreResponse drainCB(t_Handle h_App,
+ t_Handle h_QmFqr,
+ t_Handle h_QmPortal,
+ uint32_t fqidOffset,
+ t_DpaaFD *p_Frame)
+{
+ UNUSED(h_App);
+ UNUSED(h_QmFqr);
+ UNUSED(h_QmPortal);
+ UNUSED(fqidOffset);
+ UNUSED(p_Frame);
+
+ DBG(TRACE,("got fd for fqid %d", ((t_QmFqr *)h_QmFqr)->fqidBase + fqidOffset));
+ return e_RX_STORE_RESPONSE_CONTINUE;
+}
+
+static void cb_ern_dcErn(t_Handle h_App,
+ t_Handle h_QmPortal,
+ struct qman_fq *p_Fq,
+ const struct qm_mr_entry *p_Msg)
+{
+ static int cnt = 0;
+ UNUSED(p_Fq);
+ UNUSED(p_Msg);
+ UNUSED(h_App);
+ UNUSED(h_QmPortal);
+
+ XX_Print("cb_ern_dcErn_fqs() unimplemented %d\n", ++cnt);
+}
+
+static void cb_fqs(t_Handle h_App,
+ t_Handle h_QmPortal,
+ struct qman_fq *p_Fq,
+ const struct qm_mr_entry *p_Msg)
+{
+ UNUSED(p_Msg);
+ UNUSED(h_App);
+ UNUSED(h_QmPortal);
+
+ if (p_Fq->state == qman_fq_state_retired &&
+ !(p_Fq->flags & QMAN_FQ_STATE_ORL))
+ drainRetiredFq(p_Fq);
+}
+
+static void null_cb_mr(t_Handle h_App,
+ t_Handle h_QmPortal,
+ struct qman_fq *p_Fq,
+ const struct qm_mr_entry *p_Msg)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ UNUSED(p_Fq);UNUSED(h_App);
+
+ if ((p_Msg->verb & QM_MR_VERB_DC_ERN) == QM_MR_VERB_DC_ERN)
+ XX_Print("Ignoring unowned MR frame on cpu %d, dc-portal 0x%02x.\n",
+ p_QmPortal->p_LowQmPortal->config.cpu,p_Msg->dcern.portal);
+ else
+ XX_Print("Ignoring unowned MR frame on cpu %d, verb 0x%02x.\n",
+ p_QmPortal->p_LowQmPortal->config.cpu,p_Msg->verb);
+}
+
+static uint32_t LoopMessageRing(t_QmPortal *p_QmPortal, uint32_t is)
+{
+ struct qm_mr_entry *p_Msg;
+
+ if (is & QM_PIRQ_CSCI) {
+ struct qm_mc_result *p_Mcr;
+ struct qman_cgrs tmp;
+ uint32_t mask;
+ unsigned int i, j;
+
+ NCSW_PLOCK(p_QmPortal);
+ qm_mc_start(p_QmPortal->p_LowQmPortal);
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYCONGESTION);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+
+ /* cgrs[0] is the portal mask for its cg's, cgrs[1] is the
+ previous state of cg's */
+ for (i = 0; i < QM_MAX_NUM_OF_CGS/32; i++)
+ {
+ /* get curent state */
+ tmp.q.__state[i] = p_Mcr->querycongestion.state.__state[i];
+ /* keep only cg's that are registered for this portal */
+ tmp.q.__state[i] &= p_QmPortal->cgrs[0].q.__state[i];
+ /* handle only cg's that changed their state from previous exception */
+ tmp.q.__state[i] ^= p_QmPortal->cgrs[1].q.__state[i];
+ /* update previous */
+ p_QmPortal->cgrs[1].q.__state[i] = p_Mcr->querycongestion.state.__state[i];
+ }
+ PUNLOCK(p_QmPortal);
+
+ /* if in interrupt */
+ /* call the callback routines for any CG with a changed state */
+ for (i = 0; i < QM_MAX_NUM_OF_CGS/32; i++)
+ for(j=0, mask = 0x80000000; j<32 ; j++, mask>>=1)
+ {
+ if(tmp.q.__state[i] & mask)
+ {
+ t_QmCg *p_QmCg = (t_QmCg *)(p_QmPortal->cgsHandles[i*32 + j]);
+ if(p_QmCg->f_Exception)
+ p_QmCg->f_Exception(p_QmCg->h_App, e_QM_EX_CG_STATE_CHANGE);
+ }
+ }
+
+ }
+
+
+ if (is & QM_PIRQ_EQRI) {
+ NCSW_PLOCK(p_QmPortal);
+ qmPortalEqcrCceUpdate(p_QmPortal->p_LowQmPortal);
+ qm_eqcr_set_ithresh(p_QmPortal->p_LowQmPortal, 0);
+ PUNLOCK(p_QmPortal);
+ }
+
+ if (is & QM_PIRQ_MRI) {
+mr_loop:
+ qmPortalMrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ p_Msg = qm_mr_current(p_QmPortal->p_LowQmPortal);
+ if (p_Msg) {
+ struct qman_fq *p_FqFqs = (void *)p_Msg->fq.contextB;
+ struct qman_fq *p_FqErn = (void *)p_Msg->ern.tag;
+ uint8_t verb =(uint8_t)(p_Msg->verb & QM_MR_VERB_TYPE_MASK);
+ t_QmRejectedFrameInfo rejectedFrameInfo;
+
+ memset(&rejectedFrameInfo, 0, sizeof(t_QmRejectedFrameInfo));
+ if (!(verb & QM_MR_VERB_DC_ERN))
+ {
+ switch(p_Msg->ern.rc)
+ {
+ case(QM_MR_RC_CGR_TAILDROP):
+ rejectedFrameInfo.rejectionCode = e_QM_RC_CG_TAILDROP;
+ rejectedFrameInfo.cg.cgId = (uint8_t)p_FqErn->cgr_groupid;
+ break;
+ case(QM_MR_RC_WRED):
+ rejectedFrameInfo.rejectionCode = e_QM_RC_CG_WRED;
+ rejectedFrameInfo.cg.cgId = (uint8_t)p_FqErn->cgr_groupid;
+ break;
+ case(QM_MR_RC_FQ_TAILDROP):
+ rejectedFrameInfo.rejectionCode = e_QM_RC_FQ_TAILDROP;
+ rejectedFrameInfo.cg.cgId = (uint8_t)p_FqErn->cgr_groupid;
+ break;
+ case(QM_MR_RC_ERROR):
+ break;
+ default:
+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("Unknown rejection code"));
+ }
+ if (!p_FqErn)
+ p_QmPortal->p_NullCB->ern(p_QmPortal->h_App, NULL, p_QmPortal, 0, (t_DpaaFD*)&p_Msg->ern.fd, &rejectedFrameInfo);
+ else
+ p_FqErn->cb.ern(p_FqErn->h_App, p_FqErn->h_QmFqr, p_QmPortal, p_FqErn->fqidOffset, (t_DpaaFD*)&p_Msg->ern.fd, &rejectedFrameInfo);
+ } else if (verb == QM_MR_VERB_DC_ERN)
+ {
+ if (!p_FqErn)
+ p_QmPortal->p_NullCB->dc_ern(NULL, p_QmPortal, NULL, p_Msg);
+ else
+ p_FqErn->cb.dc_ern(p_FqErn->h_App, p_QmPortal, p_FqErn, p_Msg);
+ } else
+ {
+ if (verb == QM_MR_VERB_FQRNI)
+ ; /* we drop FQRNIs on the floor */
+ else if (!p_FqFqs)
+ p_QmPortal->p_NullCB->fqs(NULL, p_QmPortal, NULL, p_Msg);
+ else if ((verb == QM_MR_VERB_FQRN) ||
+ (verb == QM_MR_VERB_FQRL) ||
+ (verb == QM_MR_VERB_FQPN))
+ {
+ fq_state_change(p_FqFqs, p_Msg, verb);
+ p_FqFqs->cb.fqs(p_FqFqs->h_App, p_QmPortal, p_FqFqs, p_Msg);
+ }
+ }
+ qm_mr_next(p_QmPortal->p_LowQmPortal);
+ qmPortalMrCciConsume(p_QmPortal->p_LowQmPortal, 1);
+
+ goto mr_loop;
+ }
+ }
+
+ return is & (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
+}
+
+static void LoopDequeueRing(t_Handle h_QmPortal)
+{
+ struct qm_dqrr_entry *p_Dq;
+ struct qman_fq *p_Fq;
+ enum qman_cb_dqrr_result res = qman_cb_dqrr_consume;
+ e_RxStoreResponse tmpRes;
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+ int prefetch = !(p_QmPortal->options & QMAN_PORTAL_FLAG_RSTASH);
+
+ while (res != qman_cb_dqrr_pause)
+ {
+ if (prefetch)
+ qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
+ if (!p_Dq)
+ break;
+ p_Fq = (void *)p_Dq->contextB;
+ if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
+ /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
+ * to check for clearing it when doing volatile dequeues. It's
+ * one less thing to check in the critical path (SDQCR). */
+ tmpRes = p_Fq->cb.dqrr(p_Fq->h_App, p_Fq->h_QmFqr, p_QmPortal, p_Fq->fqidOffset, (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ /* Check for VDQCR completion */
+ if (p_Dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
+ p_Fq->flags &= ~QMAN_FQ_STATE_VDQCR;
+ if (p_Dq->stat & QM_DQRR_STAT_FQ_EMPTY)
+ {
+ p_Fq->flags &= ~QMAN_FQ_STATE_NE;
+ freeDrainedFq(p_Fq);
+ }
+ }
+ else
+ {
+ /* Interpret 'dq' from the owner's perspective. */
+ /* use portal default handlers */
+ ASSERT_COND(p_Dq->fqid);
+ if (p_Fq)
+ {
+ tmpRes = p_Fq->cb.dqrr(p_Fq->h_App,
+ p_Fq->h_QmFqr,
+ p_QmPortal,
+ p_Fq->fqidOffset,
+ (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ else if (p_Fq->state == qman_fq_state_waiting_parked)
+ res = qman_cb_dqrr_park;
+ }
+ else
+ {
+ tmpRes = p_QmPortal->p_NullCB->dqrr(p_QmPortal->h_App,
+ NULL,
+ p_QmPortal,
+ p_Dq->fqid,
+ (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ }
+ }
+
+ /* Parking isn't possible unless HELDACTIVE was set. NB,
+ * FORCEELIGIBLE implies HELDACTIVE, so we only need to
+ * check for HELDACTIVE to cover both. */
+ ASSERT_COND((p_Dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
+ (res != qman_cb_dqrr_park));
+ if (p_QmPortal->options & QMAN_PORTAL_FLAG_DCA) {
+ /* Defer just means "skip it, I'll consume it myself later on" */
+ if (res != qman_cb_dqrr_defer)
+ qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
+ p_Dq,
+ (res == qman_cb_dqrr_park));
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ } else {
+ if (res == qman_cb_dqrr_park)
+ /* The only thing to do for non-DCA is the park-request */
+ qm_dqrr_park_ci(p_QmPortal->p_LowQmPortal);
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
+ }
+ }
+}
+
+static void LoopDequeueRingDcaOptimized(t_Handle h_QmPortal)
+{
+ struct qm_dqrr_entry *p_Dq;
+ struct qman_fq *p_Fq;
+ enum qman_cb_dqrr_result res = qman_cb_dqrr_consume;
+ e_RxStoreResponse tmpRes;
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ while (res != qman_cb_dqrr_pause)
+ {
+ qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
+ if (!p_Dq)
+ break;
+ p_Fq = (void *)p_Dq->contextB;
+ if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
+ /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
+ * to check for clearing it when doing volatile dequeues. It's
+ * one less thing to check in the critical path (SDQCR). */
+ tmpRes = p_Fq->cb.dqrr(p_Fq->h_App, p_Fq->h_QmFqr, p_QmPortal, p_Fq->fqidOffset, (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ /* Check for VDQCR completion */
+ if (p_Dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
+ p_Fq->flags &= ~QMAN_FQ_STATE_VDQCR;
+ if (p_Dq->stat & QM_DQRR_STAT_FQ_EMPTY)
+ {
+ p_Fq->flags &= ~QMAN_FQ_STATE_NE;
+ freeDrainedFq(p_Fq);
+ }
+ }
+ else
+ {
+ /* Interpret 'dq' from the owner's perspective. */
+ /* use portal default handlers */
+ ASSERT_COND(p_Dq->fqid);
+ if (p_Fq)
+ {
+ tmpRes = p_Fq->cb.dqrr(p_Fq->h_App,
+ p_Fq->h_QmFqr,
+ p_QmPortal,
+ p_Fq->fqidOffset,
+ (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ else if (p_Fq->state == qman_fq_state_waiting_parked)
+ res = qman_cb_dqrr_park;
+ }
+ else
+ {
+ tmpRes = p_QmPortal->p_NullCB->dqrr(p_QmPortal->h_App,
+ NULL,
+ p_QmPortal,
+ p_Dq->fqid,
+ (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ }
+ }
+
+ /* Parking isn't possible unless HELDACTIVE was set. NB,
+ * FORCEELIGIBLE implies HELDACTIVE, so we only need to
+ * check for HELDACTIVE to cover both. */
+ ASSERT_COND((p_Dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
+ (res != qman_cb_dqrr_park));
+ /* Defer just means "skip it, I'll consume it myself later on" */
+ if (res != qman_cb_dqrr_defer)
+ qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
+ p_Dq,
+ (res == qman_cb_dqrr_park));
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ }
+}
+
+static void LoopDequeueRingOptimized(t_Handle h_QmPortal)
+{
+ struct qm_dqrr_entry *p_Dq;
+ struct qman_fq *p_Fq;
+ enum qman_cb_dqrr_result res = qman_cb_dqrr_consume;
+ e_RxStoreResponse tmpRes;
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ while (res != qman_cb_dqrr_pause)
+ {
+ qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
+ if (!p_Dq)
+ break;
+ p_Fq = (void *)p_Dq->contextB;
+ if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
+ /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
+ * to check for clearing it when doing volatile dequeues. It's
+ * one less thing to check in the critical path (SDQCR). */
+ tmpRes = p_Fq->cb.dqrr(p_Fq->h_App, p_Fq->h_QmFqr, p_QmPortal, p_Fq->fqidOffset, (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ /* Check for VDQCR completion */
+ if (p_Dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
+ p_Fq->flags &= ~QMAN_FQ_STATE_VDQCR;
+ if (p_Dq->stat & QM_DQRR_STAT_FQ_EMPTY)
+ {
+ p_Fq->flags &= ~QMAN_FQ_STATE_NE;
+ freeDrainedFq(p_Fq);
+ }
+ }
+ else
+ {
+ /* Interpret 'dq' from the owner's perspective. */
+ /* use portal default handlers */
+ ASSERT_COND(p_Dq->fqid);
+ if (p_Fq)
+ {
+ tmpRes = p_Fq->cb.dqrr(p_Fq->h_App,
+ p_Fq->h_QmFqr,
+ p_QmPortal,
+ p_Fq->fqidOffset,
+ (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ else if (p_Fq->state == qman_fq_state_waiting_parked)
+ res = qman_cb_dqrr_park;
+ }
+ else
+ {
+ tmpRes = p_QmPortal->p_NullCB->dqrr(p_QmPortal->h_App,
+ NULL,
+ p_QmPortal,
+ p_Dq->fqid,
+ (t_DpaaFD*)&p_Dq->fd);
+ if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
+ res = qman_cb_dqrr_pause;
+ }
+ }
+
+ /* Parking isn't possible unless HELDACTIVE was set. NB,
+ * FORCEELIGIBLE implies HELDACTIVE, so we only need to
+ * check for HELDACTIVE to cover both. */
+ ASSERT_COND((p_Dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
+ (res != qman_cb_dqrr_park));
+ if (res == qman_cb_dqrr_park)
+ /* The only thing to do for non-DCA is the park-request */
+ qm_dqrr_park_ci(p_QmPortal->p_LowQmPortal);
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
+ }
+}
+
+/* Portal interrupt handler */
+static void portal_isr(void *ptr)
+{
+ t_QmPortal *p_QmPortal = ptr;
+ uint32_t event = 0;
+ uint32_t enableEvents = qm_isr_enable_read(p_QmPortal->p_LowQmPortal);
+
+ DBG(TRACE, ("software-portal %d got interrupt", p_QmPortal->p_LowQmPortal->config.cpu));
+
+ event |= (qm_isr_status_read(p_QmPortal->p_LowQmPortal) &
+ enableEvents);
+
+ qm_isr_status_clear(p_QmPortal->p_LowQmPortal, event);
+ /* Only do fast-path handling if it's required */
+ if (/*(event & QM_PIRQ_DQRI) &&*/
+ (p_QmPortal->options & QMAN_PORTAL_FLAG_IRQ_FAST))
+ p_QmPortal->f_LoopDequeueRingCB(p_QmPortal);
+ if (p_QmPortal->options & QMAN_PORTAL_FLAG_IRQ_SLOW)
+ LoopMessageRing(p_QmPortal, event);
+}
+
+
+static t_Error qman_query_fq_np(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq, struct qm_mcr_queryfq_np *p_Np)
+{
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ uint8_t res;
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->queryfq_np.fqid = p_Fq->fqid;
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYFQ_NP);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
+ res = p_Mcr->result;
+ if (res == QM_MCR_RESULT_OK)
+ *p_Np = p_Mcr->queryfq_np;
+ PUNLOCK(p_QmPortal);
+ if (res != QM_MCR_RESULT_OK)
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("QUERYFQ_NP failed: %s\n", mcr_result_str(res)));
+ return E_OK;
+}
+
+static uint8_t QmCgGetCgId(t_Handle h_QmCg)
+{
+ t_QmCg *p_QmCg = (t_QmCg *)h_QmCg;
+
+ return p_QmCg->id;
+
+}
+
+static t_Error qm_new_fq(t_QmPortal *p_QmPortal,
+ uint32_t fqid,
+ uint32_t fqidOffset,
+ uint32_t channel,
+ uint32_t wqid,
+ uint16_t count,
+ uint32_t flags,
+ t_QmFqrCongestionAvoidanceParams *p_CgParams,
+ t_QmContextA *p_ContextA,
+ t_QmContextB *p_ContextB,
+ bool initParked,
+ t_Handle h_QmFqr,
+ struct qman_fq **p_Fqs)
+{
+ struct qman_fq *p_Fq = NULL;
+ struct qm_mcc_initfq fq_opts;
+ uint32_t i;
+ t_Error err = E_OK;
+ int gap, tmp;
+ uint32_t tmpA, tmpN, ta=0, tn=0, initFqFlag;
+
+ ASSERT_COND(p_QmPortal);
+ ASSERT_COND(count);
+
+ for(i=0;i<count;i++)
+ {
+ p_Fq = (struct qman_fq *)XX_MallocSmart(sizeof(struct qman_fq), 0, 64);
+ if (!p_Fq)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
+ memset(p_Fq, 0, sizeof(struct qman_fq));
+ p_Fq->cb.dqrr = p_QmPortal->f_DfltFrame;
+ p_Fq->cb.ern = p_QmPortal->f_RejectedFrame;
+ p_Fq->cb.dc_ern = cb_ern_dcErn;
+ p_Fq->cb.fqs = cb_fqs;
+ p_Fq->h_App = p_QmPortal->h_App;
+ p_Fq->h_QmFqr = h_QmFqr;
+ p_Fq->fqidOffset = fqidOffset;
+ p_Fqs[i] = p_Fq;
+ if ((err = qman_create_fq(p_QmPortal,(uint32_t)(fqid + i), 0, p_Fqs[i])) != E_OK)
+ break;
+ }
+
+ if (err != E_OK)
+ {
+ for(i=0;i<count;i++)
+ if (p_Fqs[i])
+ {
+ XX_FreeSmart(p_Fqs[i]);
+ p_Fqs[i] = NULL;
+ }
+ RETURN_ERROR(MINOR, err, ("Failed to create Fqs"));
+ }
+
+ memset(&fq_opts,0,sizeof(fq_opts));
+ fq_opts.fqid = fqid;
+ fq_opts.count = (uint16_t)(count-1);
+ fq_opts.we_mask |= QM_INITFQ_WE_DESTWQ;
+ fq_opts.fqd.dest.channel = channel;
+ fq_opts.fqd.dest.wq = wqid;
+ fq_opts.we_mask |= QM_INITFQ_WE_FQCTRL;
+ fq_opts.fqd.fq_ctrl = (uint16_t)flags;
+
+ if ((flags & QM_FQCTRL_CGE) || (flags & QM_FQCTRL_TDE))
+ ASSERT_COND(p_CgParams);
+
+ if(flags & QM_FQCTRL_CGE)
+ {
+ ASSERT_COND(p_CgParams->h_QmCg);
+
+ /* CG OAC and FQ TD may not be configured at the same time. if both are required,
+ than we configure CG first, and the FQ TD later - see below. */
+ fq_opts.fqd.cgid = QmCgGetCgId(p_CgParams->h_QmCg);
+ fq_opts.we_mask |= QM_INITFQ_WE_CGID;
+ if(p_CgParams->overheadAccountingLength)
+ {
+ fq_opts.we_mask |= QM_INITFQ_WE_OAC;
+ fq_opts.we_mask &= ~QM_INITFQ_WE_TDTHRESH;
+ fq_opts.fqd.td_thresh = (uint16_t)(QM_FQD_TD_THRESH_OAC_EN | p_CgParams->overheadAccountingLength);
+ }
+ }
+ if((flags & QM_FQCTRL_TDE) && (!p_CgParams->overheadAccountingLength))
+ {
+ ASSERT_COND(p_CgParams->fqTailDropThreshold);
+
+ fq_opts.we_mask |= QM_INITFQ_WE_TDTHRESH;
+
+ /* express thresh as ta*2^tn */
+ gap = (int)p_CgParams->fqTailDropThreshold;
+ for (tmpA=0 ; tmpA<256; tmpA++ )
+ for (tmpN=0 ; tmpN<32; tmpN++ )
+ {
+ tmp = ABS((int)(p_CgParams->fqTailDropThreshold - tmpA*(1<<tmpN)));
+ if (tmp < gap)
+ {
+ ta = tmpA;
+ tn = tmpN;
+ gap = tmp;
+ }
+ }
+ fq_opts.fqd.td.exp = tn;
+ fq_opts.fqd.td.mant = ta;
+ }
+
+ if (p_ContextA)
+ {
+ fq_opts.we_mask |= QM_INITFQ_WE_CONTEXTA;
+ memcpy((void*)&fq_opts.fqd.context_a, p_ContextA, sizeof(t_QmContextA));
+ }
+ /* If this FQ will not be used for tx, we can use contextB field */
+ if (fq_opts.fqd.dest.channel < e_QM_FQ_CHANNEL_FMAN0_SP0)
+ {
+ if (sizeof(p_Fqs[0]) <= sizeof(fq_opts.fqd.context_b))
+ {
+ fq_opts.we_mask |= QM_INITFQ_WE_CONTEXTB;
+ fq_opts.fqd.context_b = (uint32_t)PTR_TO_UINT(p_Fqs[0]);
+ }
+ else
+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("64 bit pointer (virtual) not supported yet!!!"));
+ }
+ else if (p_ContextB) /* Tx-Queue */
+ {
+ fq_opts.we_mask |= QM_INITFQ_WE_CONTEXTB;
+ memcpy((void*)&fq_opts.fqd.context_b, p_ContextB, sizeof(t_QmContextB));
+ }
+
+ if((flags & QM_FQCTRL_TDE) && (p_CgParams->overheadAccountingLength))
+ initFqFlag = 0;
+ else
+ initFqFlag = (uint32_t)(initParked?0:QMAN_INITFQ_FLAG_SCHED);
+
+ if ((err = qman_init_fq(p_QmPortal, p_Fqs[0], initFqFlag, &fq_opts)) != E_OK)
+ {
+ for(i=0;i<count;i++)
+ if (p_Fqs[i])
+ {
+ XX_FreeSmart(p_Fqs[i]);
+ p_Fqs[i] = NULL;
+ }
+ RETURN_ERROR(MINOR, err, ("Failed to init Fqs [%d-%d]", fqid, fqid+count-1));
+ }
+
+ /* if both CG OAC and FQ TD are needed, we call qman_init_fq again, this time for the FQ TD only */
+ if((flags & QM_FQCTRL_TDE) && (p_CgParams->overheadAccountingLength))
+ {
+ ASSERT_COND(p_CgParams->fqTailDropThreshold);
+
+ fq_opts.we_mask = QM_INITFQ_WE_TDTHRESH;
+
+ /* express thresh as ta*2^tn */
+ gap = (int)p_CgParams->fqTailDropThreshold;
+ for (tmpA=0 ; tmpA<256; tmpA++ )
+ for (tmpN=0 ; tmpN<32; tmpN++ )
+ {
+ tmp = ABS((int)(p_CgParams->fqTailDropThreshold - tmpA*(1<<tmpN)));
+ if (tmp < gap)
+ {
+ ta = tmpA;
+ tn = tmpN;
+ gap = tmp;
+ }
+ }
+ fq_opts.fqd.td.exp = tn;
+ fq_opts.fqd.td.mant = ta;
+ if ((err = qman_init_fq(p_QmPortal, p_Fqs[0], (uint32_t)(initParked?0:QMAN_INITFQ_FLAG_SCHED), &fq_opts)) != E_OK)
+ {
+ for(i=0;i<count;i++)
+ if (p_Fqs[i])
+ {
+ XX_FreeSmart(p_Fqs[i]);
+ p_Fqs[i] = NULL;
+ }
+ RETURN_ERROR(MINOR, err, ("Failed to init Fqs"));
+ }
+ }
+
+
+ for(i=1;i<count;i++)
+ {
+ memcpy(p_Fqs[i], p_Fqs[0], sizeof(struct qman_fq));
+ p_Fqs[i]->fqid += i;
+ }
+
+ return err;
+}
+
+
+static t_Error qm_free_fq(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq)
+{
+ uint32_t flags=0;
+
+ if (qman_retire_fq(p_QmPortal, p_Fq, &flags, FALSE) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed!"));
+
+ if (flags & QMAN_FQ_STATE_CHANGING)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("fq %d currently in use, will be retired", p_Fq->fqid));
+
+ if (flags & QMAN_FQ_STATE_NE)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed;" \
+ "Frame Queue Not Empty, Need to dequeue"));
+
+ if (qman_oos_fq(p_QmPortal, p_Fq) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_oos_fq() failed!"));
+
+ qman_destroy_fq(p_Fq,0);
+
+ return E_OK;
+}
+
+static void qman_disable_portal(t_QmPortal *p_QmPortal)
+{
+ NCSW_PLOCK(p_QmPortal);
+ if (!(p_QmPortal->disable_count++))
+ qm_dqrr_set_maxfill(p_QmPortal->p_LowQmPortal, 0);
+ PUNLOCK(p_QmPortal);
+}
+
+
+/* quiesce SDQCR/VDQCR, then drain till h/w wraps up anything it
+ * was doing (5ms is more than enough to ensure it's done). */
+static void clean_dqrr_mr(t_QmPortal *p_QmPortal)
+{
+ struct qm_dqrr_entry *p_Dq;
+ struct qm_mr_entry *p_Msg;
+ int idle = 0;
+
+ qm_dqrr_sdqcr_set(p_QmPortal->p_LowQmPortal, 0);
+ qm_dqrr_vdqcr_set(p_QmPortal->p_LowQmPortal, 0);
+drain_loop:
+ qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ qmPortalMrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
+ p_Msg = qm_mr_current(p_QmPortal->p_LowQmPortal);
+ if (p_Dq) {
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
+ }
+ if (p_Msg) {
+ qm_mr_next(p_QmPortal->p_LowQmPortal);
+ qmPortalMrCciConsume(p_QmPortal->p_LowQmPortal, 1);
+ }
+ if (!p_Dq && !p_Msg) {
+ if (++idle < 5) {
+ XX_UDelay(1000);
+ goto drain_loop;
+ }
+ } else {
+ idle = 0;
+ goto drain_loop;
+ }
+}
+
+static t_Error qman_create_portal(t_QmPortal *p_QmPortal,
+ uint32_t flags,
+ uint32_t sdqcrFlags,
+ uint8_t dqrrSize)
+{
+ const struct qm_portal_config *p_Config = &(p_QmPortal->p_LowQmPortal->config);
+ int ret = 0;
+ t_Error err;
+ uint32_t isdr;
+
+ if ((err = qm_eqcr_init(p_QmPortal->p_LowQmPortal, e_QmPortalPVB, e_QmPortalEqcrCCE)) != E_OK)
+ RETURN_ERROR(MINOR, err, ("Qman EQCR initialization failed\n"));
+
+ if (qm_dqrr_init(p_QmPortal->p_LowQmPortal,
+ sdqcrFlags ? e_QmPortalDequeuePushMode : e_QmPortalDequeuePullMode,
+ e_QmPortalPVB,
+ (flags & QMAN_PORTAL_FLAG_DCA) ? e_QmPortalDqrrDCA : e_QmPortalDqrrCCI,
+ dqrrSize,
+ (flags & QMAN_PORTAL_FLAG_RSTASH) ? 1 : 0,
+ (flags & QMAN_PORTAL_FLAG_DSTASH) ? 1 : 0)) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("DQRR initialization failed"));
+ goto fail_dqrr;
+ }
+
+ if (qm_mr_init(p_QmPortal->p_LowQmPortal, e_QmPortalPVB, e_QmPortalMrCCI)) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MR initialization failed"));
+ goto fail_mr;
+ }
+ if (qm_mc_init(p_QmPortal->p_LowQmPortal)) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MC initialization failed"));
+ goto fail_mc;
+ }
+ if (qm_isr_init(p_QmPortal->p_LowQmPortal)) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("ISR initialization failed"));
+ goto fail_isr;
+ }
+ /* static interrupt-gating controls */
+ qm_dqrr_set_ithresh(p_QmPortal->p_LowQmPortal, 12);
+ qm_mr_set_ithresh(p_QmPortal->p_LowQmPortal, 4);
+ qm_isr_set_iperiod(p_QmPortal->p_LowQmPortal, 100);
+ p_QmPortal->options = flags;
+ isdr = 0xffffffff;
+ qm_isr_status_clear(p_QmPortal->p_LowQmPortal, 0xffffffff);
+ qm_isr_enable_write(p_QmPortal->p_LowQmPortal, DEFAULT_portalExceptions);
+ qm_isr_disable_write(p_QmPortal->p_LowQmPortal, isdr);
+ if (flags & QMAN_PORTAL_FLAG_IRQ)
+ {
+ XX_SetIntr(p_Config->irq, portal_isr, p_QmPortal);
+ XX_EnableIntr(p_Config->irq);
+ qm_isr_uninhibit(p_QmPortal->p_LowQmPortal);
+ } else
+ /* without IRQ, we can't block */
+ flags &= ~QMAN_PORTAL_FLAG_WAIT;
+ /* Need EQCR to be empty before continuing */
+ isdr ^= QM_PIRQ_EQCI;
+ qm_isr_disable_write(p_QmPortal->p_LowQmPortal, isdr);
+ ret = qm_eqcr_get_fill(p_QmPortal->p_LowQmPortal);
+ if (ret) {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("EQCR unclean"));
+ goto fail_eqcr_empty;
+ }
+ isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
+ qm_isr_disable_write(p_QmPortal->p_LowQmPortal, isdr);
+ if (qm_dqrr_current(p_QmPortal->p_LowQmPortal) != NULL)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("DQRR unclean"));
+goto fail_dqrr_mr_empty;
+ }
+ if (qm_mr_current(p_QmPortal->p_LowQmPortal) != NULL)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MR unclean"));
+goto fail_dqrr_mr_empty;
+ }
+ qm_isr_disable_write(p_QmPortal->p_LowQmPortal, 0);
+ qm_dqrr_sdqcr_set(p_QmPortal->p_LowQmPortal, sdqcrFlags);
+ return E_OK;
+fail_dqrr_mr_empty:
+fail_eqcr_empty:
+ qm_isr_finish(p_QmPortal->p_LowQmPortal);
+fail_isr:
+ qm_mc_finish(p_QmPortal->p_LowQmPortal);
+fail_mc:
+ qm_mr_finish(p_QmPortal->p_LowQmPortal);
+fail_mr:
+ qm_dqrr_finish(p_QmPortal->p_LowQmPortal);
+fail_dqrr:
+ qm_eqcr_finish(p_QmPortal->p_LowQmPortal);
+ return ERROR_CODE(E_INVALID_STATE);
+}
+
+static void qman_destroy_portal(t_QmPortal *p_QmPortal)
+{
+ /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
+ * something related to QM_PIRQ_EQCI, this may need fixing. */
+ qmPortalEqcrCceUpdate(p_QmPortal->p_LowQmPortal);
+ if (p_QmPortal->options & QMAN_PORTAL_FLAG_IRQ)
+ {
+ XX_DisableIntr(p_QmPortal->p_LowQmPortal->config.irq);
+ XX_FreeIntr(p_QmPortal->p_LowQmPortal->config.irq);
+ }
+ qm_isr_finish(p_QmPortal->p_LowQmPortal);
+ qm_mc_finish(p_QmPortal->p_LowQmPortal);
+ qm_mr_finish(p_QmPortal->p_LowQmPortal);
+ qm_dqrr_finish(p_QmPortal->p_LowQmPortal);
+ qm_eqcr_finish(p_QmPortal->p_LowQmPortal);
+}
+
+static inline struct qm_eqcr_entry *try_eq_start(t_QmPortal *p_QmPortal)
+{
+ struct qm_eqcr_entry *p_Eq;
+ uint8_t avail;
+
+ avail = qm_eqcr_get_avail(p_QmPortal->p_LowQmPortal);
+ if (avail == EQCR_THRESH)
+ qmPortalEqcrCcePrefetch(p_QmPortal->p_LowQmPortal);
+ else if (avail < EQCR_THRESH)
+ qmPortalEqcrCceUpdate(p_QmPortal->p_LowQmPortal);
+ p_Eq = qm_eqcr_start(p_QmPortal->p_LowQmPortal);
+
+ return p_Eq;
+}
+
+
+static t_Error qman_orp_update(t_QmPortal *p_QmPortal,
+ uint32_t orpId,
+ uint16_t orpSeqnum,
+ uint32_t flags)
+{
+ struct qm_eqcr_entry *p_Eq;
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Eq = try_eq_start(p_QmPortal);
+ if (!p_Eq)
+ {
+ PUNLOCK(p_QmPortal);
+ return ERROR_CODE(E_BUSY);
+ }
+
+ if (flags & QMAN_ENQUEUE_FLAG_NESN)
+ orpSeqnum |= QM_EQCR_SEQNUM_NESN;
+ else
+ /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
+ orpSeqnum &= ~QM_EQCR_SEQNUM_NESN;
+ p_Eq->seqnum = orpSeqnum;
+ p_Eq->orp = orpId;
+qmPortalEqcrPvbCommit(p_QmPortal->p_LowQmPortal, (uint8_t)QM_EQCR_VERB_ORP);
+
+ PUNLOCK(p_QmPortal);
+ return E_OK;
+}
+
+static __inline__ t_Error CheckStashParams(t_QmFqrParams *p_QmFqrParams)
+{
+ ASSERT_COND(p_QmFqrParams);
+
+ if (p_QmFqrParams->stashingParams.frameAnnotationSize > QM_CONTEXTA_MAX_STASH_SIZE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Frame Annotation Size Exceeded Max Stash Size(%d)", QM_CONTEXTA_MAX_STASH_SIZE));
+ if (p_QmFqrParams->stashingParams.frameDataSize > QM_CONTEXTA_MAX_STASH_SIZE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Frame Data Size Exceeded Max Stash Size(%d)", QM_CONTEXTA_MAX_STASH_SIZE));
+ if (p_QmFqrParams->stashingParams.fqContextSize > QM_CONTEXTA_MAX_STASH_SIZE)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Frame Context Size Exceeded Max Stash Size(%d)", QM_CONTEXTA_MAX_STASH_SIZE));
+ if (p_QmFqrParams->stashingParams.fqContextSize)
+ {
+ if (!p_QmFqrParams->stashingParams.fqContextAddr)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FQ Context Address Must be givven"));
+ if (!IS_ALIGNED(p_QmFqrParams->stashingParams.fqContextAddr, CACHELINE_SIZE))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FQ Context Address Must be aligned to %d", CACHELINE_SIZE));
+ if (p_QmFqrParams->stashingParams.fqContextAddr & 0xffffff0000000000LL)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FQ Context Address May be up to 40 bit"));
+ }
+
+ return E_OK;
+}
+
+static t_Error QmPortalRegisterCg(t_Handle h_QmPortal, t_Handle h_QmCg, uint8_t cgId)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ /* cgrs[0] is the mask of registered CG's*/
+ if(p_QmPortal->cgrs[0].q.__state[cgId/32] & (0x80000000 >> (cgId % 32)))
+ RETURN_ERROR(MINOR, E_BUSY, ("CG already used"));
+
+ p_QmPortal->cgrs[0].q.__state[cgId/32] |= 0x80000000 >> (cgId % 32);
+ p_QmPortal->cgsHandles[cgId] = h_QmCg;
+
+ return E_OK;
+}
+
+static t_Error QmPortalUnregisterCg(t_Handle h_QmPortal, uint8_t cgId)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ /* cgrs[0] is the mask of registered CG's*/
+ if(!(p_QmPortal->cgrs[0].q.__state[cgId/32] & (0x80000000 >> (cgId % 32))))
+ RETURN_ERROR(MINOR, E_BUSY, ("CG is not in use"));
+
+ p_QmPortal->cgrs[0].q.__state[cgId/32] &= ~0x80000000 >> (cgId % 32);
+ p_QmPortal->cgsHandles[cgId] = NULL;
+
+ return E_OK;
+}
+
+static e_DpaaSwPortal QmPortalGetSwPortalId(t_Handle h_QmPortal)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ return (e_DpaaSwPortal)p_QmPortal->p_LowQmPortal->config.cpu;
+}
+
+static t_Error CalcWredCurve(t_QmCgWredCurve *p_WredCurve, uint32_t *p_CurveWord)
+{
+ uint32_t maxP, roundDown, roundUp, tmpA, tmpN;
+ uint32_t ma=0, mn=0, slope, sa=0, sn=0, pn;
+ int pres = 1000;
+ int gap, tmp;
+
+/* TODO - change maxTh to uint64_t?
+ if(p_WredCurve->maxTh > (1<<39))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("maxTh is not in range"));*/
+
+ /* express maxTh as ma*2^mn */
+ gap = (int)p_WredCurve->maxTh;
+ for (tmpA=0 ; tmpA<256; tmpA++ )
+ for (tmpN=0 ; tmpN<32; tmpN++ )
+ {
+ tmp = ABS((int)(p_WredCurve->maxTh - tmpA*(1<<tmpN)));
+ if (tmp < gap)
+ {
+ ma = tmpA;
+ mn = tmpN;
+ gap = tmp;
+ }
+ }
+ ASSERT_COND(ma <256);
+ ASSERT_COND(mn <32);
+ p_WredCurve->maxTh = ma*(1<<mn);
+
+ if(p_WredCurve->maxTh <= p_WredCurve->minTh)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("maxTh must be larger than minTh"));
+ if(p_WredCurve->probabilityDenominator > 64)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("probabilityDenominator mustn't be 1-64"));
+
+ /* first we translate from Cisco probabilityDenominator
+ to 256 fixed denominator, result must be divisible by 4. */
+ /* we multiply by a fixed value to get better accuracy (without
+ using floating point) */
+ maxP = (uint32_t)(256*1000/p_WredCurve->probabilityDenominator);
+ if (maxP % 4*pres)
+ {
+ roundDown = maxP + (maxP % (4*pres));
+ roundUp = roundDown + 4*pres;
+ if((roundUp - maxP) > (maxP - roundDown))
+ maxP = roundDown;
+ else
+ maxP = roundUp;
+ }
+ maxP = maxP/pres;
+ ASSERT_COND(maxP <= 256);
+ pn = (uint8_t)(maxP/4 - 1);
+
+ if(maxP >= (p_WredCurve->maxTh - p_WredCurve->minTh))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Due to probabilityDenominator selected, maxTh-minTh must be larger than %d", maxP));
+
+ pres = 1000000;
+ slope = maxP*pres/(p_WredCurve->maxTh - p_WredCurve->minTh);
+ /* express slope as sa/2^sn */
+ gap = (int)slope;
+ for (tmpA=(uint32_t)(64*pres) ; tmpA<128*pres; tmpA += pres )
+ for (tmpN=7 ; tmpN<64; tmpN++ )
+ {
+ tmp = ABS((int)(slope - tmpA/(1<<tmpN)));
+ if (tmp < gap)
+ {
+ sa = tmpA;
+ sn = tmpN;
+ gap = tmp;
+ }
+ }
+ sa = sa/pres;
+ ASSERT_COND(sa<128 && sa>=64);
+ sn = sn;
+ ASSERT_COND(sn<64 && sn>=7);
+
+ *p_CurveWord = ((ma << 24) |
+ (mn << 19) |
+ (sa << 12) |
+ (sn << 6) |
+ pn);
+
+ return E_OK;
+}
+
+static t_Error QmPortalPullFrame(t_Handle h_QmPortal, uint32_t pdqcr, t_DpaaFD *p_Frame)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+ struct qm_dqrr_entry *p_Dq;
+ struct qman_fq *p_Fq;
+ int prefetch;
+ uint32_t *p_Dst, *p_Src;
+
+ ASSERT_COND(p_QmPortal);
+ ASSERT_COND(p_Frame);
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal->pullMode, E_INVALID_STATE);
+
+ NCSW_PLOCK(p_QmPortal);
+
+ qm_dqrr_pdqcr_set(p_QmPortal->p_LowQmPortal, pdqcr);
+ CORE_MemoryBarrier();
+ while (qm_dqrr_pdqcr_get(p_QmPortal->p_LowQmPortal)) ;
+
+ prefetch = !(p_QmPortal->options & QMAN_PORTAL_FLAG_RSTASH);
+ while(TRUE)
+ {
+ if (prefetch)
+ qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
+ if (!p_Dq)
+ continue;
+ p_Fq = (void *)p_Dq->contextB;
+ ASSERT_COND(p_Dq->fqid);
+ p_Dst = (uint32_t *)p_Frame;
+ p_Src = (uint32_t *)&p_Dq->fd;
+ p_Dst[0] = p_Src[0];
+ p_Dst[1] = p_Src[1];
+ p_Dst[2] = p_Src[2];
+ p_Dst[3] = p_Src[3];
+ if (p_QmPortal->options & QMAN_PORTAL_FLAG_DCA)
+ {
+ qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
+ p_Dq,
+ FALSE);
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ }
+ else
+ {
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
+ }
+ break;
+ }
+
+ PUNLOCK(p_QmPortal);
+
+ if (!(p_Dq->stat & QM_DQRR_STAT_FD_VALID))
+ return ERROR_CODE(E_EMPTY);
+
+ return E_OK;
+}
+
+
+/****************************************/
+/* API Init unit functions */
+/****************************************/
+t_Handle QM_PORTAL_Config(t_QmPortalParam *p_QmPortalParam)
+{
+ t_QmPortal *p_QmPortal;
+ uint32_t i;
+
+ SANITY_CHECK_RETURN_VALUE(p_QmPortalParam, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_QmPortalParam->swPortalId < DPAA_MAX_NUM_OF_SW_PORTALS, E_INVALID_VALUE, 0);
+
+ p_QmPortal = (t_QmPortal *)XX_Malloc(sizeof(t_QmPortal));
+ if (!p_QmPortal)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Qm Portal obj!!!"));
+ return NULL;
+ }
+ memset(p_QmPortal, 0, sizeof(t_QmPortal));
+
+ p_QmPortal->p_LowQmPortal = (struct qm_portal *)XX_Malloc(sizeof(struct qm_portal));
+ if (!p_QmPortal->p_LowQmPortal)
+ {
+ XX_Free(p_QmPortal);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Low qm p_QmPortal obj!!!"));
+ return NULL;
+ }
+ memset(p_QmPortal->p_LowQmPortal, 0, sizeof(struct qm_portal));
+
+ p_QmPortal->p_QmPortalDriverParams = (t_QmPortalDriverParams *)XX_Malloc(sizeof(t_QmPortalDriverParams));
+ if (!p_QmPortal->p_QmPortalDriverParams)
+ {
+ XX_Free(p_QmPortal->p_LowQmPortal);
+ XX_Free(p_QmPortal);
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Qm Portal driver parameters"));
+ return NULL;
+ }
+ memset(p_QmPortal->p_QmPortalDriverParams, 0, sizeof(t_QmPortalDriverParams));
+
+ p_QmPortal->p_LowQmPortal->addr.addr_ce = UINT_TO_PTR(p_QmPortalParam->ceBaseAddress);
+ p_QmPortal->p_LowQmPortal->addr.addr_ci = UINT_TO_PTR(p_QmPortalParam->ciBaseAddress);
+ p_QmPortal->p_LowQmPortal->config.irq = p_QmPortalParam->irq;
+ p_QmPortal->p_LowQmPortal->config.bound = 0;
+ p_QmPortal->p_LowQmPortal->config.cpu = (int)p_QmPortalParam->swPortalId;
+ p_QmPortal->p_LowQmPortal->config.channel = (e_QmFQChannel)(e_QM_FQ_CHANNEL_SWPORTAL0 + p_QmPortalParam->swPortalId);
+ p_QmPortal->p_LowQmPortal->bind_lock = XX_InitSpinlock();
+
+ p_QmPortal->h_Qm = p_QmPortalParam->h_Qm;
+ p_QmPortal->f_DfltFrame = p_QmPortalParam->f_DfltFrame;
+ p_QmPortal->f_RejectedFrame = p_QmPortalParam->f_RejectedFrame;
+ p_QmPortal->h_App = p_QmPortalParam->h_App;
+
+ p_QmPortal->p_QmPortalDriverParams->fdLiodnOffset = p_QmPortalParam->fdLiodnOffset;
+ p_QmPortal->p_QmPortalDriverParams->dequeueDcaMode = DEFAULT_dequeueDcaMode;
+ p_QmPortal->p_QmPortalDriverParams->dequeueUpToThreeFrames = DEFAULT_dequeueUpToThreeFrames;
+ p_QmPortal->p_QmPortalDriverParams->commandType = DEFAULT_dequeueCommandType;
+ p_QmPortal->p_QmPortalDriverParams->userToken = DEFAULT_dequeueUserToken;
+ p_QmPortal->p_QmPortalDriverParams->specifiedWq = DEFAULT_dequeueSpecifiedWq;
+ p_QmPortal->p_QmPortalDriverParams->dedicatedChannel = DEFAULT_dequeueDedicatedChannel;
+ p_QmPortal->p_QmPortalDriverParams->dedicatedChannelHasPrecedenceOverPoolChannels =
+ DEFAULT_dequeueDedicatedChannelHasPrecedenceOverPoolChannels;
+ p_QmPortal->p_QmPortalDriverParams->poolChannelId = DEFAULT_dequeuePoolChannelId;
+ p_QmPortal->p_QmPortalDriverParams->wqId = DEFAULT_dequeueWqId;
+ for (i=0;i<QM_MAX_NUM_OF_POOL_CHANNELS;i++)
+ p_QmPortal->p_QmPortalDriverParams->poolChannels[i] = FALSE;
+ p_QmPortal->p_QmPortalDriverParams->dqrrSize = DEFAULT_dqrrSize;
+ p_QmPortal->p_QmPortalDriverParams->pullMode = DEFAULT_pullMode;
+
+ return p_QmPortal;
+}
+
+t_Error QM_PORTAL_Init(t_Handle h_QmPortal)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+ uint32_t i, flags=0, sdqcrFlags=0;
+ t_Error err;
+ t_QmInterModulePortalInitParams qmParams;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_INVALID_HANDLE);
+
+ memset(&qmParams, 0, sizeof(qmParams));
+ qmParams.portalId = (uint8_t)p_QmPortal->p_LowQmPortal->config.cpu;
+ qmParams.liodn = p_QmPortal->p_QmPortalDriverParams->fdLiodnOffset;
+ qmParams.dqrrLiodn = p_QmPortal->p_QmPortalDriverParams->dqrrLiodn;
+ qmParams.fdFqLiodn = p_QmPortal->p_QmPortalDriverParams->fdFqLiodn;
+ qmParams.stashDestQueue = p_QmPortal->p_QmPortalDriverParams->stashDestQueue;
+ if ((err = QmGetSetPortalParams(p_QmPortal->h_Qm, &qmParams)) != E_OK)
+ RETURN_ERROR(MAJOR, err, NO_MSG);
+
+ flags = (uint32_t)(((p_QmPortal->p_LowQmPortal->config.irq == NO_IRQ) ?
+ 0 :
+ (QMAN_PORTAL_FLAG_IRQ |
+ QMAN_PORTAL_FLAG_IRQ_FAST |
+ QMAN_PORTAL_FLAG_IRQ_SLOW)));
+ flags |= ((p_QmPortal->p_QmPortalDriverParams->dequeueDcaMode) ? QMAN_PORTAL_FLAG_DCA : 0);
+ flags |= (p_QmPortal->p_QmPortalDriverParams->dqrr)?QMAN_PORTAL_FLAG_RSTASH:0;
+ flags |= (p_QmPortal->p_QmPortalDriverParams->fdFq)?QMAN_PORTAL_FLAG_DSTASH:0;
+
+ p_QmPortal->pullMode = p_QmPortal->p_QmPortalDriverParams->pullMode;
+ if (!p_QmPortal->pullMode)
+ {
+ sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dequeueUpToThreeFrames) ? QM_SDQCR_COUNT_UPTO3 : QM_SDQCR_COUNT_EXACT1;
+ sdqcrFlags |= QM_SDQCR_TOKEN_SET(p_QmPortal->p_QmPortalDriverParams->userToken);
+ sdqcrFlags |= QM_SDQCR_TYPE_SET(p_QmPortal->p_QmPortalDriverParams->commandType);
+ if (!p_QmPortal->p_QmPortalDriverParams->specifiedWq)
+ {
+ /* sdqcrFlags |= QM_SDQCR_SOURCE_CHANNELS;*/ /* removed as the macro is '0' */
+ sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dedicatedChannelHasPrecedenceOverPoolChannels) ? QM_SDQCR_DEDICATED_PRECEDENCE : 0;
+ sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dedicatedChannel) ? QM_SDQCR_CHANNELS_DEDICATED : 0;
+ for (i=0;i<QM_MAX_NUM_OF_POOL_CHANNELS;i++)
+ sdqcrFlags |= ((p_QmPortal->p_QmPortalDriverParams->poolChannels[i]) ?
+ QM_SDQCR_CHANNELS_POOL(i+1) : 0);
+ }
+ else
+ {
+ sdqcrFlags |= QM_SDQCR_SOURCE_SPECIFICWQ;
+ sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dedicatedChannel) ?
+ QM_SDQCR_SPECIFICWQ_DEDICATED : QM_SDQCR_SPECIFICWQ_POOL(p_QmPortal->p_QmPortalDriverParams->poolChannelId);
+ sdqcrFlags |= QM_SDQCR_SPECIFICWQ_WQ(p_QmPortal->p_QmPortalDriverParams->wqId);
+ }
+ }
+ if ((flags & QMAN_PORTAL_FLAG_RSTASH) && (flags & QMAN_PORTAL_FLAG_DCA))
+ p_QmPortal->f_LoopDequeueRingCB = LoopDequeueRingDcaOptimized;
+ else if ((flags & QMAN_PORTAL_FLAG_RSTASH) && !(flags & QMAN_PORTAL_FLAG_DCA))
+ p_QmPortal->f_LoopDequeueRingCB = LoopDequeueRingOptimized;
+ else
+ p_QmPortal->f_LoopDequeueRingCB = LoopDequeueRing;
+
+ if ((!p_QmPortal->f_RejectedFrame) || (!p_QmPortal->f_DfltFrame))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_RejectedFrame or f_DfltFrame callback not provided"));
+
+ p_QmPortal->p_NullCB = (struct qman_fq_cb *)XX_Malloc(sizeof(struct qman_fq_cb));
+ if (!p_QmPortal->p_NullCB)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FQ Null CB obj!!!"));
+ memset(p_QmPortal->p_NullCB, 0, sizeof(struct qman_fq_cb));
+
+ p_QmPortal->p_NullCB->dqrr = p_QmPortal->f_DfltFrame;
+ p_QmPortal->p_NullCB->ern = p_QmPortal->f_RejectedFrame;
+ p_QmPortal->p_NullCB->dc_ern = p_QmPortal->p_NullCB->fqs = null_cb_mr;
+
+ if (qman_create_portal(p_QmPortal, flags, sdqcrFlags, p_QmPortal->p_QmPortalDriverParams->dqrrSize) != E_OK)
+ {
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("create portal failed"));
+ }
+
+ QmSetPortalHandle(p_QmPortal->h_Qm, (t_Handle)p_QmPortal, (e_DpaaSwPortal)p_QmPortal->p_LowQmPortal->config.cpu);
+ XX_Free(p_QmPortal->p_QmPortalDriverParams);
+ p_QmPortal->p_QmPortalDriverParams = NULL;
+
+ DBG(TRACE, ("Qman-Portal %d @ %p:%p",
+ p_QmPortal->p_LowQmPortal->config.cpu,
+ p_QmPortal->p_LowQmPortal->addr.addr_ce,
+ p_QmPortal->p_LowQmPortal->addr.addr_ci
+ ));
+
+ DBG(TRACE, ("Qman-Portal %d phys @ 0x%016llx:0x%016llx",
+ p_QmPortal->p_LowQmPortal->config.cpu,
+ (uint64_t)XX_VirtToPhys(p_QmPortal->p_LowQmPortal->addr.addr_ce),
+ (uint64_t)XX_VirtToPhys(p_QmPortal->p_LowQmPortal->addr.addr_ci)
+ ));
+
+ return E_OK;
+}
+
+t_Error QM_PORTAL_Free(t_Handle h_QmPortal)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ if (!p_QmPortal)
+ return ERROR_CODE(E_INVALID_HANDLE);
+
+ ASSERT_COND(p_QmPortal->p_LowQmPortal);
+ QmSetPortalHandle(p_QmPortal->h_Qm, NULL, (e_DpaaSwPortal)p_QmPortal->p_LowQmPortal->config.cpu);
+ qman_destroy_portal(p_QmPortal);
+ if (p_QmPortal->p_NullCB)
+ XX_Free(p_QmPortal->p_NullCB);
+
+ if (p_QmPortal->p_LowQmPortal->bind_lock)
+ XX_FreeSpinlock(p_QmPortal->p_LowQmPortal->bind_lock);
+ if(p_QmPortal->p_QmPortalDriverParams)
+ XX_Free(p_QmPortal->p_QmPortalDriverParams);
+ XX_Free(p_QmPortal->p_LowQmPortal);
+ XX_Free(p_QmPortal);
+
+ return E_OK;
+}
+
+t_Error QM_PORTAL_ConfigDcaMode(t_Handle h_QmPortal, bool enable)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_INVALID_HANDLE);
+
+ p_QmPortal->p_QmPortalDriverParams->dequeueDcaMode = enable;
+
+ return E_OK;
+}
+
+t_Error QM_PORTAL_ConfigStash(t_Handle h_QmPortal, t_QmPortalStashParam *p_StashParams)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR(p_StashParams, E_NULL_POINTER);
+
+ p_QmPortal->p_QmPortalDriverParams->stashDestQueue = p_StashParams->stashDestQueue;
+ p_QmPortal->p_QmPortalDriverParams->dqrrLiodn = p_StashParams->dqrrLiodn;
+ p_QmPortal->p_QmPortalDriverParams->fdFqLiodn = p_StashParams->fdFqLiodn;
+ p_QmPortal->p_QmPortalDriverParams->eqcr = p_StashParams->eqcr;
+ p_QmPortal->p_QmPortalDriverParams->eqcrHighPri = p_StashParams->eqcrHighPri;
+ p_QmPortal->p_QmPortalDriverParams->dqrr = p_StashParams->dqrr;
+ p_QmPortal->p_QmPortalDriverParams->dqrrHighPri = p_StashParams->dqrrHighPri;
+ p_QmPortal->p_QmPortalDriverParams->fdFq = p_StashParams->fdFq;
+ p_QmPortal->p_QmPortalDriverParams->fdFqHighPri = p_StashParams->fdFqHighPri;
+ p_QmPortal->p_QmPortalDriverParams->fdFqDrop = p_StashParams->fdFqDrop;
+
+ return E_OK;
+}
+
+
+t_Error QM_PORTAL_ConfigPullMode(t_Handle h_QmPortal, bool pullMode)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_NULL_POINTER);
+
+ p_QmPortal->p_QmPortalDriverParams->pullMode = pullMode;
+
+ return E_OK;
+}
+
+t_Error QM_PORTAL_AddPoolChannel(t_Handle h_QmPortal, uint8_t poolChannelId)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+ uint32_t sdqcrFlags;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((poolChannelId < QM_MAX_NUM_OF_POOL_CHANNELS), E_INVALID_VALUE);
+
+ sdqcrFlags = qm_dqrr_sdqcr_get(p_QmPortal->p_LowQmPortal);
+ sdqcrFlags |= QM_SDQCR_CHANNELS_POOL(poolChannelId+1);
+ qm_dqrr_sdqcr_set(p_QmPortal->p_LowQmPortal, sdqcrFlags);
+
+ return E_OK;
+}
+
+t_Error QM_PORTAL_Poll(t_Handle h_QmPortal, e_QmPortalPollSource source)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+
+ NCSW_PLOCK(p_QmPortal);
+
+ if ((source == e_QM_PORTAL_POLL_SOURCE_CONTROL_FRAMES) ||
+ (source == e_QM_PORTAL_POLL_SOURCE_BOTH))
+ {
+ uint32_t is = qm_isr_status_read(p_QmPortal->p_LowQmPortal);
+ uint32_t active = LoopMessageRing(p_QmPortal, is);
+ if (active)
+ qm_isr_status_clear(p_QmPortal->p_LowQmPortal, active);
+ }
+ if ((source == e_QM_PORTAL_POLL_SOURCE_DATA_FRAMES) ||
+ (source == e_QM_PORTAL_POLL_SOURCE_BOTH))
+ p_QmPortal->f_LoopDequeueRingCB((t_Handle)p_QmPortal);
+
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
+t_Error QM_PORTAL_PollFrame(t_Handle h_QmPortal, t_QmPortalFrameInfo *p_frameInfo)
+{
+ t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
+ struct qm_dqrr_entry *p_Dq;
+ struct qman_fq *p_Fq;
+ int prefetch;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR(p_frameInfo, E_NULL_POINTER);
+
+ NCSW_PLOCK(p_QmPortal);
+
+ prefetch = !(p_QmPortal->options & QMAN_PORTAL_FLAG_RSTASH);
+ if (prefetch)
+ qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
+ p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
+ if (!p_Dq)
+ {
+ PUNLOCK(p_QmPortal);
+ return ERROR_CODE(E_EMPTY);
+ }
+ p_Fq = (void *)p_Dq->contextB;
+ ASSERT_COND(p_Dq->fqid);
+ if (p_Fq)
+ {
+ p_frameInfo->h_App = p_Fq->h_App;
+ p_frameInfo->h_QmFqr = p_Fq->h_QmFqr;
+ p_frameInfo->fqidOffset = p_Fq->fqidOffset;
+ memcpy((void*)&p_frameInfo->frame, (void*)&p_Dq->fd, sizeof(t_DpaaFD));
+ }
+ else
+ {
+ p_frameInfo->h_App = p_QmPortal->h_App;
+ p_frameInfo->h_QmFqr = NULL;
+ p_frameInfo->fqidOffset = p_Dq->fqid;
+ memcpy((void*)&p_frameInfo->frame, (void*)&p_Dq->fd, sizeof(t_DpaaFD));
+ }
+ if (p_QmPortal->options & QMAN_PORTAL_FLAG_DCA) {
+ qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
+ p_Dq,
+ FALSE);
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ } else {
+ qm_dqrr_next(p_QmPortal->p_LowQmPortal);
+ qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
+ }
+
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
+
+t_Handle QM_FQR_Create(t_QmFqrParams *p_QmFqrParams)
+{
+ t_QmFqr *p_QmFqr;
+ uint32_t i, flags = 0;
+ u_QmFqdContextA cnxtA;
+
+ SANITY_CHECK_RETURN_VALUE(p_QmFqrParams, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_QmFqrParams->h_Qm, E_INVALID_HANDLE, NULL);
+
+ if (p_QmFqrParams->shadowMode &&
+ (!p_QmFqrParams->useForce || p_QmFqrParams->numOfFqids != 1))
+ {
+ REPORT_ERROR(MAJOR, E_CONFLICT, ("shadowMode must be use with useForce and numOfFqids==1!!!"));
+ return NULL;
+ }
+
+ p_QmFqr = (t_QmFqr *)XX_MallocSmart(sizeof(t_QmFqr), 0, 64);
+ if (!p_QmFqr)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM FQR obj!!!"));
+ return NULL;
+ }
+ memset(p_QmFqr, 0, sizeof(t_QmFqr));
+
+ p_QmFqr->h_Qm = p_QmFqrParams->h_Qm;
+ p_QmFqr->h_QmPortal = p_QmFqrParams->h_QmPortal;
+ p_QmFqr->shadowMode = p_QmFqrParams->shadowMode;
+ p_QmFqr->numOfFqids = (p_QmFqrParams->useForce && !p_QmFqrParams->numOfFqids) ?
+ 1 : p_QmFqrParams->numOfFqids;
+
+ if (!p_QmFqr->h_QmPortal)
+ {
+ p_QmFqr->h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
+ SANITY_CHECK_RETURN_VALUE(p_QmFqr->h_QmPortal, E_INVALID_HANDLE, NULL);
+ }
+
+ p_QmFqr->p_Fqs = (struct qman_fq **)XX_Malloc(sizeof(struct qman_fq *) * p_QmFqr->numOfFqids);
+ if (!p_QmFqr->p_Fqs)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM FQs obj!!!"));
+ QM_FQR_Free(p_QmFqr);
+ return NULL;
+ }
+ memset(p_QmFqr->p_Fqs, 0, sizeof(struct qman_fq *) * p_QmFqr->numOfFqids);
+
+ if (p_QmFqr->shadowMode)
+ {
+ struct qman_fq *p_Fq = NULL;
+
+ p_QmFqr->fqidBase = p_QmFqrParams->qs.frcQ.fqid;
+ p_Fq = (struct qman_fq *)XX_MallocSmart(sizeof(struct qman_fq), 0, 64);
+ if (!p_Fq)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
+ QM_FQR_Free(p_QmFqr);
+ return NULL;
+ }
+ memset(p_Fq, 0, sizeof(struct qman_fq));
+ p_Fq->cb.dqrr = ((t_QmPortal*)p_QmFqr->h_QmPortal)->f_DfltFrame;
+ p_Fq->cb.ern = ((t_QmPortal*)p_QmFqr->h_QmPortal)->f_RejectedFrame;
+ p_Fq->cb.dc_ern = cb_ern_dcErn;
+ p_Fq->cb.fqs = cb_fqs;
+ p_Fq->h_App = ((t_QmPortal*)p_QmFqr->h_QmPortal)->h_App;
+ p_Fq->h_QmFqr = p_QmFqr;
+ p_Fq->state = qman_fq_state_sched;
+ p_Fq->fqid = p_QmFqr->fqidBase;
+ p_QmFqr->p_Fqs[0] = p_Fq;
+ }
+ else
+ {
+ p_QmFqr->channel = p_QmFqrParams->channel;
+ p_QmFqr->workQueue = p_QmFqrParams->wq;
+
+ p_QmFqr->fqidBase = QmFqidGet(p_QmFqr->h_Qm,
+ p_QmFqr->numOfFqids,
+ p_QmFqrParams->qs.nonFrcQs.align,
+ p_QmFqrParams->useForce,
+ p_QmFqrParams->qs.frcQ.fqid);
+ if (p_QmFqr->fqidBase == (uint32_t)ILLEGAL_BASE)
+ {
+ REPORT_ERROR(CRITICAL,E_INVALID_STATE,("can't allocate a fqid"));
+ QM_FQR_Free(p_QmFqr);
+ return NULL;
+ }
+
+ if(p_QmFqrParams->congestionAvoidanceEnable &&
+ (p_QmFqrParams->congestionAvoidanceParams.h_QmCg == NULL) &&
+ (p_QmFqrParams->congestionAvoidanceParams.fqTailDropThreshold == 0))
+ {
+ REPORT_ERROR(CRITICAL,E_INVALID_STATE,("NULL congestion group handle and no FQ Threshold"));
+ QM_FQR_Free(p_QmFqr);
+ return NULL;
+ }
+ if(p_QmFqrParams->congestionAvoidanceEnable)
+ {
+ if(p_QmFqrParams->congestionAvoidanceParams.h_QmCg)
+ flags |= QM_FQCTRL_CGE;
+ if(p_QmFqrParams->congestionAvoidanceParams.fqTailDropThreshold)
+ flags |= QM_FQCTRL_TDE;
+ }
+
+ /*
+ flags |= (p_QmFqrParams->holdActive) ? QM_FQCTRL_ORP : 0;
+ flags |= (p_QmFqrParams->holdActive) ? QM_FQCTRL_CPCSTASH : 0;
+ flags |= (p_QmFqrParams->holdActive) ? QM_FQCTRL_FORCESFDR : 0;
+ flags |= (p_QmFqrParams->holdActive) ? QM_FQCTRL_AVOIDBLOCK : 0;
+ */
+ flags |= (p_QmFqrParams->holdActive) ? QM_FQCTRL_HOLDACTIVE : 0;
+ flags |= (p_QmFqrParams->preferInCache) ? QM_FQCTRL_LOCKINCACHE : 0;
+
+ if (p_QmFqrParams->useContextAForStash)
+ {
+ if (CheckStashParams(p_QmFqrParams) != E_OK)
+ {
+ REPORT_ERROR(CRITICAL,E_INVALID_STATE,NO_MSG);
+ QM_FQR_Free(p_QmFqr);
+ return NULL;
+ }
+
+ memset(&cnxtA, 0, sizeof(cnxtA));
+ cnxtA.stashing.annotation_cl = DIV_CEIL(p_QmFqrParams->stashingParams.frameAnnotationSize, CACHELINE_SIZE);
+ cnxtA.stashing.data_cl = DIV_CEIL(p_QmFqrParams->stashingParams.frameDataSize, CACHELINE_SIZE);
+ cnxtA.stashing.context_cl = DIV_CEIL(p_QmFqrParams->stashingParams.fqContextSize, CACHELINE_SIZE);
+ cnxtA.context_hi = (uint8_t)((p_QmFqrParams->stashingParams.fqContextAddr >> 32) & 0xff);
+ cnxtA.context_lo = (uint32_t)(p_QmFqrParams->stashingParams.fqContextAddr);
+ flags |= QM_FQCTRL_CTXASTASHING;
+ }
+
+ for(i=0;i<p_QmFqr->numOfFqids;i++)
+ if (qm_new_fq(p_QmFqr->h_QmPortal,
+ p_QmFqr->fqidBase+i,
+ i,
+ p_QmFqr->channel,
+ p_QmFqr->workQueue,
+ 1/*p_QmFqr->numOfFqids*/,
+ flags,
+ (p_QmFqrParams->congestionAvoidanceEnable ?
+ &p_QmFqrParams->congestionAvoidanceParams : NULL),
+ p_QmFqrParams->useContextAForStash ?
+ (t_QmContextA *)&cnxtA : p_QmFqrParams->p_ContextA,
+ p_QmFqrParams->p_ContextB,
+ p_QmFqrParams->initParked,
+ p_QmFqr,
+ &p_QmFqr->p_Fqs[i]) != E_OK)
+ {
+ QM_FQR_Free(p_QmFqr);
+ return NULL;
+ }
+ }
+ return p_QmFqr;
+}
+
+t_Error QM_FQR_Free(t_Handle h_QmFqr)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+ uint32_t i;
+
+ if (!p_QmFqr)
+ return ERROR_CODE(E_INVALID_HANDLE);
+
+ if (p_QmFqr->p_Fqs)
+ {
+ for (i=0;i<p_QmFqr->numOfFqids;i++)
+ if (p_QmFqr->p_Fqs[i])
+ {
+ if (!p_QmFqr->shadowMode)
+ qm_free_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i]);
+ XX_FreeSmart(p_QmFqr->p_Fqs[i]);
+ }
+ XX_Free(p_QmFqr->p_Fqs);
+ }
+
+ if (!p_QmFqr->shadowMode && p_QmFqr->fqidBase)
+ QmFqidPut(p_QmFqr->h_Qm, p_QmFqr->fqidBase);
+
+ XX_FreeSmart(p_QmFqr);
+
+ return E_OK;
+}
+
+t_Error QM_FQR_FreeWDrain(t_Handle h_QmFqr,
+ t_QmFqrDrainedCompletionCB *f_CompletionCB,
+ bool deliverFrame,
+ t_QmReceivedFrameCallback *f_CallBack,
+ t_Handle h_App)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+ uint32_t i;
+
+ if (!p_QmFqr)
+ return ERROR_CODE(E_INVALID_HANDLE);
+
+ if (p_QmFqr->shadowMode)
+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("QM_FQR_FreeWDrain can't be called to shadow FQR!!!. call QM_FQR_Free"));
+
+ p_QmFqr->p_DrainedFqs = (bool *)XX_Malloc(sizeof(bool) * p_QmFqr->numOfFqids);
+ if (!p_QmFqr->p_DrainedFqs)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("QM Drained-FQs obj!!!. Try to Free without draining"));
+ memset(p_QmFqr->p_DrainedFqs, 0, sizeof(bool) * p_QmFqr->numOfFqids);
+
+ if (f_CompletionCB)
+ {
+ p_QmFqr->f_CompletionCB = f_CompletionCB;
+ p_QmFqr->h_App = h_App;
+ }
+
+ if (deliverFrame)
+ {
+ if (!f_CallBack)
+ {
+ REPORT_ERROR(MAJOR, E_NULL_POINTER, ("f_CallBack must be given."));
+ XX_Free(p_QmFqr->p_DrainedFqs);
+ return ERROR_CODE(E_NULL_POINTER);
+ }
+ QM_FQR_RegisterCB(p_QmFqr, f_CallBack, h_App);
+ }
+ else
+ QM_FQR_RegisterCB(p_QmFqr, drainCB, h_App);
+
+ for (i=0;i<p_QmFqr->numOfFqids;i++)
+ {
+ if (qman_retire_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i], 0, TRUE) != E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed!"));
+
+ if (p_QmFqr->p_Fqs[i]->flags & QMAN_FQ_STATE_CHANGING)
+ DBG(INFO, ("fq %d currently in use, will be retired", p_QmFqr->p_Fqs[i]->fqid));
+ else
+ drainRetiredFq(p_QmFqr->p_Fqs[i]);
+ }
+
+ if (!p_QmFqr->f_CompletionCB)
+ {
+ while(p_QmFqr->p_DrainedFqs) ;
+ DBG(TRACE, ("QM-FQR with base %d completed", p_QmFqr->fqidBase));
+ XX_FreeSmart(p_QmFqr->p_Fqs);
+ if (p_QmFqr->fqidBase)
+ QmFqidPut(p_QmFqr->h_Qm, p_QmFqr->fqidBase);
+ XX_FreeSmart(p_QmFqr);
+ }
+
+ return E_OK;
+}
+
+t_Error QM_FQR_RegisterCB(t_Handle h_QmFqr, t_QmReceivedFrameCallback *f_CallBack, t_Handle h_App)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+ int i;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
+
+ for (i=0;i<p_QmFqr->numOfFqids;i++)
+ {
+ p_QmFqr->p_Fqs[i]->cb.dqrr = f_CallBack;
+ p_QmFqr->p_Fqs[i]->h_App = h_App;
+ }
+
+ return E_OK;
+}
+
+t_Error QM_FQR_Enqueue(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, t_DpaaFD *p_Frame)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+ t_QmPortal *p_QmPortal;
+ struct qm_eqcr_entry *p_Eq;
+ uint32_t *p_Dst, *p_Src;
+ const struct qman_fq *p_Fq;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
+
+ if (!h_QmPortal)
+ {
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr->h_Qm, E_INVALID_HANDLE);
+ h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
+ SANITY_CHECK_RETURN_ERROR(h_QmPortal, E_INVALID_HANDLE);
+ }
+ p_QmPortal = (t_QmPortal *)h_QmPortal;
+
+ p_Fq = p_QmFqr->p_Fqs[fqidOffset];
+
+#ifdef QM_CHECKING
+ if (p_Fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+ if ((!(p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)) &&
+ ((p_Fq->state == qman_fq_state_retired) ||
+ (p_Fq->state == qman_fq_state_oos)))
+ return ERROR_CODE(E_BUSY);
+#endif /* QM_CHECKING */
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Eq = try_eq_start(p_QmPortal);
+ if (!p_Eq)
+ {
+ PUNLOCK(p_QmPortal);
+ return ERROR_CODE(E_BUSY);
+ }
+
+ p_Eq->fqid = p_Fq->fqid;
+ p_Eq->tag = (uint32_t)p_Fq;
+ /* gcc does a dreadful job of the following;
+ * eq->fd = *fd;
+ * It causes the entire function to save/restore a wider range of
+ * registers, and comes up with instruction-waste galore. This will do
+ * until we can rework the function for better code-generation. */
+ p_Dst = (uint32_t *)&p_Eq->fd;
+ p_Src = (uint32_t *)p_Frame;
+ p_Dst[0] = p_Src[0];
+ p_Dst[1] = p_Src[1];
+ p_Dst[2] = p_Src[2];
+ p_Dst[3] = p_Src[3];
+
+ qmPortalEqcrPvbCommit(p_QmPortal->p_LowQmPortal,
+ (uint8_t)(QM_EQCR_VERB_CMD_ENQUEUE/* |
+ (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))*/));
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
+
+t_Error QM_FQR_PullFrame(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, t_DpaaFD *p_Frame)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+ uint32_t pdqcr = 0;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR(p_Frame, E_NULL_POINTER);
+ SANITY_CHECK_RETURN_ERROR((p_QmFqr->p_Fqs[fqidOffset]->state == qman_fq_state_oos) ||
+ (p_QmFqr->p_Fqs[fqidOffset]->state == qman_fq_state_parked),
+ E_INVALID_STATE);
+ if (!h_QmPortal)
+ {
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr->h_Qm, E_INVALID_HANDLE);
+ h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
+ SANITY_CHECK_RETURN_ERROR(h_QmPortal, E_INVALID_HANDLE);
+ }
+
+ pdqcr |= QM_PDQCR_MODE_UNSCHEDULED;
+ pdqcr |= QM_PDQCR_FQID(p_QmFqr->p_Fqs[fqidOffset]->fqid);
+ return QmPortalPullFrame(h_QmPortal, pdqcr, p_Frame);
+}
+
+t_Error QM_FQR_Resume(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
+
+ if (!h_QmPortal)
+ {
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr->h_Qm, E_INVALID_HANDLE);
+ h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
+ SANITY_CHECK_RETURN_ERROR(h_QmPortal, E_INVALID_HANDLE);
+ }
+ return qman_schedule_fq(h_QmPortal, p_QmFqr->p_Fqs[fqidOffset]);
+}
+
+t_Error QM_FQR_Suspend(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
+ SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
+ SANITY_CHECK_RETURN_ERROR((p_QmFqr->p_Fqs[fqidOffset]->flags & QM_FQCTRL_HOLDACTIVE), E_INVALID_STATE);
+
+ UNUSED(h_QmPortal);
+ p_QmFqr->p_Fqs[fqidOffset]->state = qman_fq_state_waiting_parked;
+
+ return E_OK;
+}
+
+uint32_t QM_FQR_GetFqid(t_Handle h_QmFqr)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+
+ SANITY_CHECK_RETURN_VALUE(p_QmFqr, E_INVALID_HANDLE, 0);
+
+ return p_QmFqr->fqidBase;
+}
+
+uint32_t QM_FQR_GetCounter(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, e_QmFqrCounters counter)
+{
+ t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
+ struct qm_mcr_queryfq_np queryfq_np;
+
+ SANITY_CHECK_RETURN_VALUE(p_QmFqr, E_INVALID_HANDLE, 0);
+ SANITY_CHECK_RETURN_VALUE((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE, 0);
+
+ if (!h_QmPortal)
+ {
+ SANITY_CHECK_RETURN_VALUE(p_QmFqr->h_Qm, E_INVALID_HANDLE, 0);
+ h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
+ SANITY_CHECK_RETURN_VALUE(h_QmPortal, E_INVALID_HANDLE, 0);
+ }
+ if (qman_query_fq_np(h_QmPortal, p_QmFqr->p_Fqs[fqidOffset], &queryfq_np) != E_OK)
+ return 0;
+ switch (counter)
+ {
+ case e_QM_FQR_COUNTERS_FRAME :
+ return queryfq_np.frm_cnt;
+ case e_QM_FQR_COUNTERS_BYTE :
+ return queryfq_np.byte_cnt;
+ default :
+ break;
+ }
+ /* should never get here */
+ ASSERT_COND(FALSE);
+
+ return 0;
+}
+
+
+t_Handle QM_CG_Create(t_QmCgParams *p_CgParams)
+{
+ t_QmCg *p_QmCg;
+ t_QmPortal *p_QmPortal;
+ t_Error err;
+ uint32_t wredParams;
+ uint32_t tmpA, tmpN, ta=0, tn=0;
+ int gap, tmp;
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+
+ SANITY_CHECK_RETURN_VALUE(p_CgParams, E_INVALID_HANDLE, NULL);
+ SANITY_CHECK_RETURN_VALUE(p_CgParams->h_Qm, E_INVALID_HANDLE, NULL);
+
+ if(p_CgParams->notifyDcPortal &&
+ ((p_CgParams->dcPortalId == e_DPAA_DCPORTAL2) || (p_CgParams->dcPortalId == e_DPAA_DCPORTAL3)))
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("notifyDcPortal is invalid for this DC Portal"));
+ return NULL;
+ }
+
+ if (!p_CgParams->h_QmPortal)
+ {
+ p_QmPortal = QmGetPortalHandle(p_CgParams->h_Qm);
+ SANITY_CHECK_RETURN_VALUE(p_QmPortal, E_INVALID_STATE, NULL);
+ }
+ else
+ p_QmPortal = p_CgParams->h_QmPortal;
+
+ p_QmCg = (t_QmCg *)XX_Malloc(sizeof(t_QmCg));
+ if (!p_QmCg)
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM CG obj!!!"));
+ return NULL;
+ }
+ memset(p_QmCg, 0, sizeof(t_QmCg));
+
+ /* build CG struct */
+ p_QmCg->h_Qm = p_CgParams->h_Qm;
+ p_QmCg->h_QmPortal = p_QmPortal;
+ p_QmCg->h_App = p_CgParams->h_App;
+ err = QmGetCgId(p_CgParams->h_Qm, &p_QmCg->id);
+ if (err)
+ {
+ XX_Free(p_QmCg);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("QmGetCgId failed"));
+ return NULL;
+ }
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->initcgr.cgid = p_QmCg->id;
+
+ err = QmPortalRegisterCg(p_QmPortal, p_QmCg, p_QmCg->id);
+ if (err)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("QmPortalRegisterCg failed"));
+ return NULL;
+ }
+
+ /* Build CGR command */
+ {
+#ifdef QM_CGS_NO_FRAME_MODE
+ t_QmRevisionInfo revInfo;
+
+ QmGetRevision(p_QmCg->h_Qm, &revInfo);
+
+ if (!((revInfo.majorRev == 1) && (revInfo.minorRev == 0)))
+#endif /* QM_CGS_NO_FRAME_MODE */
+ if (p_CgParams->frameCount)
+ {
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_MODE;
+ p_Mcc->initcgr.cgr.frame_mode = QM_CGR_EN;
+ }
+ }
+
+ if (p_CgParams->wredEnable)
+ {
+ if (p_CgParams->wredParams.enableGreen)
+ {
+ err = CalcWredCurve(&p_CgParams->wredParams.greenCurve, &wredParams);
+ if(err)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_G | QM_CGR_WE_WR_PARM_G;
+ p_Mcc->initcgr.cgr.wr_en_g = QM_CGR_EN;
+ p_Mcc->initcgr.cgr.wr_parm_g.word = wredParams;
+ }
+ if (p_CgParams->wredParams.enableYellow)
+ {
+ err = CalcWredCurve(&p_CgParams->wredParams.yellowCurve, &wredParams);
+ if(err)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_Y | QM_CGR_WE_WR_PARM_Y;
+ p_Mcc->initcgr.cgr.wr_en_y = QM_CGR_EN;
+ p_Mcc->initcgr.cgr.wr_parm_y.word = wredParams;
+ }
+ if (p_CgParams->wredParams.enableRed)
+ {
+ err = CalcWredCurve(&p_CgParams->wredParams.redCurve, &wredParams);
+ if(err)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ REPORT_ERROR(MAJOR, err, NO_MSG);
+ return NULL;
+ }
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_R | QM_CGR_WE_WR_PARM_R;
+ p_Mcc->initcgr.cgr.wr_en_r = QM_CGR_EN;
+ p_Mcc->initcgr.cgr.wr_parm_r.word = wredParams;
+ }
+ }
+
+ if (p_CgParams->tailDropEnable)
+ {
+ if (!p_CgParams->threshold)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("tailDropThreshold must be configured if tailDropEnable "));
+ return NULL;
+ }
+ p_Mcc->initcgr.cgr.cstd_en = QM_CGR_EN;
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
+ }
+
+ if (p_CgParams->threshold)
+ {
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_CS_THRES;
+ p_QmCg->f_Exception = p_CgParams->f_Exception;
+ if (p_QmCg->f_Exception || p_CgParams->notifyDcPortal)
+ {
+ p_Mcc->initcgr.cgr.cscn_en = QM_CGR_EN;
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_CSCN_EN | QM_CGR_WE_CSCN_TARG;
+ /* if SW - set target, if HW - if FM, set HW target, otherwize, set SW target */
+ p_Mcc->initcgr.cgr.cscn_targ = 0;
+ if (p_QmCg->f_Exception)
+ p_Mcc->initcgr.cgr.cscn_targ = (uint32_t)QM_CGR_TARGET_SWP(QmPortalGetSwPortalId(p_QmCg->h_QmPortal));
+ if (p_CgParams->notifyDcPortal)
+ p_Mcc->initcgr.cgr.cscn_targ |= (uint32_t)QM_CGR_TARGET_DCP(p_CgParams->dcPortalId);
+ }
+
+ /* express thresh as ta*2^tn */
+ gap = (int)p_CgParams->threshold;
+ for (tmpA=0 ; tmpA<256; tmpA++ )
+ for (tmpN=0 ; tmpN<32; tmpN++ )
+ {
+ tmp = ABS((int)(p_CgParams->threshold - tmpA*(1<<tmpN)));
+ if (tmp < gap)
+ {
+ ta = tmpA;
+ tn = tmpN;
+ gap = tmp;
+ }
+ }
+ p_Mcc->initcgr.cgr.cs_thres.TA = ta;
+ p_Mcc->initcgr.cgr.cs_thres.Tn = tn;
+ }
+ else if(p_CgParams->f_Exception)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("No threshold configured, but f_Exception defined"));
+ return NULL;
+ }
+
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_INITCGR);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_INITCGR);
+ if (p_Mcr->result != QM_MCR_RESULT_OK)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
+ return NULL;
+ }
+ PUNLOCK(p_QmPortal);
+
+ return p_QmCg;
+}
+
+t_Error QM_CG_Free(t_Handle h_QmCg)
+{
+
+ t_QmCg *p_QmCg = (t_QmCg *)h_QmCg;
+ t_Error err;
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ t_QmPortal *p_QmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
+
+ p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->initcgr.cgid = p_QmCg->id;
+ p_Mcc->initcgr.we_mask = QM_CGR_WE_MASK;
+
+ err = QmFreeCgId(p_QmCg->h_Qm, p_QmCg->id);
+ if(err)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("QmFreeCgId failed"));
+ }
+
+ err = QmPortalUnregisterCg(p_QmCg->h_QmPortal, p_QmCg->id);
+ if(err)
+ {
+ XX_Free(p_QmCg);
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("QmPortalUnregisterCg failed"));
+ }
+
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
+ if (p_Mcr->result != QM_MCR_RESULT_OK)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+ PUNLOCK(p_QmPortal);
+
+ XX_Free(p_QmCg);
+
+ return E_OK;
+}
+
+t_Error QM_CG_SetException(t_Handle h_QmCg, e_QmExceptions exception, bool enable)
+{
+ t_QmCg *p_QmCg = (t_QmCg *)h_QmCg;
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ t_QmPortal *p_QmPortal;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
+
+ p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
+ if (!p_QmCg->f_Exception)
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Either threshold or exception callback was not configured."));
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->initcgr.cgid = p_QmCg->id;
+ p_Mcc->initcgr.we_mask = QM_CGR_WE_CSCN_EN;
+
+ if(exception == e_QM_EX_CG_STATE_CHANGE)
+ {
+ if(enable)
+ p_Mcc->initcgr.cgr.cscn_en = QM_CGR_EN;
+ }
+ else
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal exception"));
+ }
+
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
+ if (p_Mcr->result != QM_MCR_RESULT_OK)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
+t_Error QM_CG_ModifyWredCurve(t_Handle h_QmCg, t_QmCgModifyWredParams *p_QmCgModifyParams)
+{
+ t_QmCg *p_QmCg = (t_QmCg *)h_QmCg;
+ uint32_t wredParams;
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ t_QmPortal *p_QmPortal;
+ t_Error err = E_OK;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
+
+ p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->initcgr.cgid = p_QmCg->id;
+
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYCGR);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
+ if (p_Mcr->result != QM_MCR_RESULT_OK)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("QM_MCC_VERB_QUERYCGR failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+
+ switch(p_QmCgModifyParams->color)
+ {
+ case(e_QM_CG_COLOR_GREEN):
+ if(!p_Mcr->querycgr.cgr.wr_en_g)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("WRED is not enabled for green"));
+ }
+ break;
+ case(e_QM_CG_COLOR_YELLOW):
+ if(!p_Mcr->querycgr.cgr.wr_en_y)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("WRED is not enabled for yellow"));
+ }
+ break;
+ case(e_QM_CG_COLOR_RED):
+ if(!p_Mcr->querycgr.cgr.wr_en_r)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("WRED is not enabled for red"));
+ }
+ break;
+ }
+
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->initcgr.cgid = p_QmCg->id;
+
+ switch(p_QmCgModifyParams->color)
+ {
+ case(e_QM_CG_COLOR_GREEN):
+ err = CalcWredCurve(&p_QmCgModifyParams->wredParams, &wredParams);
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_G | QM_CGR_WE_WR_PARM_G;
+ p_Mcc->initcgr.cgr.wr_en_g = QM_CGR_EN;
+ p_Mcc->initcgr.cgr.wr_parm_g.word = wredParams;
+ break;
+ case(e_QM_CG_COLOR_YELLOW):
+ err = CalcWredCurve(&p_QmCgModifyParams->wredParams, &wredParams);
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_Y | QM_CGR_WE_WR_PARM_Y;
+ p_Mcc->initcgr.cgr.wr_en_y = QM_CGR_EN;
+ p_Mcc->initcgr.cgr.wr_parm_y.word = wredParams;
+ break;
+ case(e_QM_CG_COLOR_RED):
+ err = CalcWredCurve(&p_QmCgModifyParams->wredParams, &wredParams);
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_R | QM_CGR_WE_WR_PARM_R;
+ p_Mcc->initcgr.cgr.wr_en_r = QM_CGR_EN;
+ p_Mcc->initcgr.cgr.wr_parm_r.word = wredParams;
+ break;
+ }
+ if (err)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
+ if (p_Mcr->result != QM_MCR_RESULT_OK)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
+t_Error QM_CG_ModifyTailDropThreshold(t_Handle h_QmCg, uint32_t threshold)
+{
+ t_QmCg *p_QmCg = (t_QmCg *)h_QmCg;
+ struct qm_mc_command *p_Mcc;
+ struct qm_mc_result *p_Mcr;
+ t_QmPortal *p_QmPortal;
+ uint32_t tmpA, tmpN, ta=0, tn=0;
+ int gap, tmp;
+
+ SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
+
+ p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
+
+ NCSW_PLOCK(p_QmPortal);
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->initcgr.cgid = p_QmCg->id;
+
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYCGR);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
+ if (p_Mcr->result != QM_MCR_RESULT_OK)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("QM_MCC_VERB_QUERYCGR failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+
+ if(!p_Mcr->querycgr.cgr.cstd_en)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tail Drop is not enabled!"));
+ }
+
+ p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
+ p_Mcc->initcgr.cgid = p_QmCg->id;
+ p_Mcc->initcgr.we_mask |= QM_CGR_WE_CS_THRES;
+
+ /* express thresh as ta*2^tn */
+ gap = (int)threshold;
+ for (tmpA=0 ; tmpA<256; tmpA++ )
+ for (tmpN=0 ; tmpN<32; tmpN++ )
+ {
+ tmp = ABS((int)(threshold - tmpA*(1<<tmpN)));
+ if (tmp < gap)
+ {
+ ta = tmpA;
+ tn = tmpN;
+ gap = tmp;
+ }
+ }
+ p_Mcc->initcgr.cgr.cs_thres.TA = ta;
+ p_Mcc->initcgr.cgr.cs_thres.Tn = tn;
+
+ qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
+ while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
+ ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
+ if (p_Mcr->result != QM_MCR_RESULT_OK)
+ {
+ PUNLOCK(p_QmPortal);
+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
+ }
+ PUNLOCK(p_QmPortal);
+
+ return E_OK;
+}
+
diff --git a/sys/contrib/ncsw/Peripherals/QM/qman_low.h b/sys/contrib/ncsw/Peripherals/QM/qman_low.h
new file mode 100644
index 0000000..ea00514
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/QM/qman_low.h
@@ -0,0 +1,1148 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File qman_low.c
+
+ @Description QM Low-level implementation
+*//***************************************************************************/
+#include "std_ext.h"
+#include "core_ext.h"
+#include "xx_ext.h"
+#include "error_ext.h"
+
+#include "qman_private.h"
+
+
+/***************************/
+/* Portal register assists */
+/***************************/
+
+/* Cache-inhibited register offsets */
+#define REG_EQCR_PI_CINH (void *)0x0000
+#define REG_EQCR_CI_CINH (void *)0x0004
+#define REG_EQCR_ITR (void *)0x0008
+#define REG_DQRR_PI_CINH (void *)0x0040
+#define REG_DQRR_CI_CINH (void *)0x0044
+#define REG_DQRR_ITR (void *)0x0048
+#define REG_DQRR_DCAP (void *)0x0050
+#define REG_DQRR_SDQCR (void *)0x0054
+#define REG_DQRR_VDQCR (void *)0x0058
+#define REG_DQRR_PDQCR (void *)0x005c
+#define REG_MR_PI_CINH (void *)0x0080
+#define REG_MR_CI_CINH (void *)0x0084
+#define REG_MR_ITR (void *)0x0088
+#define REG_CFG (void *)0x0100
+#define REG_ISR (void *)0x0e00
+#define REG_IER (void *)0x0e04
+#define REG_ISDR (void *)0x0e08
+#define REG_IIR (void *)0x0e0c
+#define REG_ITPR (void *)0x0e14
+
+/* Cache-enabled register offsets */
+#define CL_EQCR (void *)0x0000
+#define CL_DQRR (void *)0x1000
+#define CL_MR (void *)0x2000
+#define CL_EQCR_PI_CENA (void *)0x3000
+#define CL_EQCR_CI_CENA (void *)0x3100
+#define CL_DQRR_PI_CENA (void *)0x3200
+#define CL_DQRR_CI_CENA (void *)0x3300
+#define CL_MR_PI_CENA (void *)0x3400
+#define CL_MR_CI_CENA (void *)0x3500
+#define CL_RORI_CENA (void *)0x3600
+#define CL_CR (void *)0x3800
+#define CL_RR0 (void *)0x3900
+#define CL_RR1 (void *)0x3940
+
+static __inline__ void *ptr_ADD(void *a, void *b)
+{
+ return (void *)((uintptr_t)a + (uintptr_t)b);
+}
+
+/* The h/w design requires mappings to be size-aligned so that "add"s can be
+ * reduced to "or"s. The primitives below do the same for s/w. */
+/* Bitwise-OR two pointers */
+static __inline__ void *ptr_OR(void *a, void *b)
+{
+ return (void *)((uintptr_t)a + (uintptr_t)b);
+}
+
+/* Cache-inhibited register access */
+static __inline__ uint32_t __qm_in(struct qm_addr *qm, void *offset)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(qm->addr_ci, offset);
+ return GET_UINT32(*tmp);
+}
+static __inline__ void __qm_out(struct qm_addr *qm, void *offset, uint32_t val)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(qm->addr_ci, offset);
+ WRITE_UINT32(*tmp, val);
+}
+#define qm_in(reg) __qm_in(&portal->addr, REG_##reg)
+#define qm_out(reg, val) __qm_out(&portal->addr, REG_##reg, (uint32_t)val)
+
+/* Convert 'n' cachelines to a pointer value for bitwise OR */
+#define qm_cl(n) (void *)((n) << 6)
+
+/* Cache-enabled (index) register access */
+static __inline__ void __qm_cl_touch_ro(struct qm_addr *qm, void *offset)
+{
+ dcbt_ro(ptr_ADD(qm->addr_ce, offset));
+}
+static __inline__ void __qm_cl_touch_rw(struct qm_addr *qm, void *offset)
+{
+ dcbt_rw(ptr_ADD(qm->addr_ce, offset));
+}
+static __inline__ uint32_t __qm_cl_in(struct qm_addr *qm, void *offset)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(qm->addr_ce, offset);
+ return GET_UINT32(*tmp);
+}
+static __inline__ void __qm_cl_out(struct qm_addr *qm, void *offset, uint32_t val)
+{
+ uint32_t *tmp = (uint32_t *)ptr_ADD(qm->addr_ce, offset);
+ WRITE_UINT32(*tmp, val);
+ dcbf(tmp);
+}
+static __inline__ void __qm_cl_invalidate(struct qm_addr *qm, void *offset)
+{
+ dcbi(ptr_ADD(qm->addr_ce, offset));
+}
+#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, CL_##reg##_CENA)
+#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, CL_##reg##_CENA)
+#define qm_cl_in(reg) __qm_cl_in(&portal->addr, CL_##reg##_CENA)
+#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, CL_##reg##_CENA, val)
+#define qm_cl_invalidate(reg) __qm_cl_invalidate(&portal->addr, CL_##reg##_CENA)
+
+/* Cyclic helper for rings. TODO: once we are able to do fine-grain perf
+ * analysis, look at using the "extra" bit in the ring index registers to avoid
+ * cyclic issues. */
+static __inline__ uint8_t cyc_diff(uint8_t ringsize, uint8_t first, uint8_t last)
+{
+ /* 'first' is included, 'last' is excluded */
+ if (first <= last)
+ return (uint8_t)(last - first);
+ return (uint8_t)(ringsize + last - first);
+}
+
+static __inline__ t_Error __qm_portal_bind(struct qm_portal *portal, uint8_t iface)
+{
+ t_Error ret = E_BUSY;
+ if (!(portal->config.bound & iface)) {
+ portal->config.bound |= iface;
+ ret = E_OK;
+ }
+ return ret;
+}
+
+static __inline__ void __qm_portal_unbind(struct qm_portal *portal, uint8_t iface)
+{
+#ifdef QM_CHECKING
+ ASSERT_COND(portal->config.bound & iface);
+#endif /* QM_CHECKING */
+ portal->config.bound &= ~iface;
+}
+
+/* ---------------- */
+/* --- EQCR API --- */
+
+/* It's safer to code in terms of the 'eqcr' object than the 'portal' object,
+ * because the latter runs the risk of copy-n-paste errors from other code where
+ * we could manipulate some other structure within 'portal'. */
+/* #define EQCR_API_START() register struct qm_eqcr *eqcr = &portal->eqcr */
+
+/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
+#define EQCR_CARRYCLEAR(p) \
+ (void *)((uintptr_t)(p) & (~(uintptr_t)(QM_EQCR_SIZE << 6)))
+
+/* Bit-wise logic to convert a ring pointer to a ring index */
+static __inline__ uint8_t EQCR_PTR2IDX(struct qm_eqcr_entry *e)
+{
+ return (uint8_t)(((uint32_t)e >> 6) & (QM_EQCR_SIZE - 1));
+}
+
+/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
+static __inline__ void EQCR_INC(struct qm_eqcr *eqcr)
+{
+ /* NB: this is odd-looking, but experiments show that it generates fast
+ * code with essentially no branching overheads. We increment to the
+ * next EQCR pointer and handle overflow and 'vbit'. */
+ struct qm_eqcr_entry *partial = eqcr->cursor + 1;
+ eqcr->cursor = EQCR_CARRYCLEAR(partial);
+ if (partial != eqcr->cursor)
+ eqcr->vbit ^= QM_EQCR_VERB_VBIT;
+}
+
+static __inline__ t_Error qm_eqcr_init(struct qm_portal *portal, e_QmPortalProduceMode pmode,
+ e_QmPortalEqcrConsumeMode cmode)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ uint32_t cfg;
+ uint8_t pi;
+
+ if (__qm_portal_bind(portal, QM_BIND_EQCR))
+ return ERROR_CODE(E_BUSY);
+ eqcr->ring = ptr_ADD(portal->addr.addr_ce, CL_EQCR);
+ eqcr->ci = (uint8_t)(qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1));
+ qm_cl_invalidate(EQCR_CI);
+ pi = (uint8_t)(qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1));
+ eqcr->cursor = eqcr->ring + pi;
+ eqcr->vbit = (uint8_t)((qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
+ QM_EQCR_VERB_VBIT : 0);
+ eqcr->available = (uint8_t)(QM_EQCR_SIZE - 1 -
+ cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi));
+ eqcr->ithresh = (uint8_t)qm_in(EQCR_ITR);
+
+#ifdef QM_CHECKING
+ eqcr->busy = 0;
+ eqcr->pmode = pmode;
+ eqcr->cmode = cmode;
+#else
+ UNUSED(cmode);
+#endif /* QM_CHECKING */
+ cfg = (qm_in(CFG) & 0x00ffffff) |
+ ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
+ qm_out(CFG, cfg);
+ return 0;
+}
+
+static __inline__ void qm_eqcr_finish(struct qm_portal *portal)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ uint8_t pi = (uint8_t)(qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1));
+ uint8_t ci = (uint8_t)(qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1));
+
+#ifdef QM_CHECKING
+ ASSERT_COND(!eqcr->busy);
+#endif /* QM_CHECKING */
+ if (pi != EQCR_PTR2IDX(eqcr->cursor))
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("losing uncommitted EQCR entries"));
+ if (ci != eqcr->ci)
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("missing existing EQCR completions"));
+ if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("EQCR destroyed unquiesced"));
+ __qm_portal_unbind(portal, QM_BIND_EQCR);
+}
+
+static __inline__ struct qm_eqcr_entry *qm_eqcr_start(struct qm_portal *portal)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+#ifdef QM_CHECKING
+ ASSERT_COND(!eqcr->busy);
+#endif /* QM_CHECKING */
+ if (!eqcr->available)
+ return NULL;
+#ifdef QM_CHECKING
+ eqcr->busy = 1;
+#endif /* QM_CHECKING */
+ dcbz_64(eqcr->cursor);
+ return eqcr->cursor;
+}
+
+static __inline__ void qm_eqcr_abort(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ ASSERT_COND(eqcr->busy);
+ eqcr->busy = 0;
+#else
+ UNUSED(portal);
+#endif /* QM_CHECKING */
+}
+
+static __inline__ struct qm_eqcr_entry *qm_eqcr_pend_and_next(struct qm_portal *portal, uint8_t myverb)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+#ifdef QM_CHECKING
+ ASSERT_COND(eqcr->busy);
+ ASSERT_COND(eqcr->pmode != e_QmPortalPVB);
+#endif /* QM_CHECKING */
+ if (eqcr->available == 1)
+ return NULL;
+ eqcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | eqcr->vbit);
+ dcbf_64(eqcr->cursor);
+ EQCR_INC(eqcr);
+ eqcr->available--;
+ dcbz_64(eqcr->cursor);
+ return eqcr->cursor;
+}
+
+#ifdef QM_CHECKING
+#define EQCR_COMMIT_CHECKS(eqcr) \
+do { \
+ ASSERT_COND(eqcr->busy); \
+ ASSERT_COND(eqcr->cursor->orp == (eqcr->cursor->orp & 0x00ffffff)); \
+ ASSERT_COND(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0x00ffffff)); \
+} while(0)
+
+#else
+#define EQCR_COMMIT_CHECKS(eqcr)
+#endif /* QM_CHECKING */
+
+
+static __inline__ void qmPortalEqcrPciCommit(struct qm_portal *portal, uint8_t myverb)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+#ifdef QM_CHECKING
+ EQCR_COMMIT_CHECKS(eqcr);
+ ASSERT_COND(eqcr->pmode == e_QmPortalPCI);
+#endif /* QM_CHECKING */
+ eqcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | eqcr->vbit);
+ EQCR_INC(eqcr);
+ eqcr->available--;
+ dcbf_64(eqcr->cursor);
+ hwsync();
+ qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
+#ifdef QM_CHECKING
+ eqcr->busy = 0;
+#endif /* QM_CHECKING */
+}
+
+static __inline__ void qmPortalEqcrPcePrefetch(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ ASSERT_COND(eqcr->pmode == e_QmPortalPCE);
+#endif /* QM_CHECKING */
+ qm_cl_invalidate(EQCR_PI);
+ qm_cl_touch_rw(EQCR_PI);
+}
+
+static __inline__ void qmPortalEqcrPceCommit(struct qm_portal *portal, uint8_t myverb)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+#ifdef QM_CHECKING
+ EQCR_COMMIT_CHECKS(eqcr);
+ ASSERT_COND(eqcr->pmode == e_QmPortalPCE);
+#endif /* QM_CHECKING */
+ eqcr->cursor->__dont_write_directly__verb = (uint8_t)(myverb | eqcr->vbit);
+ EQCR_INC(eqcr);
+ eqcr->available--;
+ dcbf_64(eqcr->cursor);
+ lwsync();
+ qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
+#ifdef QM_CHECKING
+ eqcr->busy = 0;
+#endif /* QM_CHECKING */
+}
+
+static __inline__ void qmPortalEqcrPvbCommit(struct qm_portal *portal, uint8_t myverb)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ struct qm_eqcr_entry *eqcursor;
+#ifdef QM_CHECKING
+ EQCR_COMMIT_CHECKS(eqcr);
+ ASSERT_COND(eqcr->pmode == e_QmPortalPVB);
+#endif /* QM_CHECKING */
+ lwsync();
+ eqcursor = eqcr->cursor;
+ eqcursor->__dont_write_directly__verb = (uint8_t)(myverb | eqcr->vbit);
+ dcbf_64(eqcursor);
+ EQCR_INC(eqcr);
+ eqcr->available--;
+#ifdef QM_CHECKING
+ eqcr->busy = 0;
+#endif /* QM_CHECKING */
+}
+
+static __inline__ uint8_t qmPortalEqcrCciUpdate(struct qm_portal *portal)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ uint8_t diff, old_ci = eqcr->ci;
+#ifdef QM_CHECKING
+ ASSERT_COND(eqcr->cmode == e_QmPortalEqcrCCI);
+#endif /* QM_CHECKING */
+ eqcr->ci = (uint8_t)(qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1));
+ diff = cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
+ eqcr->available += diff;
+ return diff;
+}
+
+static __inline__ void qmPortalEqcrCcePrefetch(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ ASSERT_COND(eqcr->cmode == e_QmPortalEqcrCCE);
+#endif /* QM_CHECKING */
+ qm_cl_touch_ro(EQCR_CI);
+}
+
+static __inline__ uint8_t qmPortalEqcrCceUpdate(struct qm_portal *portal)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ uint8_t diff, old_ci = eqcr->ci;
+#ifdef QM_CHECKING
+ ASSERT_COND(eqcr->cmode == e_QmPortalEqcrCCE);
+#endif /* QM_CHECKING */
+ eqcr->ci = (uint8_t)(qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1));
+ qm_cl_invalidate(EQCR_CI);
+ diff = cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
+ eqcr->available += diff;
+ return diff;
+}
+
+static __inline__ uint8_t qm_eqcr_get_ithresh(struct qm_portal *portal)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ return eqcr->ithresh;
+}
+
+static __inline__ void qm_eqcr_set_ithresh(struct qm_portal *portal, uint8_t ithresh)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ eqcr->ithresh = ithresh;
+ qm_out(EQCR_ITR, ithresh);
+}
+
+static __inline__ uint8_t qm_eqcr_get_avail(struct qm_portal *portal)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ return eqcr->available;
+}
+
+static __inline__ uint8_t qm_eqcr_get_fill(struct qm_portal *portal)
+{
+ register struct qm_eqcr *eqcr = &portal->eqcr;
+ return (uint8_t)(QM_EQCR_SIZE - 1 - eqcr->available);
+}
+
+
+
+/* ---------------- */
+/* --- DQRR API --- */
+
+/* TODO: many possible improvements;
+ * - look at changing the API to use pointer rather than index parameters now
+ * that 'cursor' is a pointer,
+ * - consider moving other parameters to pointer if it could help (ci)
+ */
+
+/* It's safer to code in terms of the 'dqrr' object than the 'portal' object,
+ * because the latter runs the risk of copy-n-paste errors from other code where
+ * we could manipulate some other structure within 'portal'. */
+/* #define DQRR_API_START() register struct qm_dqrr *dqrr = &portal->dqrr */
+
+#define DQRR_CARRYCLEAR(p) \
+ (void *)((uintptr_t)(p) & (~(uintptr_t)(QM_DQRR_SIZE << 6)))
+
+static __inline__ uint8_t DQRR_PTR2IDX(struct qm_dqrr_entry *e)
+{
+ return (uint8_t)(((uint32_t)e >> 6) & (QM_DQRR_SIZE - 1));
+}
+
+static __inline__ struct qm_dqrr_entry *DQRR_INC(struct qm_dqrr_entry *e)
+{
+ return DQRR_CARRYCLEAR(e + 1);
+}
+
+static __inline__ void qm_dqrr_set_maxfill(struct qm_portal *portal, uint8_t mf)
+{
+ qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
+ ((mf & (QM_DQRR_SIZE - 1)) << 20));
+}
+
+static __inline__ t_Error qm_dqrr_init(struct qm_portal *portal, e_QmPortalDequeueMode dmode,
+ e_QmPortalProduceMode pmode, e_QmPortalDqrrConsumeMode cmode,
+ uint8_t max_fill, int stash_ring, int stash_data)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ const struct qm_portal_config *config = &portal->config;
+ uint32_t cfg;
+
+ if (__qm_portal_bind(portal, QM_BIND_DQRR))
+ return ERROR_CODE(E_BUSY);
+ if ((stash_ring || stash_data) && (config->cpu == -1))
+ return ERROR_CODE(E_INVALID_STATE);
+ /* Make sure the DQRR will be idle when we enable */
+ qm_out(DQRR_SDQCR, 0);
+ qm_out(DQRR_VDQCR, 0);
+ qm_out(DQRR_PDQCR, 0);
+ dqrr->ring = ptr_ADD(portal->addr.addr_ce, CL_DQRR);
+ dqrr->pi = (uint8_t)(qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1));
+ dqrr->ci = (uint8_t)(qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1));
+ dqrr->cursor = dqrr->ring + dqrr->ci;
+ dqrr->fill = cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
+ dqrr->vbit = (uint8_t)((qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
+ QM_DQRR_VERB_VBIT : 0);
+ dqrr->ithresh = (uint8_t)qm_in(DQRR_ITR);
+
+#ifdef QM_CHECKING
+ dqrr->dmode = dmode;
+ dqrr->pmode = pmode;
+ dqrr->cmode = cmode;
+ dqrr->flags = 0;
+ if (stash_ring)
+ dqrr->flags |= QM_DQRR_FLAG_RE;
+ if (stash_data)
+ dqrr->flags |= QM_DQRR_FLAG_SE;
+#else
+ UNUSED(pmode);
+#endif /* QM_CHECKING */
+
+ cfg = (qm_in(CFG) & 0xff000f00) |
+ ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
+ ((dmode & 1) << 18) | /* DP */
+ ((cmode & 3) << 16) | /* DCM */
+ (stash_ring ? 0x80 : 0) | /* RE */
+ (0 ? 0x40 : 0) | /* Ignore RP */
+ (stash_data ? 0x20 : 0) | /* SE */
+ (0 ? 0x10 : 0); /* Ignore SP */
+ qm_out(CFG, cfg);
+ return E_OK;
+}
+
+
+static __inline__ void qm_dqrr_finish(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ if (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor))
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("Ignoring completed DQRR entries"));
+ __qm_portal_unbind(portal, QM_BIND_DQRR);
+}
+
+static __inline__ struct qm_dqrr_entry *qm_dqrr_current(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ if (!dqrr->fill)
+ return NULL;
+ return dqrr->cursor;
+}
+
+static __inline__ uint8_t qm_dqrr_cursor(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ return DQRR_PTR2IDX(dqrr->cursor);
+}
+
+static __inline__ uint8_t qm_dqrr_next(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->fill);
+#endif
+ dqrr->cursor = DQRR_INC(dqrr->cursor);
+ return --dqrr->fill;
+}
+
+static __inline__ uint8_t qmPortalDqrrPciUpdate(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ uint8_t diff, old_pi = dqrr->pi;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->pmode == e_QmPortalPCI);
+#endif /* QM_CHECKING */
+ dqrr->pi = (uint8_t)(qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1));
+ diff = cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
+ dqrr->fill += diff;
+ return diff;
+}
+
+static __inline__ void qmPortalDqrrPcePrefetch(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->pmode == e_QmPortalPCE);
+#endif /* QM_CHECKING */
+ qm_cl_invalidate(DQRR_PI);
+ qm_cl_touch_ro(DQRR_PI);
+}
+
+static __inline__ uint8_t qmPortalDqrrPceUpdate(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ uint8_t diff, old_pi = dqrr->pi;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->pmode == e_QmPortalPCE);
+#endif /* QM_CHECKING */
+ dqrr->pi = (uint8_t)(qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1));
+ diff = cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
+ dqrr->fill += diff;
+ return diff;
+}
+
+static __inline__ void qmPortalDqrrPvbPrefetch(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->pmode == e_QmPortalPVB);
+ /* If ring entries get stashed, don't invalidate/prefetch */
+ if (!(dqrr->flags & QM_DQRR_FLAG_RE))
+#endif /*QM_CHECKING */
+ dcbit_ro(ptr_ADD(dqrr->ring, qm_cl(dqrr->pi)));
+}
+
+static __inline__ uint8_t qmPortalDqrrPvbUpdate(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ struct qm_dqrr_entry *res = ptr_ADD(dqrr->ring, qm_cl(dqrr->pi));
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->pmode == e_QmPortalPVB);
+#endif /* QM_CHECKING */
+ if ((res->verb & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
+ dqrr->pi = (uint8_t)((dqrr->pi + 1) & (QM_DQRR_SIZE - 1));
+ if (!dqrr->pi)
+ dqrr->vbit ^= QM_DQRR_VERB_VBIT;
+ dqrr->fill++;
+ return 1;
+ }
+ return 0;
+}
+
+static __inline__ void qmPortalDqrrCciConsume(struct qm_portal *portal, uint8_t num)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrCCI);
+#endif /* QM_CHECKING */
+ dqrr->ci = (uint8_t)((dqrr->ci + num) & (QM_DQRR_SIZE - 1));
+ qm_out(DQRR_CI_CINH, dqrr->ci);
+}
+
+static __inline__ void qmPortalDqrrCciConsumeToCurrent(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrCCI);
+#endif /* QM_CHECKING */
+ dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
+ qm_out(DQRR_CI_CINH, dqrr->ci);
+}
+
+static __inline__ void qmPortalDqrrCcePrefetch(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrCCE);
+#endif /* QM_CHECKING */
+ qm_cl_invalidate(DQRR_CI);
+ qm_cl_touch_rw(DQRR_CI);
+}
+
+static __inline__ void qmPortalDqrrCceConsume(struct qm_portal *portal, uint8_t num)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrCCE);
+#endif /* QM_CHECKING */
+ dqrr->ci = (uint8_t)((dqrr->ci + num) & (QM_DQRR_SIZE - 1));
+ qm_cl_out(DQRR_CI, dqrr->ci);
+}
+
+static __inline__ void qmPortalDqrrCceConsume_to_current(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrCCE);
+#endif /* QM_CHECKING */
+ dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
+ qm_cl_out(DQRR_CI, dqrr->ci);
+}
+
+static __inline__ void qmPortalDqrrDcaConsume1(struct qm_portal *portal, uint8_t idx, bool park)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+ ASSERT_COND(idx < QM_DQRR_SIZE);
+ qm_out(DQRR_DCAP, (0 << 8) | /* S */
+ ((uint32_t)(park ? 1 : 0) << 6) | /* PK */
+ idx); /* DCAP_CI */
+}
+
+static __inline__ void qmPortalDqrrDcaConsume1ptr(struct qm_portal *portal,
+ struct qm_dqrr_entry *dq,
+ bool park)
+{
+ uint8_t idx = DQRR_PTR2IDX(dq);
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrDCA);
+ ASSERT_COND((dqrr->ring + idx) == dq);
+ ASSERT_COND(idx < QM_DQRR_SIZE);
+#endif /* QM_CHECKING */
+ qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
+ ((uint32_t)(park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
+ idx); /* DQRR_DCAP::DCAP_CI */
+}
+
+static __inline__ void qmPortalDqrrDcaConsumeN(struct qm_portal *portal, uint16_t bitmask)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+ qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
+ ((uint32_t)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
+}
+
+static __inline__ uint8_t qmPortalDqrrDcaCci(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+ return (uint8_t)(qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1));
+}
+
+static __inline__ void qmPortalDqrrDcaCcePrefetch(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+ qm_cl_invalidate(DQRR_CI);
+ qm_cl_touch_ro(DQRR_CI);
+}
+
+static __inline__ uint8_t qmPortalDqrrDcaCce(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->cmode == e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+ return (uint8_t)(qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1));
+}
+
+static __inline__ uint8_t qm_dqrr_get_ci(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->cmode != e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+
+ return dqrr->ci;
+}
+
+static __inline__ void qm_dqrr_park(struct qm_portal *portal, uint8_t idx)
+{
+#ifdef QM_CHECKING
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ ASSERT_COND(dqrr->cmode != e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+
+ qm_out(DQRR_DCAP, (0 << 8) | /* S */
+ (uint32_t)(1 << 6) | /* PK */
+ (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
+}
+
+static __inline__ void qm_dqrr_park_ci(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+#ifdef QM_CHECKING
+ ASSERT_COND(dqrr->cmode != e_QmPortalDqrrDCA);
+#endif /* QM_CHECKING */
+ qm_out(DQRR_DCAP, (0 << 8) | /* S */
+ (uint32_t)(1 << 6) | /* PK */
+ (dqrr->ci & (QM_DQRR_SIZE - 1)));/* DCAP_CI */
+}
+
+static __inline__ void qm_dqrr_sdqcr_set(struct qm_portal *portal, uint32_t sdqcr)
+{
+ qm_out(DQRR_SDQCR, sdqcr);
+}
+
+static __inline__ uint32_t qm_dqrr_sdqcr_get(struct qm_portal *portal)
+{
+ return qm_in(DQRR_SDQCR);
+}
+
+static __inline__ void qm_dqrr_vdqcr_set(struct qm_portal *portal, uint32_t vdqcr)
+{
+ qm_out(DQRR_VDQCR, vdqcr);
+}
+
+static __inline__ uint32_t qm_dqrr_vdqcr_get(struct qm_portal *portal)
+{
+ return qm_in(DQRR_VDQCR);
+}
+
+static __inline__ void qm_dqrr_pdqcr_set(struct qm_portal *portal, uint32_t pdqcr)
+{
+ qm_out(DQRR_PDQCR, pdqcr);
+}
+
+static __inline__ uint32_t qm_dqrr_pdqcr_get(struct qm_portal *portal)
+{
+ return qm_in(DQRR_PDQCR);
+}
+
+static __inline__ uint8_t qm_dqrr_get_ithresh(struct qm_portal *portal)
+{
+ register struct qm_dqrr *dqrr = &portal->dqrr;
+ return dqrr->ithresh;
+}
+
+static __inline__ void qm_dqrr_set_ithresh(struct qm_portal *portal, uint8_t ithresh)
+{
+ qm_out(DQRR_ITR, ithresh);
+}
+
+static __inline__ uint8_t qm_dqrr_get_maxfill(struct qm_portal *portal)
+{
+ return (uint8_t)((qm_in(CFG) & 0x00f00000) >> 20);
+}
+
+/* -------------- */
+/* --- MR API --- */
+
+/* It's safer to code in terms of the 'mr' object than the 'portal' object,
+ * because the latter runs the risk of copy-n-paste errors from other code where
+ * we could manipulate some other structure within 'portal'. */
+/* #define MR_API_START() register struct qm_mr *mr = &portal->mr */
+
+#define MR_CARRYCLEAR(p) \
+ (void *)((uintptr_t)(p) & (~(uintptr_t)(QM_MR_SIZE << 6)))
+
+static __inline__ uint8_t MR_PTR2IDX(struct qm_mr_entry *e)
+{
+ return (uint8_t)(((uint32_t)e >> 6) & (QM_MR_SIZE - 1));
+}
+
+static __inline__ struct qm_mr_entry *MR_INC(struct qm_mr_entry *e)
+{
+ return MR_CARRYCLEAR(e + 1);
+}
+
+static __inline__ t_Error qm_mr_init(struct qm_portal *portal, e_QmPortalProduceMode pmode,
+ e_QmPortalMrConsumeMode cmode)
+{
+ register struct qm_mr *mr = &portal->mr;
+ uint32_t cfg;
+
+ if (__qm_portal_bind(portal, QM_BIND_MR))
+ return ERROR_CODE(E_BUSY);
+ mr->ring = ptr_ADD(portal->addr.addr_ce, CL_MR);
+ mr->pi = (uint8_t)(qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1));
+ mr->ci = (uint8_t)(qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1));
+ mr->cursor = mr->ring + mr->ci;
+ mr->fill = cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
+ mr->vbit = (uint8_t)((qm_in(MR_PI_CINH) & QM_MR_SIZE) ?QM_MR_VERB_VBIT : 0);
+ mr->ithresh = (uint8_t)qm_in(MR_ITR);
+
+#ifdef QM_CHECKING
+ mr->pmode = pmode;
+ mr->cmode = cmode;
+#else
+ UNUSED(pmode);
+#endif /* QM_CHECKING */
+ cfg = (qm_in(CFG) & 0xfffff0ff) |
+ ((cmode & 1) << 8); /* QCSP_CFG:MM */
+ qm_out(CFG, cfg);
+ return E_OK;
+}
+
+
+static __inline__ void qm_mr_finish(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ if (mr->ci != MR_PTR2IDX(mr->cursor))
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("Ignoring completed MR entries"));
+ __qm_portal_unbind(portal, QM_BIND_MR);
+}
+
+static __inline__ void qm_mr_current_prefetch(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ dcbt_ro(mr->cursor);
+}
+
+static __inline__ struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ if (!mr->fill)
+ return NULL;
+ return mr->cursor;
+}
+
+static __inline__ uint8_t qm_mr_cursor(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ return MR_PTR2IDX(mr->cursor);
+}
+
+static __inline__ uint8_t qm_mr_next(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->fill);
+#endif /* QM_CHECKING */
+ mr->cursor = MR_INC(mr->cursor);
+ return --mr->fill;
+}
+
+static __inline__ uint8_t qmPortalMrPciUpdate(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ uint8_t diff, old_pi = mr->pi;
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->pmode == e_QmPortalPCI);
+#endif /* QM_CHECKING */
+ mr->pi = (uint8_t)qm_in(MR_PI_CINH);
+ diff = cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
+ mr->fill += diff;
+ return diff;
+}
+
+static __inline__ void qmPortalMrPcePrefetch(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_mr *mr = &portal->mr;
+ ASSERT_COND(mr->pmode == e_QmPortalPCE);
+#endif /* QM_CHECKING */
+ qm_cl_invalidate(MR_PI);
+ qm_cl_touch_ro(MR_PI);
+}
+
+static __inline__ uint8_t qmPortalMrPceUpdate(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ uint8_t diff, old_pi = mr->pi;
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->pmode == e_QmPortalPCE);
+#endif /* QM_CHECKING */
+ mr->pi = (uint8_t)(qm_cl_in(MR_PI) & (QM_MR_SIZE - 1));
+ diff = cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
+ mr->fill += diff;
+ return diff;
+}
+
+static __inline__ void qmPortalMrPvbUpdate(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ struct qm_mr_entry *res = ptr_ADD(mr->ring, qm_cl(mr->pi));
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->pmode == e_QmPortalPVB);
+#endif /* QM_CHECKING */
+ dcbit_ro(ptr_ADD(mr->ring, qm_cl(mr->pi)));
+ if ((res->verb & QM_MR_VERB_VBIT) == mr->vbit) {
+ mr->pi = (uint8_t)((mr->pi + 1) & (QM_MR_SIZE - 1));
+ if (!mr->pi)
+ mr->vbit ^= QM_MR_VERB_VBIT;
+ mr->fill++;
+ }
+}
+
+static __inline__ void qmPortalMrCciConsume(struct qm_portal *portal, uint8_t num)
+{
+ register struct qm_mr *mr = &portal->mr;
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->cmode == e_QmPortalMrCCI);
+#endif /* QM_CHECKING */
+ mr->ci = (uint8_t)((mr->ci + num) & (QM_MR_SIZE - 1));
+ qm_out(MR_CI_CINH, mr->ci);
+}
+
+static __inline__ void qmPortalMrCciConsumeToCurrent(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->cmode == e_QmPortalMrCCI);
+#endif /* QM_CHECKING */
+ mr->ci = MR_PTR2IDX(mr->cursor);
+ qm_out(MR_CI_CINH, mr->ci);
+}
+
+static __inline__ void qmPortalMrCcePrefetch(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_mr *mr = &portal->mr;
+ ASSERT_COND(mr->cmode == e_QmPortalMrCCE);
+#endif /* QM_CHECKING */
+ qm_cl_invalidate(MR_CI);
+ qm_cl_touch_rw(MR_CI);
+}
+
+static __inline__ void qmPortalMrCceConsume(struct qm_portal *portal, uint8_t num)
+{
+ register struct qm_mr *mr = &portal->mr;
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->cmode == e_QmPortalMrCCE);
+#endif /* QM_CHECKING */
+ mr->ci = (uint8_t)((mr->ci + num) & (QM_MR_SIZE - 1));
+ qm_cl_out(MR_CI, mr->ci);
+}
+
+static __inline__ void qmPortalMrCceConsumeToCurrent(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+#ifdef QM_CHECKING
+ ASSERT_COND(mr->cmode == e_QmPortalMrCCE);
+#endif /* QM_CHECKING */
+ mr->ci = MR_PTR2IDX(mr->cursor);
+ qm_cl_out(MR_CI, mr->ci);
+}
+
+static __inline__ uint8_t qm_mr_get_ci(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ return mr->ci;
+}
+
+static __inline__ uint8_t qm_mr_get_ithresh(struct qm_portal *portal)
+{
+ register struct qm_mr *mr = &portal->mr;
+ return mr->ithresh;
+}
+
+static __inline__ void qm_mr_set_ithresh(struct qm_portal *portal, uint8_t ithresh)
+{
+ qm_out(MR_ITR, ithresh);
+}
+
+/* ------------------------------ */
+/* --- Management command API --- */
+
+/* It's safer to code in terms of the 'mc' object than the 'portal' object,
+ * because the latter runs the risk of copy-n-paste errors from other code where
+ * we could manipulate some other structure within 'portal'. */
+/* #define MC_API_START() register struct qm_mc *mc = &portal->mc */
+
+static __inline__ t_Error qm_mc_init(struct qm_portal *portal)
+{
+ register struct qm_mc *mc = &portal->mc;
+ if (__qm_portal_bind(portal, QM_BIND_MC))
+ return ERROR_CODE(E_BUSY);
+ mc->cr = ptr_ADD(portal->addr.addr_ce, CL_CR);
+ mc->rr = ptr_ADD(portal->addr.addr_ce, CL_RR0);
+ mc->rridx = (uint8_t)((mc->cr->__dont_write_directly__verb & QM_MCC_VERB_VBIT) ?
+ 0 : 1);
+ mc->vbit = (uint8_t)(mc->rridx ? QM_MCC_VERB_VBIT : 0);
+#ifdef QM_CHECKING
+ mc->state = mc_idle;
+#endif /* QM_CHECKING */
+ return E_OK;
+}
+
+static __inline__ void qm_mc_finish(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_mc *mc = &portal->mc;
+ ASSERT_COND(mc->state == mc_idle);
+ if (mc->state != mc_idle)
+ REPORT_ERROR(WARNING, E_INVALID_STATE, ("Losing incomplete MC command"));
+#endif /* QM_CHECKING */
+ __qm_portal_unbind(portal, QM_BIND_MC);
+}
+
+static __inline__ struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
+{
+ register struct qm_mc *mc = &portal->mc;
+#ifdef QM_CHECKING
+ ASSERT_COND(mc->state == mc_idle);
+ mc->state = mc_user;
+#endif /* QM_CHECKING */
+ dcbz_64(mc->cr);
+ return mc->cr;
+}
+
+static __inline__ void qm_mc_abort(struct qm_portal *portal)
+{
+#ifdef QM_CHECKING
+ register struct qm_mc *mc = &portal->mc;
+ ASSERT_COND(mc->state == mc_user);
+ mc->state = mc_idle;
+#else
+ UNUSED(portal);
+#endif /* QM_CHECKING */
+}
+
+static __inline__ void qm_mc_commit(struct qm_portal *portal, uint8_t myverb)
+{
+ register struct qm_mc *mc = &portal->mc;
+#ifdef QM_CHECKING
+ ASSERT_COND(mc->state == mc_user);
+#endif /* QM_CHECKING */
+ lwsync();
+ mc->cr->__dont_write_directly__verb = (uint8_t)(myverb | mc->vbit);
+ dcbf_64(mc->cr);
+ dcbit_ro(mc->rr + mc->rridx);
+#ifdef QM_CHECKING
+ mc->state = mc_hw;
+#endif /* QM_CHECKING */
+}
+
+static __inline__ struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
+{
+ register struct qm_mc *mc = &portal->mc;
+ struct qm_mc_result *rr = mc->rr + mc->rridx;
+#ifdef QM_CHECKING
+ ASSERT_COND(mc->state == mc_hw);
+#endif /* QM_CHECKING */
+ /* The inactive response register's verb byte always returns zero until
+ * its command is submitted and completed. This includes the valid-bit,
+ * in case you were wondering... */
+ if (!rr->verb) {
+ dcbit_ro(rr);
+ return NULL;
+ }
+ mc->rridx ^= 1;
+ mc->vbit ^= QM_MCC_VERB_VBIT;
+#ifdef QM_CHECKING
+ mc->state = mc_idle;
+#endif /* QM_CHECKING */
+ return rr;
+}
+
+/* ------------------------------------- */
+/* --- Portal interrupt register API --- */
+
+static __inline__ t_Error qm_isr_init(struct qm_portal *portal)
+{
+ if (__qm_portal_bind(portal, QM_BIND_ISR))
+ return ERROR_CODE(E_BUSY);
+ return E_OK;
+}
+
+static __inline__ void qm_isr_finish(struct qm_portal *portal)
+{
+ __qm_portal_unbind(portal, QM_BIND_ISR);
+}
+
+static __inline__ void qm_isr_set_iperiod(struct qm_portal *portal, uint16_t iperiod)
+{
+ qm_out(ITPR, iperiod);
+}
+
+static __inline__ uint32_t __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
+{
+ return __qm_in(&portal->addr, PTR_MOVE(REG_ISR, (n << 2)));
+}
+
+static __inline__ void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n, uint32_t val)
+{
+ __qm_out(&portal->addr, PTR_MOVE(REG_ISR, (n << 2)), val);
+}
diff --git a/sys/contrib/ncsw/Peripherals/QM/qman_private.h b/sys/contrib/ncsw/Peripherals/QM/qman_private.h
new file mode 100644
index 0000000..5bab418
--- /dev/null
+++ b/sys/contrib/ncsw/Peripherals/QM/qman_private.h
@@ -0,0 +1,285 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File qman_private.h
+
+ @Description QM private header
+*//***************************************************************************/
+#ifndef __QMAN_PRIVATE_H
+#define __QMAN_PRIVATE_H
+
+#include "fsl_qman.h"
+
+
+#define __ERR_MODULE__ MODULE_QM
+
+#if defined(DEBUG) || !defined(DISABLE_ASSERTIONS)
+/* Optionally compile-in assertion-checking */
+#define QM_CHECKING
+#endif /* defined(DEBUG) || ... */
+
+/* TODO: NB, we currently assume that CORE_MemoryBarier() and lwsync() imply compiler barriers
+ * and that dcbzl(), dcbfl(), and dcbi() won't fall victim to compiler or
+ * execution reordering with respect to other code/instructions that manipulate
+ * the same cacheline. */
+#ifdef CORE_E500MC
+
+#if defined(_DIAB_TOOL)
+#define hwsync() \
+do { \
+__asm__ __volatile__ ("sync"); \
+} while(0)
+
+#define lwsync() \
+do { \
+__asm__ __volatile__ ("lwsync"); \
+} while(0)
+
+__asm__ __volatile__ void dcbf (volatile void * addr)
+{
+%reg addr
+ dcbf r0, addr
+}
+
+__asm__ __volatile__ void dcbt_ro (volatile void * addr)
+{
+%reg addr
+ dcbt r0, addr
+}
+
+__asm__ __volatile__ void dcbt_rw (volatile void * addr)
+{
+%reg addr
+ dcbtst r0, addr
+}
+
+__asm__ __volatile__ void dcbzl (volatile void * addr)
+{
+%reg addr
+ dcbzl r0, addr
+}
+
+#define dcbz_64(p) \
+ do { \
+ dcbzl(p); \
+ } while (0)
+
+#define dcbf_64(p) \
+ do { \
+ dcbf(p); \
+ } while (0)
+
+/* Commonly used combo */
+#define dcbit_ro(p) \
+ do { \
+ dcbi(p); \
+ dcbt_ro(p); \
+ } while (0)
+
+#else /* GNU C */
+#define hwsync() \
+ do { \
+ __asm__ __volatile__ ("sync" : : : "memory"); \
+ } while(0)
+
+#define lwsync() \
+ do { \
+ __asm__ __volatile__ ("lwsync" : : : "memory"); \
+ } while(0)
+
+#define dcbf(addr) \
+ do { \
+ __asm__ __volatile__ ("dcbf 0, %0" : : "r" (addr)); \
+ } while(0)
+
+#define dcbt_ro(addr) \
+ do { \
+ __asm__ __volatile__ ("dcbt 0, %0" : : "r" (addr)); \
+ } while(0)
+
+#define dcbt_rw(addr) \
+ do { \
+ __asm__ __volatile__ ("dcbtst 0, %0" : : "r" (addr)); \
+ } while(0)
+
+#define dcbzl(p) \
+ do { \
+ __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p)); \
+ } while(0)
+
+#define dcbz_64(p) \
+ do { \
+ dcbzl(p); \
+ } while (0)
+
+#define dcbf_64(p) \
+ do { \
+ dcbf(p); \
+ } while (0)
+
+/* Commonly used combo */
+#define dcbit_ro(p) \
+ do { \
+ dcbi(p); \
+ dcbt_ro(p); \
+ } while (0)
+
+#endif /* _DIAB_TOOL */
+
+#else
+#define hwsync CORE_MemoryBarrier
+#define lwsync hwsync
+
+#define dcbf(p) \
+ do { \
+ __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p)); \
+ } while(0)
+#define dcbt_ro(p) \
+ do { \
+ __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p)); \
+ lwsync(); \
+ } while(0)
+#define dcbt_rw(p) \
+ do { \
+ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p)); \
+ } while(0)
+#define dcbz(p) \
+ do { \
+ __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p)); \
+ } while (0)
+#define dcbz_64(p) \
+ do { \
+ dcbz((uint32_t)p + 32); \
+ dcbz(p); \
+ } while (0)
+#define dcbf_64(p) \
+ do { \
+ dcbf((uint32_t)p + 32); \
+ dcbf(p); \
+ } while (0)
+/* Commonly used combo */
+#define dcbit_ro(p) \
+ do { \
+ dcbi(p); \
+ dcbi((uint32_t)p + 32); \
+ dcbt_ro(p); \
+ dcbt_ro((uint32_t)p + 32); \
+ } while (0)
+
+#endif /* CORE_E500MC */
+
+#define dcbi(p) dcbf(p)
+
+struct qm_addr {
+ void *addr_ce; /* cache-enabled */
+ void *addr_ci; /* cache-inhibited */
+};
+
+/* EQCR state */
+struct qm_eqcr {
+ struct qm_eqcr_entry *ring, *cursor;
+ uint8_t ci, available, ithresh, vbit;
+
+#ifdef QM_CHECKING
+ uint32_t busy;
+ e_QmPortalProduceMode pmode;
+ e_QmPortalEqcrConsumeMode cmode;
+#endif /* QM_CHECKING */
+};
+
+/* DQRR state */
+struct qm_dqrr {
+ struct qm_dqrr_entry *ring, *cursor;
+ uint8_t pi, ci, fill, ithresh, vbit, flags;
+
+#ifdef QM_CHECKING
+ e_QmPortalDequeueMode dmode;
+ e_QmPortalProduceMode pmode;
+ e_QmPortalDqrrConsumeMode cmode;
+#endif /* QM_CHECKING */
+};
+#define QM_DQRR_FLAG_RE 0x01 /* Stash ring entries */
+#define QM_DQRR_FLAG_SE 0x02 /* Stash data */
+
+/* MR state */
+struct qm_mr {
+ struct qm_mr_entry *ring, *cursor;
+ uint8_t pi, ci, fill, ithresh, vbit;
+
+#ifdef QM_CHECKING
+ e_QmPortalProduceMode pmode;
+ e_QmPortalMrConsumeMode cmode;
+#endif /* QM_CHECKING */
+};
+
+/* MC state */
+struct qm_mc {
+ struct qm_mc_command *cr;
+ struct qm_mc_result *rr;
+ uint8_t rridx, vbit;
+#ifdef QM_CHECKING
+ enum {
+ /* Can be _mc_start()ed */
+ mc_idle,
+ /* Can be _mc_commit()ed or _mc_abort()ed */
+ mc_user,
+ /* Can only be _mc_retry()ed */
+ mc_hw
+ } state;
+#endif /* QM_CHECKING */
+};
+
+/********************/
+/* Portal structure */
+/********************/
+
+struct qm_portal {
+ /* In the non-QM_CHECKING case, everything up to and
+ * including 'mc' fits in a cacheline (yay!). The 'config' part is setup-only, so isn't a
+ * cause for a concern. In other words, don't rearrange this structure
+ * on a whim, there be dragons ... */
+ struct qm_addr addr;
+ struct qm_eqcr eqcr;
+ struct qm_dqrr dqrr;
+ struct qm_mr mr;
+ struct qm_mc mc;
+ struct qm_portal_config config;
+ t_Handle bind_lock;
+ /* Logical index (not cell-index) */
+ int index;
+};
+
+#endif /* __QMAN_PRIVATE_H */
diff --git a/sys/contrib/ncsw/build/dflags.h b/sys/contrib/ncsw/build/dflags.h
new file mode 100644
index 0000000..bddd743
--- /dev/null
+++ b/sys/contrib/ncsw/build/dflags.h
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2011 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef DFLAGS_H_
+#define DFLAGS_H_
+
+#include "opt_platform.h"
+#include "events_mapping.h"
+
+#if defined(P3041DS)
+#define P3041
+#elif defined(P2041RDB)
+#define P2041
+#elif defined(P5020DS)
+#define P5020
+#else
+#define P5020
+#endif
+
+#define NCSW_PPC_CORE
+#define NCSW_FREEBSD
+
+/* Debugging */
+#define DEBUG_ERRORS 1
+#define DPAA_DEBUG 1
+#if defined(DPAA_DEBUG)
+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
+
+#else
+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
+#endif
+
+/* Events */
+#define REPORT_EVENTS 1
+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
+
+#endif /* DFLAGS_H_ */
diff --git a/sys/contrib/ncsw/build/events_mapping.h b/sys/contrib/ncsw/build/events_mapping.h
new file mode 100644
index 0000000..713b2f1
--- /dev/null
+++ b/sys/contrib/ncsw/build/events_mapping.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef EVENTS_MAPPING_H_
+#define EVENTS_MAPPING_H_
+
+#define EV_RX_DISCARD_LEVEL REPORT_LEVEL_MINOR
+#define EV_RX_ERROR_LEVEL REPORT_LEVEL_MINOR
+#define EV_TX_ERROR_LEVEL REPORT_LEVEL_MINOR
+#define EV_NO_BUFFERS_LEVEL REPORT_LEVEL_MAJOR
+#define EV_NO_MB_FRAMES_LEVEL REPORT_LEVEL_MAJOR
+#define EV_NO_SB_FRAMES_LEVEL REPORT_LEVEL_MAJOR
+#define EV_TX_QUEUE_FULL_LEVEL REPORT_LEVEL_MINOR
+#define EV_RX_QUEUE_FULL_LEVEL REPORT_LEVEL_MAJOR
+#define EV_INTR_QUEUE_FULL_LEVEL REPORT_LEVEL_MINOR
+#define EV_NO_DATA_BUFFER_LEVEL REPORT_LEVEL_MAJOR
+#define EV_OBJ_POOL_EMPTY_LEVEL REPORT_LEVEL_MAJOR
+#define EV_BUS_ERROR_LEVEL REPORT_LEVEL_CRITICAL
+#define EV_PTP_TXTS_QUEUE_FULL_LEVEL REPORT_LEVEL_MAJOR
+#define EV_PTP_RXTS_QUEUE_FULL_LEVEL REPORT_LEVEL_MAJOR
+
+
+#endif /* EVENTS_MAPPING_H_ */
+
diff --git a/sys/contrib/ncsw/etc/error.c b/sys/contrib/ncsw/etc/error.c
new file mode 100644
index 0000000..896722f
--- /dev/null
+++ b/sys/contrib/ncsw/etc/error.c
@@ -0,0 +1,118 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+
+ @File error.c
+
+ @Description General errors and events reporting utilities.
+*//***************************************************************************/
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+
+const char *dbgLevelStrings[] =
+{
+ "CRITICAL"
+ ,"MAJOR"
+ ,"MINOR"
+ ,"WARNING"
+ ,"INFO"
+ ,"TRACE"
+};
+
+const char *errTypeStrings[] =
+{
+ "Invalid State" /* E_INVALID_STATE */
+ ,"Invalid Operation" /* E_INVALID_OPERATION */
+ ,"Unsupported Operation" /* E_NOT_SUPPORTED */
+ ,"No Device" /* E_NO_DEVICE */
+ ,"Invalid Handle" /* E_INVALID_HANDLE */
+ ,"Invalid ID" /* E_INVALID_ID */
+ ,"Unexpected NULL Pointer" /* E_NULL_POINTER */
+ ,"Invalid Value" /* E_INVALID_VALUE */
+ ,"Invalid Selection" /* E_INVALID_SELECTION */
+ ,"Invalid Communication Mode" /* E_INVALID_COMM_MODE */
+ ,"Invalid Byte Order" /* E_INVALID_BYTE_ORDER */
+ ,"Invalid Memory Type" /* E_INVALID_MEMORY_TYPE */
+ ,"Invalid Interrupt Queue" /* E_INVALID_INTR_QUEUE */
+ ,"Invalid Priority" /* E_INVALID_PRIORITY */
+ ,"Invalid Clock" /* E_INVALID_CLOCK */
+ ,"Invalid Rate" /* E_INVALID_RATE */
+ ,"Invalid Address" /* E_INVALID_ADDRESS */
+ ,"Invalid Bus" /* E_INVALID_BUS */
+ ,"Conflict In Bus Selection" /* E_BUS_CONFLICT */
+ ,"Conflict In Settings" /* E_CONFLICT */
+ ,"Incorrect Alignment" /* E_NOT_ALIGNED */
+ ,"Value Out Of Range" /* E_NOT_IN_RANGE */
+ ,"Invalid Frame" /* E_INVALID_FRAME */
+ ,"Frame Is Empty" /* E_EMPTY_FRAME */
+ ,"Buffer Is Empty" /* E_EMPTY_BUFFER */
+ ,"Memory Allocation Failed" /* E_NO_MEMORY */
+ ,"Resource Not Found" /* E_NOT_FOUND */
+ ,"Resource Is Unavailable" /* E_NOT_AVAILABLE */
+ ,"Resource Already Exists" /* E_ALREADY_EXISTS */
+ ,"Resource Is Full" /* E_FULL */
+ ,"Resource Is Empty" /* E_EMPTY */
+ ,"Resource Is Busy" /* E_BUSY */
+ ,"Resource Already Free" /* E_ALREADY_FREE */
+ ,"Read Access Failed" /* E_READ_FAILED */
+ ,"Write Access Failed" /* E_WRITE_FAILED */
+ ,"Send Operation Failed" /* E_SEND_FAILED */
+ ,"Receive Operation Failed" /* E_RECEIVE_FAILED */
+ ,"Operation Timed Out" /* E_TIMEOUT */
+};
+
+
+#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
+
+const char *eventStrings[] =
+{
+ "Rx Discard" /* EV_RX_DISCARD */
+ ,"Rx Error" /* EV_RX_ERROR */
+ ,"Tx Error" /* EV_TX_ERROR */
+ ,"No Buffer Objects" /* EV_NO_BUFFERS */
+ ,"No MB-Frame Objects" /* EV_NO_MB_FRAMES */
+ ,"No SB-Frame Objects" /* EV_NO_SB_FRAMES */
+ ,"Tx Queue Is Full" /* EV_TX_QUEUE_FULL */
+ ,"Rx Queue Is Full" /* EV_RX_QUEUE_FULL */
+ ,"Interrupts Queue Is Full" /* EV_INTR_QUEUE_FULL */
+ ,"Data Buffer Is Unavailable" /* EV_NO_DATA_BUFFER */
+ ,"Objects Pool Is Empty" /* EV_OBJ_POOL_EMPTY */
+ ,"Illegal bus access" /* EV_BUS_ERROR */
+ ,"PTP Tx Timestamps Queue Is Full" /* EV_PTP_TXTS_QUEUE_FULL */
+ ,"PTP Rx Timestamps Queue Is Full" /* EV_PTP_RXTS_QUEUE_FULL */
+};
+
+#endif /* (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0)) */
+
+#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
+
diff --git a/sys/contrib/ncsw/etc/list.c b/sys/contrib/ncsw/etc/list.c
new file mode 100644
index 0000000..62a5fcd
--- /dev/null
+++ b/sys/contrib/ncsw/etc/list.c
@@ -0,0 +1,70 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+
+ @File list.c
+
+ @Description Implementation of list.
+*//***************************************************************************/
+#include "std_ext.h"
+#include "list_ext.h"
+
+
+void LIST_Append(t_List *p_NewList, t_List *p_Head)
+{
+ t_List *p_First = NCSW_LIST_FIRST(p_NewList);
+
+ if (p_First != p_NewList)
+ {
+ t_List *p_Last = LIST_LAST(p_NewList);
+ t_List *p_Cur = NCSW_LIST_NEXT(p_Head);
+
+ NCSW_LIST_PREV(p_First) = p_Head;
+ NCSW_LIST_FIRST(p_Head) = p_First;
+ NCSW_LIST_NEXT(p_Last) = p_Cur;
+ LIST_LAST(p_Cur) = p_Last;
+ }
+}
+
+
+int LIST_NumOfObjs(t_List *p_List)
+{
+ t_List *p_Tmp;
+ int numOfObjs = 0;
+
+ if (!LIST_IsEmpty(p_List))
+ LIST_FOR_EACH(p_Tmp, p_List)
+ numOfObjs++;
+
+ return numOfObjs;
+}
diff --git a/sys/contrib/ncsw/etc/mem.h b/sys/contrib/ncsw/etc/mem.h
new file mode 100644
index 0000000..776d880
--- /dev/null
+++ b/sys/contrib/ncsw/etc/mem.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+#ifndef __MEM_H
+#define __MEM_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "list_ext.h"
+
+
+#define __ERR_MODULE__ MODULE_MEM
+
+
+
+
+/**************************************************************************//**
+ @Description Memory allocation owner.
+*//***************************************************************************/
+typedef enum e_MemAllocOwner
+{
+ e_MEM_ALLOC_OWNER_LOCAL,
+ e_MEM_ALLOC_OWNER_LOCAL_SMART,
+ e_MEM_ALLOC_OWNER_EXTERNAL
+} e_MemAllocOwner;
+
+
+#ifdef DEBUG_MEM_LEAKS
+
+/**************************************************************************//**
+ @Description MEM block information for leaks detection.
+*//***************************************************************************/
+typedef struct t_MemDbg
+{
+ uintptr_t ownerAddress;
+
+} t_MemDbg;
+
+#endif /* DEBUG_MEM_LEAKS */
+
+
+#endif /* __MEM_H */
diff --git a/sys/contrib/ncsw/etc/memcpy.c b/sys/contrib/ncsw/etc/memcpy.c
new file mode 100644
index 0000000..1ed8dae
--- /dev/null
+++ b/sys/contrib/ncsw/etc/memcpy.c
@@ -0,0 +1,665 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "std_ext.h"
+#include "xx_ext.h"
+#include "memcpy_ext.h"
+
+
+#ifdef CORE_8BIT_ACCESS_ERRATA
+static void MY_MY_WRITE_UINT8(uint8_t *addr, uint8_t val)
+{
+ uint32_t newAddr, newVal;
+ newAddr = (uint32_t)addr & ~0x3L;
+ switch ((uint32_t)addr%4)
+ {
+ case (0):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x00ffffff) | (((uint32_t)val)<<24);
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ case (1):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xff00ffff) | (((uint32_t)val)<<16);
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ case (2):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xffff00ff) | (((uint32_t)val)<<8);
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ case (3):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xffffff00) | val;
+ WRITE_UINT32(*(uint32_t*)newAddr, newVal);
+ break;
+ }
+}
+
+static uint8_t MY_MY_GET_UINT8(uint8_t *addr)
+{
+ uint32_t newAddr, newVal=0;
+ newAddr = (uint32_t)addr & ~0x3L;
+ switch ((uint32_t)addr%4)
+ {
+ case (0):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0xff000000)>>24;
+ break;
+ case (1):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x00ff0000)>>16;
+ break;
+ case (2):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x0000ff00)>>8;
+ break;
+ case (3):
+ newVal = GET_UINT32(*(uint32_t*)newAddr);
+ newVal = (newVal & 0x000000ff);
+ break;
+ }
+
+ return (uint8_t)newVal;
+}
+
+#define MY_WRITE_UINT8(addr,val) MY_MY_WRITE_UINT8(&addr,val)
+#define MY_GET_UINT8(addr) MY_MY_GET_UINT8(&addr)
+#else
+#define MY_WRITE_UINT8 WRITE_UINT8
+#define MY_GET_UINT8 GET_UINT8
+#endif /* CORE_8BIT_ACCESS_ERRATA */
+
+
+void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
+{
+ uint32_t leftAlign;
+ uint32_t rightAlign;
+ uint32_t lastWord;
+ uint32_t currWord;
+ uint32_t *p_Src32;
+ uint32_t *p_Dst32;
+ uint8_t *p_Src8;
+ uint8_t *p_Dst8;
+
+ p_Src8 = (uint8_t*)(pSrc);
+ p_Dst8 = (uint8_t*)(pDst);
+ /* first copy byte by byte till the source first alignment
+ * this step is necessary to ensure we do not even try to access
+ * data which is before the source buffer, hence it is not ours.
+ */
+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
+ {
+ *p_Dst8++ = *p_Src8++;
+ size--;
+ }
+
+ /* align destination (possibly disaligning source)*/
+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
+ {
+ *p_Dst8++ = *p_Src8++;
+ size--;
+ }
+
+ /* dest is aligned and source is not necessarily aligned */
+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
+ rightAlign = 32 - leftAlign;
+
+
+ if (leftAlign == 0)
+ {
+ /* source is also aligned */
+ p_Src32 = (uint32_t*)(p_Src8);
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ while (size >> 2) /* size >= 4 */
+ {
+ *p_Dst32++ = *p_Src32++;
+ size -= 4;
+ }
+ p_Src8 = (uint8_t*)(p_Src32);
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ }
+ else
+ {
+ /* source is not aligned (destination is aligned)*/
+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ lastWord = *p_Src32++;
+ while(size >> 3) /* size >= 8 */
+ {
+ currWord = *p_Src32;
+ *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
+ lastWord = currWord;
+ p_Src32++;
+ p_Dst32++;
+ size -= 4;
+ }
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
+ }
+
+ /* complete the left overs */
+ while (size--)
+ *p_Dst8++ = *p_Src8++;
+
+ return pDst;
+}
+
+void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
+{
+ uint32_t leftAlign;
+ uint32_t rightAlign;
+ uint32_t lastWord;
+ uint32_t currWord;
+ uint32_t *p_Src32;
+ uint32_t *p_Dst32;
+ uint8_t *p_Src8;
+ uint8_t *p_Dst8;
+
+ p_Src8 = (uint8_t*)(pSrc);
+ p_Dst8 = (uint8_t*)(pDst);
+ /* first copy byte by byte till the source first alignment
+ * this step is necessary to ensure we do not even try to access
+ * data which is before the source buffer, hence it is not ours.
+ */
+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
+ {
+ MY_WRITE_UINT8(*p_Dst8, MY_GET_UINT8(*p_Src8));
+ p_Dst8++;p_Src8++;
+ size--;
+ }
+
+ /* align destination (possibly disaligning source)*/
+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
+ {
+ MY_WRITE_UINT8(*p_Dst8, MY_GET_UINT8(*p_Src8));
+ p_Dst8++;p_Src8++;
+ size--;
+ }
+
+ /* dest is aligned and source is not necessarily aligned */
+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
+ rightAlign = 32 - leftAlign;
+
+ if (leftAlign == 0)
+ {
+ /* source is also aligned */
+ p_Src32 = (uint32_t*)(p_Src8);
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ while (size >> 2) /* size >= 4 */
+ {
+ WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
+ p_Dst32++;p_Src32++;
+ size -= 4;
+ }
+ p_Src8 = (uint8_t*)(p_Src32);
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ }
+ else
+ {
+ /* source is not aligned (destination is aligned)*/
+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ lastWord = GET_UINT32(*p_Src32);
+ p_Src32++;
+ while(size >> 3) /* size >= 8 */
+ {
+ currWord = GET_UINT32(*p_Src32);
+ WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
+ lastWord = currWord;
+ p_Src32++;p_Dst32++;
+ size -= 4;
+ }
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
+ }
+
+ /* complete the left overs */
+ while (size--)
+ {
+ MY_WRITE_UINT8(*p_Dst8, MY_GET_UINT8(*p_Src8));
+ p_Dst8++;p_Src8++;
+ }
+
+ return pDst;
+}
+
+void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
+{
+ uint32_t leftAlign;
+ uint32_t rightAlign;
+ uint32_t lastWord;
+ uint32_t currWord;
+ uint32_t *p_Src32;
+ uint32_t *p_Dst32;
+ uint8_t *p_Src8;
+ uint8_t *p_Dst8;
+
+ p_Src8 = (uint8_t*)(pSrc);
+ p_Dst8 = (uint8_t*)(pDst);
+ /* first copy byte by byte till the source first alignment
+ * this step is necessary to ensure we do not even try to access
+ * data which is before the source buffer, hence it is not ours.
+ */
+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
+ {
+ MY_WRITE_UINT8(*p_Dst8, *p_Src8);
+ p_Dst8++;p_Src8++;
+ size--;
+ }
+
+ /* align destination (possibly disaligning source)*/
+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
+ {
+ MY_WRITE_UINT8(*p_Dst8, *p_Src8);
+ p_Dst8++;p_Src8++;
+ size--;
+ }
+
+ /* dest is aligned and source is not necessarily aligned */
+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
+ rightAlign = 32 - leftAlign;
+
+ if (leftAlign == 0)
+ {
+ /* source is also aligned */
+ p_Src32 = (uint32_t*)(p_Src8);
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ while (size >> 2) /* size >= 4 */
+ {
+ WRITE_UINT32(*p_Dst32, *p_Src32);
+ p_Dst32++;p_Src32++;
+ size -= 4;
+ }
+ p_Src8 = (uint8_t*)(p_Src32);
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ }
+ else
+ {
+ /* source is not aligned (destination is aligned)*/
+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ lastWord = *p_Src32++;
+ while(size >> 3) /* size >= 8 */
+ {
+ currWord = *p_Src32;
+ WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
+ lastWord = currWord;
+ p_Src32++;p_Dst32++;
+ size -= 4;
+ }
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
+ }
+
+ /* complete the left overs */
+ while (size--)
+ {
+ MY_WRITE_UINT8(*p_Dst8, *p_Src8);
+ p_Dst8++;p_Src8++;
+ }
+
+ return pDst;
+}
+
+void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
+{
+ uint32_t leftAlign;
+ uint32_t rightAlign;
+ uint32_t lastWord;
+ uint32_t currWord;
+ uint32_t *p_Src32;
+ uint32_t *p_Dst32;
+ uint8_t *p_Src8;
+ uint8_t *p_Dst8;
+
+ p_Src8 = (uint8_t*)(pSrc);
+ p_Dst8 = (uint8_t*)(pDst);
+ /* first copy byte by byte till the source first alignment
+ * this step is necessary to ensure we do not even try to access
+ * data which is before the source buffer, hence it is not ours.
+ */
+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
+ {
+ *p_Dst8 = MY_GET_UINT8(*p_Src8);
+ p_Dst8++;p_Src8++;
+ size--;
+ }
+
+ /* align destination (possibly disaligning source)*/
+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
+ {
+ *p_Dst8 = MY_GET_UINT8(*p_Src8);
+ p_Dst8++;p_Src8++;
+ size--;
+ }
+
+ /* dest is aligned and source is not necessarily aligned */
+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
+ rightAlign = 32 - leftAlign;
+
+ if (leftAlign == 0)
+ {
+ /* source is also aligned */
+ p_Src32 = (uint32_t*)(p_Src8);
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ while (size >> 2) /* size >= 4 */
+ {
+ *p_Dst32 = GET_UINT32(*p_Src32);
+ p_Dst32++;p_Src32++;
+ size -= 4;
+ }
+ p_Src8 = (uint8_t*)(p_Src32);
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ }
+ else
+ {
+ /* source is not aligned (destination is aligned)*/
+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ lastWord = GET_UINT32(*p_Src32);
+ p_Src32++;
+ while(size >> 3) /* size >= 8 */
+ {
+ currWord = GET_UINT32(*p_Src32);
+ *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
+ lastWord = currWord;
+ p_Src32++;p_Dst32++;
+ size -= 4;
+ }
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
+ }
+
+ /* complete the left overs */
+ while (size--)
+ {
+ *p_Dst8 = MY_GET_UINT8(*p_Src8);
+ p_Dst8++;p_Src8++;
+ }
+
+ return pDst;
+}
+
+void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
+{
+ uint32_t leftAlign;
+ uint32_t rightAlign;
+ uint64_t lastWord;
+ uint64_t currWord;
+ uint64_t *pSrc64;
+ uint64_t *pDst64;
+ uint8_t *p_Src8;
+ uint8_t *p_Dst8;
+
+ p_Src8 = (uint8_t*)(pSrc);
+ p_Dst8 = (uint8_t*)(pDst);
+ /* first copy byte by byte till the source first alignment
+ * this step is necessarily to ensure we do not even try to access
+ * data which is before the source buffer, hence it is not ours.
+ */
+ while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
+ {
+ *p_Dst8++ = *p_Src8++;
+ size--;
+ }
+
+ /* align destination (possibly disaligning source)*/
+ while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
+ {
+ *p_Dst8++ = *p_Src8++;
+ size--;
+ }
+
+ /* dest is aligned and source is not necessarily aligned */
+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
+ rightAlign = 64 - leftAlign;
+
+
+ if (leftAlign == 0)
+ {
+ /* source is also aligned */
+ pSrc64 = (uint64_t*)(p_Src8);
+ pDst64 = (uint64_t*)(p_Dst8);
+ while (size >> 3) /* size >= 8 */
+ {
+ *pDst64++ = *pSrc64++;
+ size -= 8;
+ }
+ p_Src8 = (uint8_t*)(pSrc64);
+ p_Dst8 = (uint8_t*)(pDst64);
+ }
+ else
+ {
+ /* source is not aligned (destination is aligned)*/
+ pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
+ pDst64 = (uint64_t*)(p_Dst8);
+ lastWord = *pSrc64++;
+ while(size >> 4) /* size >= 16 */
+ {
+ currWord = *pSrc64;
+ *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
+ lastWord = currWord;
+ pSrc64++;
+ pDst64++;
+ size -= 8;
+ }
+ p_Dst8 = (uint8_t*)(pDst64);
+ p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
+ }
+
+ /* complete the left overs */
+ while (size--)
+ *p_Dst8++ = *p_Src8++;
+
+ return pDst;
+}
+
+void * MemSet32(void* pDst, uint8_t val, uint32_t size)
+{
+ uint32_t val32;
+ uint32_t *p_Dst32;
+ uint8_t *p_Dst8;
+
+ p_Dst8 = (uint8_t*)(pDst);
+
+ /* generate four 8-bit val's in 32-bit container */
+ val32 = (uint32_t) val;
+ val32 |= (val32 << 8);
+ val32 |= (val32 << 16);
+
+ /* align destination to 32 */
+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
+ {
+ *p_Dst8++ = val;
+ size--;
+ }
+
+ /* 32-bit chunks */
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ while (size >> 2) /* size >= 4 */
+ {
+ *p_Dst32++ = val32;
+ size -= 4;
+ }
+
+ /* complete the leftovers */
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ while (size--)
+ *p_Dst8++ = val;
+
+ return pDst;
+}
+
+void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
+{
+ uint32_t val32;
+ uint32_t *p_Dst32;
+ uint8_t *p_Dst8;
+
+ p_Dst8 = (uint8_t*)(pDst);
+
+ /* generate four 8-bit val's in 32-bit container */
+ val32 = (uint32_t) val;
+ val32 |= (val32 << 8);
+ val32 |= (val32 << 16);
+
+ /* align destination to 32 */
+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
+ {
+ MY_WRITE_UINT8(*p_Dst8, val);
+ p_Dst8++;
+ size--;
+ }
+
+ /* 32-bit chunks */
+ p_Dst32 = (uint32_t*)(p_Dst8);
+ while (size >> 2) /* size >= 4 */
+ {
+ WRITE_UINT32(*p_Dst32, val32);
+ p_Dst32++;
+ size -= 4;
+ }
+
+ /* complete the leftovers */
+ p_Dst8 = (uint8_t*)(p_Dst32);
+ while (size--)
+ {
+ MY_WRITE_UINT8(*p_Dst8, val);
+ p_Dst8++;
+ }
+
+ return pDst;
+}
+
+void * MemSet64(void* pDst, uint8_t val, uint32_t size)
+{
+ uint64_t val64;
+ uint64_t *pDst64;
+ uint8_t *p_Dst8;
+
+ p_Dst8 = (uint8_t*)(pDst);
+
+ /* generate four 8-bit val's in 32-bit container */
+ val64 = (uint64_t) val;
+ val64 |= (val64 << 8);
+ val64 |= (val64 << 16);
+ val64 |= (val64 << 24);
+ val64 |= (val64 << 32);
+
+ /* align destination to 64 */
+ while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
+ {
+ *p_Dst8++ = val;
+ size--;
+ }
+
+ /* 64-bit chunks */
+ pDst64 = (uint64_t*)(p_Dst8);
+ while (size >> 4) /* size >= 8 */
+ {
+ *pDst64++ = val64;
+ size -= 8;
+ }
+
+ /* complete the leftovers */
+ p_Dst8 = (uint8_t*)(pDst64);
+ while (size--)
+ *p_Dst8++ = val;
+
+ return pDst;
+}
+
+void MemDisp(uint8_t *p, int size)
+{
+ uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
+ uint8_t *p_Limit;
+
+ if (space)
+ {
+ p_Limit = (p - space + 4);
+
+ XX_Print("0x%08X: ", (p - space));
+
+ while (space--)
+ {
+ XX_Print("--");
+ }
+ while (size && (p < p_Limit))
+ {
+ XX_Print("%02x", *(uint8_t*)p);
+ size--;
+ p++;
+ }
+
+ XX_Print(" ");
+ p_Limit += 12;
+
+ while ((size > 3) && (p < p_Limit))
+ {
+ XX_Print("%08x ", *(uint32_t*)p);
+ size -= 4;
+ p += 4;
+ }
+ XX_Print("\r\n");
+ }
+
+ while (size > 15)
+ {
+ XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
+ p, *(uint32_t *)p, *(uint32_t *)(p + 4),
+ *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
+ size -= 16;
+ p += 16;
+ }
+
+ if (size)
+ {
+ XX_Print("0x%08X: ", p);
+
+ while (size > 3)
+ {
+ XX_Print("%08x ", *(uint32_t *)p);
+ size -= 4;
+ p += 4;
+ }
+ while (size)
+ {
+ XX_Print("%02x", *(uint8_t *)p);
+ size--;
+ p++;
+ }
+
+ XX_Print("\r\n");
+ }
+}
diff --git a/sys/contrib/ncsw/etc/mm.c b/sys/contrib/ncsw/etc/mm.c
new file mode 100644
index 0000000..2a8e338
--- /dev/null
+++ b/sys/contrib/ncsw/etc/mm.c
@@ -0,0 +1,1109 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "string_ext.h"
+#include "error_ext.h"
+#include "std_ext.h"
+#include "sprint_ext.h"
+#include "part_ext.h"
+#include "xx_ext.h"
+
+#include "mm.h"
+
+
+
+
+/**********************************************************************
+ * MM internal routines set *
+ **********************************************************************/
+
+/****************************************************************
+ * Routine: CreateBusyBlock
+ *
+ * Description:
+ * Initializes a new busy block of "size" bytes and started
+ * rom "base" address. Each busy block has a name that
+ * specified the purpose of the memory allocation.
+ *
+ * Arguments:
+ * base - base address of the busy block
+ * size - size of the busy block
+ * name - name that specified the busy block
+ *
+ * Return value:
+ * A pointer to new created structure returned on success;
+ * Otherwise, NULL.
+ ****************************************************************/
+static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
+{
+ t_BusyBlock *p_BusyBlock;
+ uint32_t n;
+
+ p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
+ if ( !p_BusyBlock )
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ return NULL;
+ }
+
+ p_BusyBlock->base = base;
+ p_BusyBlock->end = base + size;
+
+ n = strlen(name);
+ if (n >= MM_MAX_NAME_LEN)
+ n = MM_MAX_NAME_LEN - 1;
+ strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
+ p_BusyBlock->name[n] = '\0';
+ p_BusyBlock->p_Next = 0;
+
+ return p_BusyBlock;
+}
+
+/****************************************************************
+ * Routine: CreateNewBlock
+ *
+ * Description:
+ * Initializes a new memory block of "size" bytes and started
+ * from "base" address.
+ *
+ * Arguments:
+ * base - base address of the memory block
+ * size - size of the memory block
+ *
+ * Return value:
+ * A pointer to new created structure returned on success;
+ * Otherwise, NULL.
+ ****************************************************************/
+static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
+{
+ t_MemBlock *p_MemBlock;
+
+ p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
+ if ( !p_MemBlock )
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ return NULL;
+ }
+
+ p_MemBlock->base = base;
+ p_MemBlock->end = base+size;
+ p_MemBlock->p_Next = 0;
+
+ return p_MemBlock;
+}
+
+/****************************************************************
+ * Routine: CreateFreeBlock
+ *
+ * Description:
+ * Initializes a new free block of of "size" bytes and
+ * started from "base" address.
+ *
+ * Arguments:
+ * base - base address of the free block
+ * size - size of the free block
+ *
+ * Return value:
+ * A pointer to new created structure returned on success;
+ * Otherwise, NULL.
+ ****************************************************************/
+static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
+{
+ t_FreeBlock *p_FreeBlock;
+
+ p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
+ if ( !p_FreeBlock )
+ {
+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ return NULL;
+ }
+
+ p_FreeBlock->base = base;
+ p_FreeBlock->end = base + size;
+ p_FreeBlock->p_Next = 0;
+
+ return p_FreeBlock;
+}
+
+/****************************************************************
+ * Routine: AddFree
+ *
+ * Description:
+ * Adds a new free block to the free lists. It updates each
+ * free list to include a new free block.
+ * Note, that all free block in each free list are ordered
+ * by their base address.
+ *
+ * Arguments:
+ * p_MM - pointer to the MM object
+ * base - base address of a given free block
+ * end - end address of a given free block
+ *
+ * Return value:
+ *
+ *
+ ****************************************************************/
+static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
+{
+ t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
+ uint64_t alignment;
+ uint64_t alignBase;
+ int i;
+
+ /* Updates free lists to include a just released block */
+ for (i=0; i <= MM_MAX_ALIGNMENT; i++)
+ {
+ p_PrevB = p_NewB = 0;
+ p_CurrB = p_MM->freeBlocks[i];
+
+ alignment = (uint64_t)(0x1 << i);
+ alignBase = MAKE_ALIGNED(base, alignment);
+
+ /* Goes to the next free list if there is no block to free */
+ if (alignBase >= end)
+ continue;
+
+ /* Looks for a free block that should be updated */
+ while ( p_CurrB )
+ {
+ if ( alignBase <= p_CurrB->end )
+ {
+ if ( end > p_CurrB->end )
+ {
+ t_FreeBlock *p_NextB;
+ while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
+ {
+ p_NextB = p_CurrB->p_Next;
+ p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
+ XX_Free(p_NextB);
+ }
+
+ p_NextB = p_CurrB->p_Next;
+ if ( !p_NextB || (p_NextB && end < p_NextB->base) )
+ {
+ p_CurrB->end = end;
+ }
+ else
+ {
+ p_CurrB->end = p_NextB->end;
+ p_CurrB->p_Next = p_NextB->p_Next;
+ XX_Free(p_NextB);
+ }
+ }
+ else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
+ {
+ if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+
+ p_NewB->p_Next = p_CurrB;
+ if (p_PrevB)
+ p_PrevB->p_Next = p_NewB;
+ else
+ p_MM->freeBlocks[i] = p_NewB;
+ break;
+ }
+
+ if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
+ {
+ p_CurrB->base = alignBase;
+ }
+
+ /* if size of the free block is less then alignment
+ * deletes that free block from the free list. */
+ if ( (p_CurrB->end - p_CurrB->base) < alignment)
+ {
+ if ( p_PrevB )
+ p_PrevB->p_Next = p_CurrB->p_Next;
+ else
+ p_MM->freeBlocks[i] = p_CurrB->p_Next;
+ XX_Free(p_CurrB);
+ }
+ break;
+ }
+ else
+ {
+ p_PrevB = p_CurrB;
+ p_CurrB = p_CurrB->p_Next;
+ }
+ }
+
+ /* If no free block found to be updated, insert a new free block
+ * to the end of the free list.
+ */
+ if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
+ {
+ if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+
+ if (p_PrevB)
+ p_PrevB->p_Next = p_NewB;
+ else
+ p_MM->freeBlocks[i] = p_NewB;
+ }
+
+ /* Update boundaries of the new free block */
+ if ((alignment == 1) && !p_NewB)
+ {
+ if ( p_CurrB && base > p_CurrB->base )
+ base = p_CurrB->base;
+ if ( p_CurrB && end < p_CurrB->end )
+ end = p_CurrB->end;
+ }
+ }
+
+ return (E_OK);
+}
+
+/****************************************************************
+ * Routine: CutFree
+ *
+ * Description:
+ * Cuts a free block from holdBase to holdEnd from the free lists.
+ * That is, it updates all free lists of the MM object do
+ * not include a block of memory from holdBase to holdEnd.
+ * For each free lists it seek for a free block that holds
+ * either holdBase or holdEnd. If such block is found it updates it.
+ *
+ * Arguments:
+ * p_MM - pointer to the MM object
+ * holdBase - base address of the allocated block
+ * holdEnd - end address of the allocated block
+ *
+ * Return value:
+ * E_OK is returned on success,
+ * otherwise returns an error code.
+ *
+ ****************************************************************/
+static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
+{
+ t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
+ uint64_t alignBase, base, end;
+ uint64_t alignment;
+ int i;
+
+ for (i=0; i <= MM_MAX_ALIGNMENT; i++)
+ {
+ p_PrevB = p_NewB = 0;
+ p_CurrB = p_MM->freeBlocks[i];
+
+ alignment = (uint64_t)(0x1 << i);
+ alignBase = MAKE_ALIGNED(holdEnd, alignment);
+
+ while ( p_CurrB )
+ {
+ base = p_CurrB->base;
+ end = p_CurrB->end;
+
+ if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
+ {
+ if ( alignBase >= end ||
+ (alignBase < end && ((end-alignBase) < alignment)) )
+ {
+ if (p_PrevB)
+ p_PrevB->p_Next = p_CurrB->p_Next;
+ else
+ p_MM->freeBlocks[i] = p_CurrB->p_Next;
+ XX_Free(p_CurrB);
+ }
+ else
+ {
+ p_CurrB->base = alignBase;
+ }
+ break;
+ }
+ else if ( (holdBase > base) && (holdEnd <= end) )
+ {
+ if ( (holdBase-base) >= alignment )
+ {
+ if ( (alignBase < end) && ((end-alignBase) >= alignment) )
+ {
+ if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ p_NewB->p_Next = p_CurrB->p_Next;
+ p_CurrB->p_Next = p_NewB;
+ }
+ p_CurrB->end = holdBase;
+ }
+ else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
+ {
+ p_CurrB->base = alignBase;
+ }
+ else
+ {
+ if (p_PrevB)
+ p_PrevB->p_Next = p_CurrB->p_Next;
+ else
+ p_MM->freeBlocks[i] = p_CurrB->p_Next;
+ XX_Free(p_CurrB);
+ }
+ break;
+ }
+ else
+ {
+ p_PrevB = p_CurrB;
+ p_CurrB = p_CurrB->p_Next;
+ }
+ }
+ }
+
+ return (E_OK);
+}
+
+/****************************************************************
+ * Routine: AddBusy
+ *
+ * Description:
+ * Adds a new busy block to the list of busy blocks. Note,
+ * that all busy blocks are ordered by their base address in
+ * the busy list.
+ *
+ * Arguments:
+ * MM - handler to the MM object
+ * p_NewBusyB - pointer to the a busy block
+ *
+ * Return value:
+ * None.
+ *
+ ****************************************************************/
+static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
+{
+ t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
+
+ /* finds a place of a new busy block in the list of busy blocks */
+ p_PrevBusyB = 0;
+ p_CurrBusyB = p_MM->busyBlocks;
+
+ while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
+ {
+ p_PrevBusyB = p_CurrBusyB;
+ p_CurrBusyB = p_CurrBusyB->p_Next;
+ }
+
+ /* insert the new busy block into the list of busy blocks */
+ if ( p_CurrBusyB )
+ p_NewBusyB->p_Next = p_CurrBusyB;
+ if ( p_PrevBusyB )
+ p_PrevBusyB->p_Next = p_NewBusyB;
+ else
+ p_MM->busyBlocks = p_NewBusyB;
+}
+
+/****************************************************************
+ * Routine: CutBusy
+ *
+ * Description:
+ * Cuts a block from base to end from the list of busy blocks.
+ * This is done by updating the list of busy blocks do not
+ * include a given block, that block is going to be free. If a
+ * given block is a part of some other busy block, so that
+ * busy block is updated. If there are number of busy blocks
+ * included in the given block, so all that blocks are removed
+ * from the busy list and the end blocks are updated.
+ * If the given block devides some block into two parts, a new
+ * busy block is added to the busy list.
+ *
+ * Arguments:
+ * p_MM - pointer to the MM object
+ * base - base address of a given busy block
+ * end - end address of a given busy block
+ *
+ * Return value:
+ * E_OK on success, E_NOMEMORY otherwise.
+ *
+ ****************************************************************/
+static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
+{
+ t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
+
+ p_CurrB = p_MM->busyBlocks;
+ p_PrevB = p_NewB = 0;
+
+ while ( p_CurrB )
+ {
+ if ( base < p_CurrB->end )
+ {
+ if ( end > p_CurrB->end )
+ {
+ t_BusyBlock *p_NextB;
+ while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
+ {
+ p_NextB = p_CurrB->p_Next;
+ p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
+ XX_Free(p_NextB);
+ }
+
+ p_NextB = p_CurrB->p_Next;
+ if ( p_NextB && end > p_NextB->base )
+ {
+ p_NextB->base = end;
+ }
+ }
+
+ if ( base <= p_CurrB->base )
+ {
+ if ( end < p_CurrB->end && end > p_CurrB->base )
+ {
+ p_CurrB->base = end;
+ }
+ else if ( end >= p_CurrB->end )
+ {
+ if ( p_PrevB )
+ p_PrevB->p_Next = p_CurrB->p_Next;
+ else
+ p_MM->busyBlocks = p_CurrB->p_Next;
+ XX_Free(p_CurrB);
+ }
+ }
+ else
+ {
+ if ( end < p_CurrB->end && end > p_CurrB->base )
+ {
+ if ((p_NewB = CreateBusyBlock(end,
+ p_CurrB->end-end,
+ p_CurrB->name)) == NULL)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ p_NewB->p_Next = p_CurrB->p_Next;
+ p_CurrB->p_Next = p_NewB;
+ }
+ p_CurrB->end = base;
+ }
+ break;
+ }
+ else
+ {
+ p_PrevB = p_CurrB;
+ p_CurrB = p_CurrB->p_Next;
+ }
+ }
+
+ return (E_OK);
+}
+
+/****************************************************************
+ * Routine: MmGetGreaterAlignment
+ *
+ * Description:
+ * Allocates a block of memory according to the given size
+ * and the alignment. That routine is called from the MM_Get
+ * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
+ * In that case, it goes over free blocks of 64 byte align list
+ * and checks if it has the required size of bytes of the required
+ * alignment. If no blocks found returns ILLEGAL_BASE.
+ * After the block is found and data is allocated, it calls
+ * the internal CutFree routine to update all free lists
+ * do not include a just allocated block. Of course, each
+ * free list contains a free blocks with the same alignment.
+ * It is also creates a busy block that holds
+ * information about an allocated block.
+ *
+ * Arguments:
+ * MM - handle to the MM object
+ * size - size of the MM
+ * alignment - index as a power of two defines
+ * a required alignment that is greater then 64.
+ * name - the name that specifies an allocated block.
+ *
+ * Return value:
+ * base address of an allocated block.
+ * ILLEGAL_BASE if can't allocate a block
+ *
+ ****************************************************************/
+static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
+{
+ t_FreeBlock *p_FreeB;
+ t_BusyBlock *p_NewBusyB;
+ uint64_t holdBase, holdEnd, alignBase = 0;
+
+ /* goes over free blocks of the 64 byte alignment list
+ and look for a block of the suitable size and
+ base address according to the alignment. */
+ p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
+
+ while ( p_FreeB )
+ {
+ alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
+
+ /* the block is found if the aligned base inside the block
+ * and has the anough size. */
+ if ( alignBase >= p_FreeB->base &&
+ alignBase < p_FreeB->end &&
+ size <= (p_FreeB->end - alignBase) )
+ break;
+ else
+ p_FreeB = p_FreeB->p_Next;
+ }
+
+ /* If such block isn't found */
+ if ( !p_FreeB )
+ return (uint64_t)(ILLEGAL_BASE);
+
+ holdBase = alignBase;
+ holdEnd = alignBase + size;
+
+ /* init a new busy block */
+ if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
+ return (uint64_t)(ILLEGAL_BASE);
+
+ /* calls Update routine to update a lists of free blocks */
+ if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
+ return (uint64_t)(ILLEGAL_BASE);
+
+ /* insert the new busy block into the list of busy blocks */
+ AddBusy ( p_MM, p_NewBusyB );
+
+ return (holdBase);
+}
+
+
+/**********************************************************************
+ * MM API routines set *
+ **********************************************************************/
+
+/*****************************************************************************/
+t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
+{
+ t_MM *p_MM;
+ uint64_t newBase, newSize;
+ int i;
+
+ if (!size)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
+ }
+
+ /* Initializes a new MM object */
+ p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
+ if (!p_MM)
+ {
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ }
+
+ p_MM->h_Spinlock = XX_InitSpinlock();
+ if (!p_MM->h_Spinlock)
+ {
+ XX_Free(p_MM);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
+ }
+
+ /* initializes a new memory block */
+ if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+
+ /* A busy list is empty */
+ p_MM->busyBlocks = 0;
+
+ /*Initializes a new free block for each free list*/
+ for (i=0; i <= MM_MAX_ALIGNMENT; i++)
+ {
+ newBase = MAKE_ALIGNED( base, (0x1 << i) );
+ newSize = size - (newBase - base);
+
+ if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ }
+
+ *h_MM = p_MM;
+
+ return (E_OK);
+}
+
+/*****************************************************************************/
+void MM_Free(t_Handle h_MM)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ t_MemBlock *p_MemBlock;
+ t_BusyBlock *p_BusyBlock;
+ t_FreeBlock *p_FreeBlock;
+ void *p_Block;
+ int i;
+
+ ASSERT_COND(p_MM);
+
+ /* release memory allocated for busy blocks */
+ p_BusyBlock = p_MM->busyBlocks;
+ while ( p_BusyBlock )
+ {
+ p_Block = p_BusyBlock;
+ p_BusyBlock = p_BusyBlock->p_Next;
+ XX_Free(p_Block);
+ }
+
+ /* release memory allocated for free blocks */
+ for (i=0; i <= MM_MAX_ALIGNMENT; i++)
+ {
+ p_FreeBlock = p_MM->freeBlocks[i];
+ while ( p_FreeBlock )
+ {
+ p_Block = p_FreeBlock;
+ p_FreeBlock = p_FreeBlock->p_Next;
+ XX_Free(p_Block);
+ }
+ }
+
+ /* release memory allocated for memory blocks */
+ p_MemBlock = p_MM->memBlocks;
+ while ( p_MemBlock )
+ {
+ p_Block = p_MemBlock;
+ p_MemBlock = p_MemBlock->p_Next;
+ XX_Free(p_Block);
+ }
+
+ if (p_MM->h_Spinlock)
+ XX_FreeSpinlock(p_MM->h_Spinlock);
+
+ /* release memory allocated for MM object itself */
+ XX_Free(p_MM);
+}
+
+/*****************************************************************************/
+uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ t_FreeBlock *p_FreeB;
+ t_BusyBlock *p_NewBusyB;
+ uint64_t holdBase, holdEnd, j, i = 0;
+ uint32_t intFlags;
+
+ SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
+
+ /* checks that alignment value is greater then zero */
+ if (alignment == 0)
+ {
+ alignment = 1;
+ }
+
+ j = alignment;
+
+ /* checks if alignment is a power of two, if it correct and if the
+ required size is multiple of the given alignment. */
+ while ((j & 0x1) == 0)
+ {
+ i++;
+ j = j >> 1;
+ }
+
+ /* if the given alignment isn't power of two, returns an error */
+ if (j != 1)
+ {
+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
+ return (uint64_t)ILLEGAL_BASE;
+ }
+
+ if (i > MM_MAX_ALIGNMENT)
+ {
+ return (MmGetGreaterAlignment(p_MM, size, alignment, name));
+ }
+
+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
+ /* look for a block of the size greater or equal to the required size. */
+ p_FreeB = p_MM->freeBlocks[i];
+ while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
+ p_FreeB = p_FreeB->p_Next;
+
+ /* If such block is found */
+ if ( !p_FreeB )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ holdBase = p_FreeB->base;
+ holdEnd = holdBase + size;
+
+ /* init a new busy block */
+ if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* calls Update routine to update a lists of free blocks */
+ if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* insert the new busy block into the list of busy blocks */
+ AddBusy ( p_MM, p_NewBusyB );
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+
+ return (holdBase);
+}
+
+/*****************************************************************************/
+uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ t_FreeBlock *p_FreeB;
+ t_BusyBlock *p_NewBusyB;
+ uint32_t intFlags;
+ bool blockIsFree = FALSE;
+
+ ASSERT_COND(p_MM);
+
+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
+ p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
+ free list with alignment 1 */
+
+ while ( p_FreeB )
+ {
+ if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
+ {
+ blockIsFree = TRUE;
+ break;
+ }
+ else
+ p_FreeB = p_FreeB->p_Next;
+ }
+
+ if ( !blockIsFree )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* init a new busy block */
+ if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* calls Update routine to update a lists of free blocks */
+ if ( CutFree ( p_MM, base, base+size ) != E_OK )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* insert the new busy block into the list of busy blocks */
+ AddBusy ( p_MM, p_NewBusyB );
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+
+ return (base);
+}
+
+/*****************************************************************************/
+uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ t_FreeBlock *p_FreeB;
+ t_BusyBlock *p_NewBusyB;
+ uint64_t holdBase, holdEnd, j = alignment, i=0;
+ uint32_t intFlags;
+
+ ASSERT_COND(p_MM);
+
+ /* checks if alignment is a power of two, if it correct and if the
+ required size is multiple of the given alignment. */
+ while ((j & 0x1) == 0)
+ {
+ i++;
+ j = j >> 1;
+ }
+
+ if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
+ {
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
+ p_FreeB = p_MM->freeBlocks[i];
+
+ /* look for the first block that contains the minimum
+ base address. If the whole required size may be fit
+ into it, use that block, otherwise look for the next
+ block of size greater or equal to the required size. */
+ while ( p_FreeB && (min >= p_FreeB->end))
+ p_FreeB = p_FreeB->p_Next;
+
+ /* If such block is found */
+ if ( !p_FreeB )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* if this block is large enough, use this block */
+ holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
+ if ((holdBase + size) <= p_FreeB->end )
+ {
+ holdEnd = holdBase + size;
+ }
+ else
+ {
+ p_FreeB = p_FreeB->p_Next;
+ while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
+ p_FreeB = p_FreeB->p_Next;
+
+ /* If such block is found */
+ if ( !p_FreeB )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ holdBase = p_FreeB->base;
+ holdEnd = holdBase + size;
+ }
+
+ /* init a new busy block */
+ if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* calls Update routine to update a lists of free blocks */
+ if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(ILLEGAL_BASE);
+ }
+
+ /* insert the new busy block into the list of busy blocks */
+ AddBusy( p_MM, p_NewBusyB );
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+
+ return (holdBase);
+}
+
+/*****************************************************************************/
+uint64_t MM_Put(t_Handle h_MM, uint64_t base)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ t_BusyBlock *p_BusyB, *p_PrevBusyB;
+ uint64_t size;
+ uint32_t intFlags;
+
+ ASSERT_COND(p_MM);
+
+ /* Look for a busy block that have the given base value.
+ * That block will be returned back to the memory.
+ */
+ p_PrevBusyB = 0;
+
+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
+ p_BusyB = p_MM->busyBlocks;
+ while ( p_BusyB && base != p_BusyB->base )
+ {
+ p_PrevBusyB = p_BusyB;
+ p_BusyB = p_BusyB->p_Next;
+ }
+
+ if ( !p_BusyB )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(0);
+ }
+
+ if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(0);
+ }
+
+ /* removes a busy block form the list of busy blocks */
+ if ( p_PrevBusyB )
+ p_PrevBusyB->p_Next = p_BusyB->p_Next;
+ else
+ p_MM->busyBlocks = p_BusyB->p_Next;
+
+ size = p_BusyB->end - p_BusyB->base;
+
+ XX_Free(p_BusyB);
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+
+ return (size);
+}
+
+/*****************************************************************************/
+uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ uint64_t end = base + size;
+ uint32_t intFlags;
+
+ ASSERT_COND(p_MM);
+
+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
+ if ( CutBusy( p_MM, base, end ) != E_OK )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(0);
+ }
+
+ if ( AddFree ( p_MM, base, end ) != E_OK )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ return (uint64_t)(0);
+ }
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+
+ return (size);
+}
+
+/*****************************************************************************/
+t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ t_MemBlock *p_MemB, *p_NewMemB;
+ t_Error errCode;
+ uint32_t intFlags;
+
+ ASSERT_COND(p_MM);
+
+ /* find a last block in the list of memory blocks to insert a new
+ * memory block
+ */
+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
+ p_MemB = p_MM->memBlocks;
+ while ( p_MemB->p_Next )
+ {
+ if ( base >= p_MemB->base && base < p_MemB->end )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
+ }
+ p_MemB = p_MemB->p_Next;
+ }
+ /* check for a last memory block */
+ if ( base >= p_MemB->base && base < p_MemB->end )
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
+ }
+
+ /* create a new memory block */
+ if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
+ }
+
+ /* append a new memory block to the end of the list of memory blocks */
+ p_MemB->p_Next = p_NewMemB;
+
+ /* add a new free block to the free lists */
+ errCode = AddFree(p_MM, base, base+size);
+ if (errCode)
+ {
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+ p_MemB->p_Next = 0;
+ XX_Free(p_NewMemB);
+ return ((t_Error)errCode);
+ }
+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
+
+ return (E_OK);
+}
+
+/*****************************************************************************/
+uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
+{
+ t_MM *p_MM = (t_MM*)h_MM;
+ t_MemBlock *p_MemBlock;
+ int i;
+
+ ASSERT_COND(p_MM);
+
+ p_MemBlock = p_MM->memBlocks;
+ for (i=0; i < index; i++)
+ p_MemBlock = p_MemBlock->p_Next;
+
+ if ( p_MemBlock )
+ return (p_MemBlock->base);
+ else
+ return (uint64_t)ILLEGAL_BASE;
+}
+
+/*****************************************************************************/
+uint64_t MM_GetBase(t_Handle h_MM)
+{
+ t_MM *p_MM = (t_MM*)h_MM;
+ t_MemBlock *p_MemBlock;
+
+ ASSERT_COND(p_MM);
+
+ p_MemBlock = p_MM->memBlocks;
+ return p_MemBlock->base;
+}
+
+/*****************************************************************************/
+bool MM_InRange(t_Handle h_MM, uint64_t addr)
+{
+ t_MM *p_MM = (t_MM*)h_MM;
+ t_MemBlock *p_MemBlock;
+
+ ASSERT_COND(p_MM);
+
+ p_MemBlock = p_MM->memBlocks;
+
+ if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*****************************************************************************/
+void MM_Dump(t_Handle h_MM, void *buff)
+{
+ t_MM *p_MM = (t_MM *)h_MM;
+ t_FreeBlock *p_FreeB;
+ t_BusyBlock *p_BusyB;
+ int i;
+
+ p_BusyB = p_MM->busyBlocks;
+ Sprint(buff, "List of busy blocks:\n");
+ while (p_BusyB)
+ {
+ Sprint(buff, "\t0x%p: (%s: b=0x%lx, e=0x%lx)\n",
+ p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
+ p_BusyB = p_BusyB->p_Next;
+ }
+
+ Sprint(buff, "\nLists of free blocks according to alignment:\n");
+ for (i=0; i <= MM_MAX_ALIGNMENT; i++)
+ {
+ Sprint(buff, "%d alignment:\n", (0x1 << i));
+ p_FreeB = p_MM->freeBlocks[i];
+ while (p_FreeB)
+ {
+ Sprint(buff, "\t0x%p: (b=0x%lx, e=0x%lx)\n",
+ p_FreeB, p_FreeB->base, p_FreeB->end);
+ p_FreeB = p_FreeB->p_Next;
+ }
+ Sprint(buff, "\n");
+ }
+}
diff --git a/sys/contrib/ncsw/etc/mm.h b/sys/contrib/ncsw/etc/mm.h
new file mode 100644
index 0000000..509f614
--- /dev/null
+++ b/sys/contrib/ncsw/etc/mm.h
@@ -0,0 +1,101 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/****************************************************************
+ *
+ * File: mm.h
+ *
+ *
+ * Description:
+ * MM (Memory Management) object definitions.
+ * It also includes definitions of the Free Block, Busy Block
+ * and Memory Block structures used by the MM object.
+ *
+ ****************************************************************/
+
+#ifndef __MM_H
+#define __MM_H
+
+
+#include "mm_ext.h"
+
+#define __ERR_MODULE__ MODULE_MM
+
+
+#define MAKE_ALIGNED(addr, align) \
+ (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
+
+
+/* t_MemBlock data stucutre defines parameters of the Memory Block */
+typedef struct t_MemBlock
+{
+ struct t_MemBlock *p_Next; /* Pointer to the next memory block */
+
+ uint64_t base; /* Base address of the memory block */
+ uint64_t end; /* End address of the memory block */
+} t_MemBlock;
+
+
+/* t_FreeBlock data stucutre defines parameters of the Free Block */
+typedef struct t_FreeBlock
+{
+ struct t_FreeBlock *p_Next; /* Pointer to the next free block */
+
+ uint64_t base; /* Base address of the block */
+ uint64_t end; /* End address of the block */
+} t_FreeBlock;
+
+
+/* t_BusyBlock data stucutre defines parameters of the Busy Block */
+typedef struct t_BusyBlock
+{
+ struct t_BusyBlock *p_Next; /* Pointer to the next free block */
+
+ uint64_t base; /* Base address of the block */
+ uint64_t end; /* End address of the block */
+ char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
+ something specified by the Name */
+} t_BusyBlock;
+
+
+/* t_MM data structure defines parameters of the MM object */
+typedef struct t_MM
+{
+ t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
+ t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
+ t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
+ /* Alignment lists of free blocks (Free lists) */
+ t_Handle h_Spinlock;
+} t_MM;
+
+
+#endif /* __MM_H */
diff --git a/sys/contrib/ncsw/etc/ncsw_mem.c b/sys/contrib/ncsw/etc/ncsw_mem.c
new file mode 100644
index 0000000..f82f0f4
--- /dev/null
+++ b/sys/contrib/ncsw/etc/ncsw_mem.c
@@ -0,0 +1,763 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+#include "error_ext.h"
+#include "part_ext.h"
+#include "std_ext.h"
+#include "string_ext.h"
+#include "mem_ext.h"
+#include "mem.h"
+#include "xx_ext.h"
+
+
+#define PAD_ALIGNMENT(align, x) (((x)%(align)) ? ((align)-((x)%(align))) : 0)
+
+#define ALIGN_BLOCK(p_Block, prefixSize, alignment) \
+ do { \
+ p_Block += (prefixSize); \
+ p_Block += PAD_ALIGNMENT((alignment), (uintptr_t)(p_Block)); \
+ } while (0)
+
+#if defined(__GNUC__)
+#define GET_CALLER_ADDR \
+ __asm__ ("mflr %0" : "=r" (callerAddr))
+#elif defined(__MWERKS__)
+/* NOTE: This implementation is only valid for CodeWarrior for PowerPC */
+#define GET_CALLER_ADDR \
+ __asm__("add %0, 0, %0" : : "r" (callerAddr))
+#endif /* defined(__GNUC__) */
+
+
+/*****************************************************************************/
+static __inline__ void * MemGet(t_MemorySegment *p_Mem)
+{
+ uint8_t *p_Block;
+
+ /* check if there is an available block */
+ if (p_Mem->current == p_Mem->num)
+ {
+ p_Mem->getFailures++;
+ return NULL;
+ }
+
+ /* get the block */
+ p_Block = p_Mem->p_BlocksStack[p_Mem->current];
+#ifdef DEBUG
+ p_Mem->p_BlocksStack[p_Mem->current] = NULL;
+#endif /* DEBUG */
+ /* advance current index */
+ p_Mem->current++;
+
+ return (void *)p_Block;
+}
+
+/*****************************************************************************/
+static __inline__ t_Error MemPut(t_MemorySegment *p_Mem, void *p_Block)
+{
+ /* check if blocks stack is full */
+ if (p_Mem->current > 0)
+ {
+ /* decrease current index */
+ p_Mem->current--;
+ /* put the block */
+ p_Mem->p_BlocksStack[p_Mem->current] = (uint8_t *)p_Block;
+ return E_OK;
+ }
+
+ RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
+}
+
+
+#ifdef DEBUG_MEM_LEAKS
+
+/*****************************************************************************/
+static t_Error InitMemDebugDatabase(t_MemorySegment *p_Mem)
+{
+ p_Mem->p_MemDbg = (void *)XX_Malloc(sizeof(t_MemDbg) * p_Mem->num);
+ if (!p_Mem->p_MemDbg)
+ {
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory debug object"));
+ }
+
+ memset(p_Mem->p_MemDbg, ILLEGAL_BASE, sizeof(t_MemDbg) * p_Mem->num);
+
+ return E_OK;
+}
+
+
+/*****************************************************************************/
+static t_Error DebugMemGet(t_Handle h_Mem, void *p_Block, uintptr_t ownerAddress)
+{
+ t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem;
+ t_MemDbg *p_MemDbg = (t_MemDbg *)p_Mem->p_MemDbg;
+ uint32_t blockIndex;
+
+ ASSERT_COND(ownerAddress != ILLEGAL_BASE);
+
+ /* Find block num */
+ if (p_Mem->consecutiveMem)
+ {
+ blockIndex =
+ (((uint8_t *)p_Block - (p_Mem->p_Bases[0] + p_Mem->blockOffset)) / p_Mem->blockSize);
+ }
+ else
+ {
+ blockIndex = *(uint32_t *)((uint8_t *)p_Block - 4);
+ }
+
+ ASSERT_COND(blockIndex < p_Mem->num);
+ ASSERT_COND(p_MemDbg[blockIndex].ownerAddress == ILLEGAL_BASE);
+
+ p_MemDbg[blockIndex].ownerAddress = ownerAddress;
+
+ return E_OK;
+}
+
+/*****************************************************************************/
+static t_Error DebugMemPut(t_Handle h_Mem, void *p_Block)
+{
+ t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem;
+ t_MemDbg *p_MemDbg = (t_MemDbg *)p_Mem->p_MemDbg;
+ uint32_t blockIndex;
+ uint8_t *p_Temp;
+
+ /* Find block num */
+ if (p_Mem->consecutiveMem)
+ {
+ blockIndex =
+ (((uint8_t *)p_Block - (p_Mem->p_Bases[0] + p_Mem->blockOffset)) / p_Mem->blockSize);
+
+ if (blockIndex >= p_Mem->num)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_ADDRESS,
+ ("Freed address (0x%08x) does not belong to this pool", p_Block));
+ }
+ }
+ else
+ {
+ blockIndex = *(uint32_t *)((uint8_t *)p_Block - 4);
+
+ if (blockIndex >= p_Mem->num)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_ADDRESS,
+ ("Freed address (0x%08x) does not belong to this pool", p_Block));
+ }
+
+ /* Verify that the block matches the corresponding base */
+ p_Temp = p_Mem->p_Bases[blockIndex];
+
+ ALIGN_BLOCK(p_Temp, p_Mem->prefixSize, p_Mem->alignment);
+
+ if (p_Temp == p_Mem->p_Bases[blockIndex])
+ p_Temp += p_Mem->alignment;
+
+ if (p_Temp != p_Block)
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_ADDRESS,
+ ("Freed address (0x%08x) does not belong to this pool", p_Block));
+ }
+ }
+
+ if (p_MemDbg[blockIndex].ownerAddress == ILLEGAL_BASE)
+ {
+ RETURN_ERROR(MAJOR, E_ALREADY_FREE,
+ ("Attempt to free unallocated address (0x%08x)", p_Block));
+ }
+
+ p_MemDbg[blockIndex].ownerAddress = (uintptr_t)ILLEGAL_BASE;
+
+ return E_OK;
+}
+
+#endif /* DEBUG_MEM_LEAKS */
+
+
+/*****************************************************************************/
+uint32_t MEM_ComputePartitionSize(uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment)
+{
+ uint32_t blockSize = 0, pad1 = 0, pad2 = 0;
+
+ /* Make sure that the alignment is at least 4 */
+ if (alignment < 4)
+ {
+ alignment = 4;
+ }
+
+ pad1 = (uint32_t)PAD_ALIGNMENT(4, prefixSize);
+ /* Block size not including 2nd padding */
+ blockSize = pad1 + prefixSize + dataSize + postfixSize;
+ pad2 = PAD_ALIGNMENT(alignment, blockSize);
+ /* Block size including 2nd padding */
+ blockSize += pad2;
+
+ return ((num * blockSize) + alignment);
+}
+
+/*****************************************************************************/
+t_Error MEM_Init(char name[],
+ t_Handle *p_Handle,
+ uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment)
+{
+ uint8_t *p_Memory;
+ uint32_t allocSize;
+ t_Error errCode;
+
+ allocSize = MEM_ComputePartitionSize(num,
+ dataSize,
+ prefixSize,
+ postfixSize,
+ alignment);
+
+ p_Memory = (uint8_t *)XX_Malloc(allocSize);
+ if (!p_Memory)
+ {
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment"));
+ }
+
+ errCode = MEM_InitByAddress(name,
+ p_Handle,
+ num,
+ dataSize,
+ prefixSize,
+ postfixSize,
+ alignment,
+ p_Memory);
+ if (errCode != E_OK)
+ {
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ }
+
+ ((t_MemorySegment *)(*p_Handle))->allocOwner = e_MEM_ALLOC_OWNER_LOCAL;
+
+ return E_OK;
+}
+
+
+/*****************************************************************************/
+t_Error MEM_InitByAddress(char name[],
+ t_Handle *p_Handle,
+ uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment,
+ uint8_t *p_Memory)
+{
+ t_MemorySegment *p_Mem;
+ uint32_t i, blockSize;
+ uint16_t alignPad, endPad;
+ uint8_t *p_Blocks;
+
+ /* prepare in case of error */
+ *p_Handle = NULL;
+
+ if (!p_Memory)
+ {
+ RETURN_ERROR(MAJOR, E_NULL_POINTER, ("Memory blocks"));
+ }
+
+ p_Blocks = p_Memory;
+
+ /* make sure that the alignment is at least 4 and power of 2 */
+ if (alignment < 4)
+ {
+ alignment = 4;
+ }
+ else if (!POWER_OF_2(alignment))
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Alignment (should be power of 2)"));
+ }
+
+ /* first allocate the segment descriptor */
+ p_Mem = (t_MemorySegment *)XX_Malloc(sizeof(t_MemorySegment));
+ if (!p_Mem)
+ {
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment structure"));
+ }
+
+ /* allocate the blocks stack */
+ p_Mem->p_BlocksStack = (uint8_t **)XX_Malloc(num * sizeof(uint8_t*));
+ if (!p_Mem->p_BlocksStack)
+ {
+ XX_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment block pointers stack"));
+ }
+
+ /* allocate the blocks bases array */
+ p_Mem->p_Bases = (uint8_t **)XX_Malloc(sizeof(uint8_t*));
+ if (!p_Mem->p_Bases)
+ {
+ MEM_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment base pointers array"));
+ }
+ memset(p_Mem->p_Bases, 0, sizeof(uint8_t*));
+
+ /* store info about this segment */
+ p_Mem->num = num;
+ p_Mem->current = 0;
+ p_Mem->dataSize = dataSize;
+ p_Mem->p_Bases[0] = p_Blocks;
+ p_Mem->getFailures = 0;
+ p_Mem->allocOwner = e_MEM_ALLOC_OWNER_EXTERNAL;
+ p_Mem->consecutiveMem = TRUE;
+ p_Mem->prefixSize = prefixSize;
+ p_Mem->postfixSize = postfixSize;
+ p_Mem->alignment = alignment;
+ /* store name */
+ strncpy(p_Mem->name, name, MEM_MAX_NAME_LENGTH-1);
+
+ p_Mem->h_Spinlock = XX_InitSpinlock();
+ if (!p_Mem->h_Spinlock)
+ {
+ MEM_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't create spinlock!"));
+ }
+
+ alignPad = (uint16_t)PAD_ALIGNMENT(4, prefixSize);
+ /* Make sure the entire size is a multiple of alignment */
+ endPad = (uint16_t)PAD_ALIGNMENT(alignment, (alignPad + prefixSize + dataSize + postfixSize));
+
+ /* The following manipulation places the data of block[0] in an aligned address,
+ since block size is aligned the following block datas will all be aligned */
+ ALIGN_BLOCK(p_Blocks, prefixSize, alignment);
+
+ blockSize = (uint32_t)(alignPad + prefixSize + dataSize + postfixSize + endPad);
+
+ /* initialize the blocks */
+ for (i=0; i < num; i++)
+ {
+ p_Mem->p_BlocksStack[i] = p_Blocks;
+ p_Blocks += blockSize;
+ }
+
+ /* return handle to caller */
+ *p_Handle = (t_Handle)p_Mem;
+
+#ifdef DEBUG_MEM_LEAKS
+ {
+ t_Error errCode = InitMemDebugDatabase(p_Mem);
+
+ if (errCode != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+
+ p_Mem->blockOffset = (uint32_t)(p_Mem->p_BlocksStack[0] - p_Mem->p_Bases[0]);
+ p_Mem->blockSize = blockSize;
+ }
+#endif /* DEBUG_MEM_LEAKS */
+
+ return E_OK;
+}
+
+
+/*****************************************************************************/
+t_Error MEM_InitSmart(char name[],
+ t_Handle *p_Handle,
+ uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment,
+ uint8_t memPartitionId,
+ bool consecutiveMem)
+{
+ t_MemorySegment *p_Mem;
+ uint32_t i, blockSize;
+ uint16_t alignPad, endPad;
+
+ /* prepare in case of error */
+ *p_Handle = NULL;
+
+ /* make sure that size is always a multiple of 4 */
+ if (dataSize & 3)
+ {
+ dataSize &= ~3;
+ dataSize += 4;
+ }
+
+ /* make sure that the alignment is at least 4 and power of 2 */
+ if (alignment < 4)
+ {
+ alignment = 4;
+ }
+ else if (!POWER_OF_2(alignment))
+ {
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Alignment (should be power of 2)"));
+ }
+
+ /* first allocate the segment descriptor */
+ p_Mem = (t_MemorySegment *)XX_Malloc(sizeof(t_MemorySegment));
+ if (!p_Mem)
+ {
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment structure"));
+ }
+
+ /* allocate the blocks stack */
+ p_Mem->p_BlocksStack = (uint8_t **)XX_Malloc(num * sizeof(uint8_t*));
+ if (!p_Mem->p_BlocksStack)
+ {
+ MEM_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment block pointers stack"));
+ }
+
+ /* allocate the blocks bases array */
+ p_Mem->p_Bases = (uint8_t **)XX_Malloc((consecutiveMem ? 1 : num) * sizeof(uint8_t*));
+ if (!p_Mem->p_Bases)
+ {
+ MEM_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment base pointers array"));
+ }
+ memset(p_Mem->p_Bases, 0, (consecutiveMem ? 1 : num) * sizeof(uint8_t*));
+
+ /* store info about this segment */
+ p_Mem->num = num;
+ p_Mem->current = 0;
+ p_Mem->dataSize = dataSize;
+ p_Mem->getFailures = 0;
+ p_Mem->allocOwner = e_MEM_ALLOC_OWNER_LOCAL_SMART;
+ p_Mem->consecutiveMem = consecutiveMem;
+ p_Mem->prefixSize = prefixSize;
+ p_Mem->postfixSize = postfixSize;
+ p_Mem->alignment = alignment;
+
+ p_Mem->h_Spinlock = XX_InitSpinlock();
+ if (!p_Mem->h_Spinlock)
+ {
+ MEM_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't create spinlock!"));
+ }
+
+ alignPad = (uint16_t)PAD_ALIGNMENT(4, prefixSize);
+ /* Make sure the entire size is a multiple of alignment */
+ endPad = (uint16_t)PAD_ALIGNMENT(alignment, alignPad + prefixSize + dataSize + postfixSize);
+
+ /* Calculate blockSize */
+ blockSize = (uint32_t)(alignPad + prefixSize + dataSize + postfixSize + endPad);
+
+ /* Now allocate the blocks */
+ if (p_Mem->consecutiveMem)
+ {
+ /* |alignment - 1| bytes at most will be discarded in the beginning of the
+ received segment for alignment reasons, therefore the allocation is of:
+ (alignment + (num * block size)). */
+ uint8_t *p_Blocks = (uint8_t *)
+ XX_MallocSmart((uint32_t)((num * blockSize) + alignment), memPartitionId, 1);
+ if (!p_Blocks)
+ {
+ MEM_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment blocks"));
+ }
+
+ /* Store the memory segment address */
+ p_Mem->p_Bases[0] = p_Blocks;
+
+ /* The following manipulation places the data of block[0] in an aligned address,
+ since block size is aligned the following block datas will all be aligned.*/
+ ALIGN_BLOCK(p_Blocks, prefixSize, alignment);
+
+ /* initialize the blocks */
+ for (i = 0; i < num; i++)
+ {
+ p_Mem->p_BlocksStack[i] = p_Blocks;
+ p_Blocks += blockSize;
+ }
+
+#ifdef DEBUG_MEM_LEAKS
+ p_Mem->blockOffset = (uint32_t)(p_Mem->p_BlocksStack[0] - p_Mem->p_Bases[0]);
+ p_Mem->blockSize = blockSize;
+#endif /* DEBUG_MEM_LEAKS */
+ }
+ else
+ {
+ /* |alignment - 1| bytes at most will be discarded in the beginning of the
+ received segment for alignment reasons, therefore the allocation is of:
+ (alignment + block size). */
+ for (i = 0; i < num; i++)
+ {
+ uint8_t *p_Block = (uint8_t *)
+ XX_MallocSmart((uint32_t)(blockSize + alignment), memPartitionId, 1);
+ if (!p_Block)
+ {
+ MEM_Free(p_Mem);
+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment blocks"));
+ }
+
+ /* Store the memory segment address */
+ p_Mem->p_Bases[i] = p_Block;
+
+ /* The following places the data of each block in an aligned address */
+ ALIGN_BLOCK(p_Block, prefixSize, alignment);
+
+#ifdef DEBUG_MEM_LEAKS
+ /* Need 4 bytes before the meaningful bytes to store the block index.
+ We know we have them because alignment is at least 4 bytes. */
+ if (p_Block == p_Mem->p_Bases[i])
+ p_Block += alignment;
+
+ *(uint32_t *)(p_Block - 4) = i;
+#endif /* DEBUG_MEM_LEAKS */
+
+ p_Mem->p_BlocksStack[i] = p_Block;
+ }
+ }
+
+ /* store name */
+ strncpy(p_Mem->name, name, MEM_MAX_NAME_LENGTH-1);
+
+ /* return handle to caller */
+ *p_Handle = (t_Handle)p_Mem;
+
+#ifdef DEBUG_MEM_LEAKS
+ {
+ t_Error errCode = InitMemDebugDatabase(p_Mem);
+
+ if (errCode != E_OK)
+ RETURN_ERROR(MAJOR, errCode, NO_MSG);
+ }
+#endif /* DEBUG_MEM_LEAKS */
+
+ return E_OK;
+}
+
+
+/*****************************************************************************/
+void MEM_Free(t_Handle h_Mem)
+{
+ t_MemorySegment *p_Mem = (t_MemorySegment*)h_Mem;
+ uint32_t num, i;
+
+ /* Check MEM leaks */
+ MEM_CheckLeaks(h_Mem);
+
+ if (p_Mem)
+ {
+ num = p_Mem->consecutiveMem ? 1 : p_Mem->num;
+
+ if (p_Mem->allocOwner == e_MEM_ALLOC_OWNER_LOCAL_SMART)
+ {
+ for (i=0; i < num; i++)
+ {
+ if (p_Mem->p_Bases[i])
+ {
+ XX_FreeSmart(p_Mem->p_Bases[i]);
+ }
+ }
+ }
+ else if (p_Mem->allocOwner == e_MEM_ALLOC_OWNER_LOCAL)
+ {
+ for (i=0; i < num; i++)
+ {
+ if (p_Mem->p_Bases[i])
+ {
+ XX_Free(p_Mem->p_Bases[i]);
+ }
+ }
+ }
+
+ if (p_Mem->h_Spinlock)
+ XX_FreeSpinlock(p_Mem->h_Spinlock);
+
+ if (p_Mem->p_Bases)
+ XX_Free(p_Mem->p_Bases);
+
+ if (p_Mem->p_BlocksStack)
+ XX_Free(p_Mem->p_BlocksStack);
+
+#ifdef DEBUG_MEM_LEAKS
+ if (p_Mem->p_MemDbg)
+ XX_Free(p_Mem->p_MemDbg);
+#endif /* DEBUG_MEM_LEAKS */
+
+ XX_Free(p_Mem);
+ }
+}
+
+
+/*****************************************************************************/
+void * MEM_Get(t_Handle h_Mem)
+{
+ t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem;
+ uint8_t *p_Block;
+ uint32_t intFlags;
+#ifdef DEBUG_MEM_LEAKS
+ uintptr_t callerAddr = 0;
+
+ GET_CALLER_ADDR;
+#endif /* DEBUG_MEM_LEAKS */
+
+ ASSERT_COND(h_Mem);
+
+ intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock);
+ /* check if there is an available block */
+ if ((p_Block = (uint8_t *)MemGet(p_Mem)) == NULL)
+ {
+ XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);
+ return NULL;
+ }
+
+#ifdef DEBUG_MEM_LEAKS
+ DebugMemGet(p_Mem, p_Block, callerAddr);
+#endif /* DEBUG_MEM_LEAKS */
+ XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);
+
+ return (void *)p_Block;
+}
+
+
+/*****************************************************************************/
+uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[])
+{
+ t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem;
+ uint32_t availableBlocks;
+ register uint32_t i;
+ uint32_t intFlags;
+#ifdef DEBUG_MEM_LEAKS
+ uintptr_t callerAddr = 0;
+
+ GET_CALLER_ADDR;
+#endif /* DEBUG_MEM_LEAKS */
+
+ ASSERT_COND(h_Mem);
+
+ intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock);
+ /* check how many blocks are available */
+ availableBlocks = (uint32_t)(p_Mem->num - p_Mem->current);
+ if (num > availableBlocks)
+ {
+ num = availableBlocks;
+ }
+
+ for (i=0; i < num; i++)
+ {
+ /* get pointer to block */
+ if ((array[i] = MemGet(p_Mem)) == NULL)
+ {
+ break;
+ }
+
+#ifdef DEBUG_MEM_LEAKS
+ DebugMemGet(p_Mem, array[i], callerAddr);
+#endif /* DEBUG_MEM_LEAKS */
+ }
+ XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);
+
+ return (uint16_t)i;
+}
+
+
+/*****************************************************************************/
+t_Error MEM_Put(t_Handle h_Mem, void *p_Block)
+{
+ t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem;
+ t_Error rc;
+ uint32_t intFlags;
+
+ ASSERT_COND(h_Mem);
+
+ intFlags = XX_LockIntrSpinlock(p_Mem->h_Spinlock);
+ /* check if blocks stack is full */
+ if ((rc = MemPut(p_Mem, p_Block)) != E_OK)
+ {
+ XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);
+ RETURN_ERROR(MAJOR, rc, NO_MSG);
+ }
+
+#ifdef DEBUG_MEM_LEAKS
+ DebugMemPut(p_Mem, p_Block);
+#endif /* DEBUG_MEM_LEAKS */
+ XX_UnlockIntrSpinlock(p_Mem->h_Spinlock, intFlags);
+
+ return E_OK;
+}
+
+
+#ifdef DEBUG_MEM_LEAKS
+
+/*****************************************************************************/
+void MEM_CheckLeaks(t_Handle h_Mem)
+{
+ t_MemorySegment *p_Mem = (t_MemorySegment *)h_Mem;
+ t_MemDbg *p_MemDbg = (t_MemDbg *)p_Mem->p_MemDbg;
+ uint8_t *p_Block;
+ int i;
+
+ ASSERT_COND(h_Mem);
+
+ if (p_Mem->consecutiveMem)
+ {
+ for (i=0; i < p_Mem->num; i++)
+ {
+ if (p_MemDbg[i].ownerAddress != ILLEGAL_BASE)
+ {
+ /* Find the block address */
+ p_Block = ((p_Mem->p_Bases[0] + p_Mem->blockOffset) +
+ (i * p_Mem->blockSize));
+
+ XX_Print("MEM leak: 0x%08x, Caller address: 0x%08x\n",
+ p_Block, p_MemDbg[i].ownerAddress);
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i < p_Mem->num; i++)
+ {
+ if (p_MemDbg[i].ownerAddress != ILLEGAL_BASE)
+ {
+ /* Find the block address */
+ p_Block = p_Mem->p_Bases[i];
+
+ ALIGN_BLOCK(p_Block, p_Mem->prefixSize, p_Mem->alignment);
+
+ if (p_Block == p_Mem->p_Bases[i])
+ p_Block += p_Mem->alignment;
+
+ XX_Print("MEM leak: 0x%08x, Caller address: 0x%08x\n",
+ p_Block, p_MemDbg[i].ownerAddress);
+ }
+ }
+ }
+}
+
+#endif /* DEBUG_MEM_LEAKS */
+
+
diff --git a/sys/contrib/ncsw/etc/sprint.c b/sys/contrib/ncsw/etc/sprint.c
new file mode 100644
index 0000000..6f9bdf9
--- /dev/null
+++ b/sys/contrib/ncsw/etc/sprint.c
@@ -0,0 +1,81 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*------------------------------------------------------*/
+/* File: sprint.c */
+/* */
+/* Description: */
+/* Debug routines (externals) */
+/*------------------------------------------------------*/
+#include "string_ext.h"
+#include "stdlib_ext.h"
+#include "ctype_ext.h"
+#include "stdarg_ext.h"
+#include "sprint_ext.h"
+#include "std_ext.h"
+#include "xx_ext.h"
+
+
+int Sprint(char * buf, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsprintf(buf,fmt,args);
+ va_end(args);
+ return i;
+}
+
+int Snprint(char * buf, uint32_t size, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsnprintf(buf,size,fmt,args);
+ va_end(args);
+ return i;
+}
+
+#ifndef NCSW_VXWORKS
+int Sscan(const char * buf, const char * fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args,fmt);
+ i = vsscanf(buf,fmt,args);
+ va_end(args);
+ return i;
+}
+#endif /* NCSW_VXWORKS */
diff --git a/sys/contrib/ncsw/inc/Peripherals/bm_ext.h b/sys/contrib/ncsw/inc/Peripherals/bm_ext.h
new file mode 100644
index 0000000..4585bba
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/bm_ext.h
@@ -0,0 +1,688 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File bm_ext.h
+
+ @Description BM API
+*//***************************************************************************/
+#ifndef __BM_EXT_H
+#define __BM_EXT_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group BM_grp Buffer Manager API
+
+ @Description BM API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description This callback type is used when handling pool depletion entry/exit.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] in - TRUE when entered depletion state
+ FALSE when exit the depletion state.
+ *//***************************************************************************/
+typedef void (t_BmDepletionCallback)(t_Handle h_App, bool in);
+
+/**************************************************************************//**
+ @Group BM_lib_grp BM common API
+
+ @Description BM common API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description BM Exceptions
+*//***************************************************************************/
+typedef enum e_BmExceptions {
+ e_BM_EX_INVALID_COMMAND = 0 , /**< Invalid Command Verb Interrupt */
+ e_BM_EX_FBPR_THRESHOLD, /**< FBPR Low Watermark Interrupt. */
+ e_BM_EX_SINGLE_ECC, /**< Single Bit ECC Error Interrupt. */
+ e_BM_EX_MULTI_ECC /**< Multi Bit ECC Error Interrupt */
+} e_BmExceptions;
+
+
+/**************************************************************************//**
+ @Group BM_init_grp BM (common) Initialization Unit
+
+ @Description BM (common) Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function t_BmExceptionsCallback
+
+ @Description Exceptions user callback routine, will be called upon an
+ exception passing the exception identification.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] exception - The exception.
+*//***************************************************************************/
+typedef void (t_BmExceptionsCallback) (t_Handle h_App,
+ e_BmExceptions exception);
+
+/**************************************************************************//**
+ @Description structure representing BM initialization parameters
+*//***************************************************************************/
+typedef struct {
+ uint8_t guestId; /**< BM Partition Id */
+
+ uintptr_t baseAddress; /**< Bm base address (virtual).
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+ uint16_t liodn; /**< This value is attached to every transaction initiated by
+ BMan when accessing its private data structures
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+ uint32_t totalNumOfBuffers; /**< Total number of buffers
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+ uint32_t fbprMemPartitionId; /**< FBPR's mem partition id;
+ NOTE: The memory partition must be non-cacheable and no-coherent area.
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+ t_BmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions.
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks.
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+ int errIrq; /**< BM error interrupt line; NO_IRQ if interrupts not used.
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+
+ uint8_t partBpidBase; /**< The first buffer-pool-id dedicated to this partition.
+ NOTE: this parameter relevant only when working with multiple partitions. */
+ uint8_t partNumOfPools; /**< Number of Pools dedicated to this partition.
+ NOTE: this parameter relevant only when working with multiple partitions. */
+} t_BmParam;
+
+
+/**************************************************************************//**
+ @Function BM_Config
+
+ @Description Creates descriptor for the BM module and initializes the BM module.
+
+ The routine returns a handle (descriptor) to the BM object.
+ This descriptor must be passed as first parameter to all other
+ BM function calls.
+
+ @Param[in] p_BmParam - A pointer to data structure of parameters
+
+ @Return Handle to BM object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle BM_Config(t_BmParam *p_BmParam);
+
+/**************************************************************************//**
+ @Function BM_Init
+
+ @Description Initializes the BM module
+
+ @Param[in] h_Bm - A handle to the BM module
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following BM_Config().
+*//***************************************************************************/
+t_Error BM_Init(t_Handle h_Bm);
+
+/**************************************************************************//**
+ @Function BM_Free
+
+ @Description Frees all resources that were assigned to BM module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_Bm - A handle to the BM module
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error BM_Free(t_Handle h_Bm);
+
+/**************************************************************************//**
+ @Group BM_advanced_init_grp BM (common) Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function BM_ConfigFbprThreshold
+
+ @Description Change the fbpr threshold from its default
+ configuration [0].
+ An interrupt if enables is asserted when the number of FBPRs is below this threshold.
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID).
+
+ @Param[in] h_Bm - A handle to the BM module
+ @Param[in] threshold - threshold value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following BM_Config() and before BM_Init().
+*//***************************************************************************/
+t_Error BM_ConfigFbprThreshold(t_Handle h_Bm, uint32_t threshold);
+
+/** @} */ /* end of BM_advanced_init_grp group */
+/** @} */ /* end of BM_init_grp group */
+
+/**************************************************************************//**
+ @Group BM_runtime_control_grp BM (common) Runtime Control Unit
+
+ @Description BM (common) Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for defining BM counters
+*//***************************************************************************/
+typedef enum e_BmCounters {
+ e_BM_COUNTERS_FBPR = 0 /**< Total Free Buffer Proxy Record (FBPR) Free Pool Count in external memory */
+} e_BmCounters;
+
+/**************************************************************************//**
+ @Description structure for returning revision information
+*//***************************************************************************/
+typedef struct t_BmRevisionInfo {
+ uint8_t majorRev; /**< Major revision */
+ uint8_t minorRev; /**< Minor revision */
+} t_BmRevisionInfo;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function BM_DumpRegs
+
+ @Description Dumps all BM registers
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID).
+
+ @Param[in] h_Bm A handle to an BM Module.
+
+ @Return E_OK on success;
+
+ @Cautions Allowed only after BM_Init().
+*//***************************************************************************/
+t_Error BM_DumpRegs(t_Handle h_Bm);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+/**************************************************************************//**
+ @Function BM_SetException
+
+ @Description Calling this routine enables/disables the specified exception.
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID).
+
+ @Param[in] h_Bm - A handle to the BM Module.
+ @Param[in] exception - The exception to be selected.
+ @Param[in] enable - TRUE to enable interrupt, FALSE to mask it.
+
+ @Cautions Allowed only following BM_Init().
+*//***************************************************************************/
+t_Error BM_SetException(t_Handle h_Bm, e_BmExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function BM_ErrorIsr
+
+ @Description BM interrupt-service-routine for errors.
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID).
+
+ @Param[in] h_Bm - A handle to the BM Module.
+
+ @Cautions Allowed only following BM_Init().
+*//***************************************************************************/
+void BM_ErrorIsr(t_Handle h_Bm);
+
+/**************************************************************************//**
+ @Function BM_GetCounter
+
+ @Description Reads one of the BM counters.
+
+ @Param[in] h_Bm - A handle to the BM Module.
+ @Param[in] counter - The requested counter.
+
+ @Return Counter's current value.
+*//***************************************************************************/
+uint32_t BM_GetCounter(t_Handle h_Bm, e_BmCounters counter);
+
+/**************************************************************************//**
+ @Function BM_GetRevision
+
+ @Description Returns the BM revision
+
+ @Param[in] h_Bm A handle to a BM Module.
+ @Param[out] p_BmRevisionInfo A structure of revision information parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init().
+*//***************************************************************************/
+t_Error BM_GetRevision(t_Handle h_Bm, t_BmRevisionInfo *p_BmRevisionInfo);
+
+/** @} */ /* end of BM_runtime_control_grp group */
+/** @} */ /* end of BM_lib_grp group */
+
+
+/**************************************************************************//**
+ @Group BM_portal_grp BM-Portal API
+
+ @Description BM-Portal API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group BM_portal_init_grp BM-Portal Initialization Unit
+
+ @Description BM-Portal Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description structure representing BM Portal initialization parameters
+*//***************************************************************************/
+typedef struct {
+ uintptr_t ceBaseAddress; /**< Cache-enabled base address (virtual) */
+ uintptr_t ciBaseAddress; /**< Cache-inhibited base address (virtual) */
+ t_Handle h_Bm; /**< Bm Handle */
+ e_DpaaSwPortal swPortalId; /**< Portal id */
+ int irq; /**< portal interrupt line; NO_IRQ if interrupts not used */
+} t_BmPortalParam;
+
+
+/**************************************************************************//**
+ @Function BM_PORTAL_Config
+
+ @Description Creates descriptor for the BM Portal;
+
+ The routine returns a handle (descriptor) to a BM-Portal object;
+ This descriptor must be passed as first parameter to all other
+ BM-Portal function calls.
+
+ No actual initialization or configuration of QM-Portal hardware is
+ done by this routine.
+
+ @Param[in] p_BmPortalParam - Pointer to data structure of parameters
+
+ @Retval Handle to a BM-Portal object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle BM_PORTAL_Config(t_BmPortalParam *p_BmPortalParam);
+
+/**************************************************************************//**
+ @Function BM_PORTAL_Init
+
+ @Description Initializes a BM-Portal module
+
+ @Param[in] h_BmPortal - A handle to a BM-Portal module
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error BM_PORTAL_Init(t_Handle h_BmPortal);
+
+/**************************************************************************//**
+ @Function BM_PortalFree
+
+ @Description Frees all resources that were assigned to BM Portal module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_BmPortal - BM Portal module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error BM_PORTAL_Free(t_Handle h_BmPortal);
+
+/**************************************************************************//**
+ @Function BM_PORTAL_ConfigMemAttr
+
+ @Description Change the memory attributes
+ from its default configuration [MEMORY_ATTR_CACHEABLE].
+
+ @Param[in] h_BmPortal - A handle to a BM-Portal module
+ @Param[in] hwExtStructsMemAttr - memory attributes (cache/non-cache, etc.)
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following BM_PORTAL_Config() and before BM_PORTAL_Init().
+*//***************************************************************************/
+t_Error BM_PORTAL_ConfigMemAttr(t_Handle h_BmPortal, uint32_t hwExtStructsMemAttr);
+
+/** @} */ /* end of BM_portal_init_grp group */
+/** @} */ /* end of BM_portal_grp group */
+
+
+/**************************************************************************//**
+ @Group BM_pool_grp BM-Pool API
+
+ @Description BM-Pool API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group BM_pool_init_grp BM-Pool Initialization Unit
+
+ @Description BM-Pool Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Collection BM Pool Depletion Thresholds macros
+ The thresholds are represent by an array of size MAX_DEPLETION_THRESHOLDS
+ Use the following macros to access the appropriate location in the array.
+*//***************************************************************************/
+#define BM_POOL_DEP_THRESH_SW_ENTRY 0
+#define BM_POOL_DEP_THRESH_SW_EXIT 1
+#define BM_POOL_DEP_THRESH_HW_ENTRY 2
+#define BM_POOL_DEP_THRESH_HW_EXIT 3
+
+#define MAX_DEPLETION_THRESHOLDS 4
+/* @} */
+
+
+/**************************************************************************//**
+ @Description structure representing BM Pool initialization parameters
+*//***************************************************************************/
+typedef struct {
+ t_Handle h_Bm; /**< A handle to a BM Module. */
+ t_Handle h_BmPortal; /**< A handle to a BM Portal Module.
+ will be used only for Init and Free routines.
+ NOTE: if NULL, assuming affinity */
+ uint32_t numOfBuffers; /**< Number of buffers use by this pool
+ NOTE: If zero, empty pool buffer is created. */
+ t_BufferPoolInfo bufferPoolInfo; /**< Data buffers pool information */
+ t_Handle h_App; /**< opaque user value passed as a parameter to callbacks */
+ bool shadowMode; /**< If TRUE, numOfBuffers will be set to '0'. */
+ uint8_t bpid; /**< index of the shadow buffer pool (0-BM_MAX_NUM_OF_POOLS).
+ valid only if shadowMode='TRUE'. */
+} t_BmPoolParam;
+
+
+/**************************************************************************//**
+ @Function BM_POOL_Config
+
+ @Description Creates descriptor for the BM Pool;
+
+ The routine returns a handle (descriptor) to the BM Pool object.
+
+ @Param[in] p_BmPoolParam - A pointer to data structure of parameters
+
+ @Return Handle to BM Portal object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle BM_POOL_Config(t_BmPoolParam *p_BmPoolParam);
+
+/**************************************************************************//**
+ @Function BM_POOL_Init
+
+ @Description Initializes a BM-Pool module
+
+ @Param[in] h_BmPool - A handle to a BM-Pool module
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error BM_POOL_Init(t_Handle h_BmPool);
+
+/**************************************************************************//**
+ @Function BM_PoolFree
+
+ @Description Frees all resources that were assigned to BM Pool module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_BmPool - BM Pool module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error BM_POOL_Free(t_Handle h_BmPool);
+
+/**************************************************************************//**
+ @Function BM_POOL_ConfigBpid
+
+ @Description Config a specific pool id rather than dynamic pool id.
+
+ @Param[in] h_BmPool - A handle to a BM-Pool module
+ @Param[in] bpid - index of the buffer pool (0-BM_MAX_NUM_OF_POOLS).
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following BM_POOL_Config() and before BM_POOL_Init().
+*//***************************************************************************/
+t_Error BM_POOL_ConfigBpid(t_Handle h_BmPool, uint8_t bpid);
+
+/**************************************************************************//**
+ @Function BM_POOL_ConfigDepletion
+
+ @Description Config depletion-entry/exit thresholds and callback.
+
+ @Param[in] h_BmPool - A handle to a BM-Pool module
+ @Param[in] f_Depletion - depletion-entry/exit callback.
+ @Param[in] thresholds - depletion-entry/exit thresholds.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following BM_POOL_Config() and before BM_POOL_Init();
+ Allowed only if shadowMode='FALSE'.
+ Allowed only if BM in master mode ('guestId'=NCSW_MASTER_ID), or
+ the BM is in guest mode BUT than this routine will invoke IPC
+ call to the master.
+*//***************************************************************************/
+t_Error BM_POOL_ConfigDepletion(t_Handle h_BmPool,
+ t_BmDepletionCallback *f_Depletion,
+ uint32_t thresholds[MAX_DEPLETION_THRESHOLDS]);
+
+/**************************************************************************//**
+ @Function BM_POOL_ConfigStockpile
+
+ @Description Config software stockpile.
+
+ @Param[in] h_BmPool - A handle to a BM-Pool module
+ @Param[in] maxBuffers - the software data structure size saved for stockpile;
+ when reached this value, release to hw command performed.
+ @Param[in] minBuffers - if current capacity is equal or lower then this value,
+ acquire from hw command performed.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following BM_POOL_Config() and before BM_POOL_Init().
+*//***************************************************************************/
+t_Error BM_POOL_ConfigStockpile(t_Handle h_BmPool, uint16_t maxBuffers, uint16_t minBuffers);
+
+/**************************************************************************//**
+ @Function BM_POOL_ConfigBuffContextMode
+
+ @Description Config the BM pool to set/unset buffer-context
+
+ @Param[in] h_BmPool - A handle to a BM-Pool module
+ @Param[in] en - enable/disable buffer context mode
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following BM_POOL_Config() and before BM_POOL_Init().
+*//***************************************************************************/
+t_Error BM_POOL_ConfigBuffContextMode(t_Handle h_BmPool, bool en);
+
+/** @} */ /* end of BM_pool_init_grp group */
+
+
+/**************************************************************************//**
+ @Group BM_pool_runtime_control_grp BM-Pool Runtime Control Unit
+
+ @Description BM-Pool Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for defining BM Pool counters
+*//***************************************************************************/
+typedef enum e_BmPoolCounters {
+ e_BM_POOL_COUNTERS_CONTENT = 0, /**< number of free buffers for a particular pool */
+ e_BM_POOL_COUNTERS_SW_DEPLETION, /**< number of times pool entered sw depletion */
+ e_BM_POOL_COUNTERS_HW_DEPLETION /**< number of times pool entered hw depletion */
+} e_BmPoolCounters;
+
+/**************************************************************************//**
+ @Function BM_POOL_GetId
+
+ @Description return a buffer pool id.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+
+ @Return Pool ID.
+*//***************************************************************************/
+uint8_t BM_POOL_GetId(t_Handle h_BmPool);
+
+/**************************************************************************//**
+ @Function BM_POOL_GetBufferSize
+
+ @Description returns the pool's buffer size.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+
+ @Return pool's buffer size.
+*//***************************************************************************/
+uint16_t BM_POOL_GetBufferSize(t_Handle h_BmPool);
+
+/**************************************************************************//**
+ @Function BM_POOL_GetBufferContext
+
+ @Description Returns the user's private context that
+ should be associated with the buffer.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+ @Param[in] p_Buff - A Pointer to the buffer
+
+ @Return user's private context.
+*//***************************************************************************/
+t_Handle BM_POOL_GetBufferContext(t_Handle h_BmPool, void *p_Buff);
+
+/**************************************************************************//**
+ @Function BM_POOL_PhysToVirt
+
+ @Description Translates a physical address to the matching virtual address.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+ @Param[in] addr - The physical address to translate
+
+ @Return Virtual address.
+*//***************************************************************************/
+void * BM_POOL_PhysToVirt(t_Handle h_BmPool, physAddress_t addr);
+
+/**************************************************************************//**
+ @Function BM_POOL_VirtToPhys
+
+ @Description Translates a virtual address to the matching physical address.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+ @Param[in] addr - The virtual address to translate
+
+ @Return Physical address.
+*//***************************************************************************/
+physAddress_t BM_POOL_VirtToPhys(t_Handle h_BmPool, void *addr);
+
+/**************************************************************************//**
+ @Function BM_POOL_GetCounter
+
+ @Description Reads one of the BM Pool counters.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+ @Param[in] counter - The requested counter.
+
+ @Return Counter's current value.
+*//***************************************************************************/
+uint32_t BM_POOL_GetCounter(t_Handle h_BmPool, e_BmPoolCounters counter);
+
+/** @} */ /* end of BM_pool_runtime_control_grp group */
+
+
+/**************************************************************************//**
+ @Group BM_pool_runtime_data_grp BM-Pool Runtime Data Unit
+
+ @Description BM-Pool Runtime data unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function BM_POOL_GetBuf
+
+ @Description Allocate buffer from a buffer pool.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+ @Param[in] h_BmPortal - A handle to a BM Portal Module;
+ NOTE : if NULL, assuming affinity.
+
+ @Return A Pointer to the allocated buffer.
+*//***************************************************************************/
+void * BM_POOL_GetBuf(t_Handle h_BmPool, t_Handle h_BmPortal);
+
+/**************************************************************************//**
+ @Function BM_POOL_PutBuf
+
+ @Description Deallocate buffer to a buffer pool.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+ @Param[in] h_BmPortal - A handle to a BM Portal Module;
+ NOTE : if NULL, assuming affinity.
+ @Param[in] p_Buff - A Pointer to the buffer.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error BM_POOL_PutBuf(t_Handle h_BmPool, t_Handle h_BmPortal, void *p_Buff);
+
+/**************************************************************************//**
+ @Function BM_POOL_FillBufs
+
+ @Description Fill a BM pool with new buffers.
+
+ @Param[in] h_BmPool - A handle to a BM-pool
+ @Param[in] h_BmPortal - A handle to a BM Portal Module;
+ NOTE : if NULL, assuming affinity.
+ @Param[in] numBufs - How many buffers to fill into the pool.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error BM_POOL_FillBufs(t_Handle h_BmPool, t_Handle h_BmPortal, uint32_t numBufs);
+
+/** @} */ /* end of BM_pool_runtime_data_grp group */
+/** @} */ /* end of BM_pool_grp group */
+/** @} */ /* end of BM_grp group */
+
+#endif /* __BM_EXT_H */
diff --git a/sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h b/sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h
new file mode 100644
index 0000000..5990f71
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/crc_mac_addr_ext.h
@@ -0,0 +1,363 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*------------------------------------------------------*/
+/* */
+/* File: crc_mac_addr_ext.h */
+/* */
+/* Description: */
+/* Define a macro that calculate the crc value of */
+/* an Ethernet MAC address (48 bitd address */
+/*------------------------------------------------------*/
+
+#ifndef __crc_mac_addr_ext_h
+#define __crc_mac_addr_ext_h
+
+#include "std_ext.h"
+
+
+static uint32_t crc_table[256] =
+{
+ 0x00000000,
+ 0x77073096,
+ 0xee0e612c,
+ 0x990951ba,
+ 0x076dc419,
+ 0x706af48f,
+ 0xe963a535,
+ 0x9e6495a3,
+ 0x0edb8832,
+ 0x79dcb8a4,
+ 0xe0d5e91e,
+ 0x97d2d988,
+ 0x09b64c2b,
+ 0x7eb17cbd,
+ 0xe7b82d07,
+ 0x90bf1d91,
+ 0x1db71064,
+ 0x6ab020f2,
+ 0xf3b97148,
+ 0x84be41de,
+ 0x1adad47d,
+ 0x6ddde4eb,
+ 0xf4d4b551,
+ 0x83d385c7,
+ 0x136c9856,
+ 0x646ba8c0,
+ 0xfd62f97a,
+ 0x8a65c9ec,
+ 0x14015c4f,
+ 0x63066cd9,
+ 0xfa0f3d63,
+ 0x8d080df5,
+ 0x3b6e20c8,
+ 0x4c69105e,
+ 0xd56041e4,
+ 0xa2677172,
+ 0x3c03e4d1,
+ 0x4b04d447,
+ 0xd20d85fd,
+ 0xa50ab56b,
+ 0x35b5a8fa,
+ 0x42b2986c,
+ 0xdbbbc9d6,
+ 0xacbcf940,
+ 0x32d86ce3,
+ 0x45df5c75,
+ 0xdcd60dcf,
+ 0xabd13d59,
+ 0x26d930ac,
+ 0x51de003a,
+ 0xc8d75180,
+ 0xbfd06116,
+ 0x21b4f4b5,
+ 0x56b3c423,
+ 0xcfba9599,
+ 0xb8bda50f,
+ 0x2802b89e,
+ 0x5f058808,
+ 0xc60cd9b2,
+ 0xb10be924,
+ 0x2f6f7c87,
+ 0x58684c11,
+ 0xc1611dab,
+ 0xb6662d3d,
+ 0x76dc4190,
+ 0x01db7106,
+ 0x98d220bc,
+ 0xefd5102a,
+ 0x71b18589,
+ 0x06b6b51f,
+ 0x9fbfe4a5,
+ 0xe8b8d433,
+ 0x7807c9a2,
+ 0x0f00f934,
+ 0x9609a88e,
+ 0xe10e9818,
+ 0x7f6a0dbb,
+ 0x086d3d2d,
+ 0x91646c97,
+ 0xe6635c01,
+ 0x6b6b51f4,
+ 0x1c6c6162,
+ 0x856530d8,
+ 0xf262004e,
+ 0x6c0695ed,
+ 0x1b01a57b,
+ 0x8208f4c1,
+ 0xf50fc457,
+ 0x65b0d9c6,
+ 0x12b7e950,
+ 0x8bbeb8ea,
+ 0xfcb9887c,
+ 0x62dd1ddf,
+ 0x15da2d49,
+ 0x8cd37cf3,
+ 0xfbd44c65,
+ 0x4db26158,
+ 0x3ab551ce,
+ 0xa3bc0074,
+ 0xd4bb30e2,
+ 0x4adfa541,
+ 0x3dd895d7,
+ 0xa4d1c46d,
+ 0xd3d6f4fb,
+ 0x4369e96a,
+ 0x346ed9fc,
+ 0xad678846,
+ 0xda60b8d0,
+ 0x44042d73,
+ 0x33031de5,
+ 0xaa0a4c5f,
+ 0xdd0d7cc9,
+ 0x5005713c,
+ 0x270241aa,
+ 0xbe0b1010,
+ 0xc90c2086,
+ 0x5768b525,
+ 0x206f85b3,
+ 0xb966d409,
+ 0xce61e49f,
+ 0x5edef90e,
+ 0x29d9c998,
+ 0xb0d09822,
+ 0xc7d7a8b4,
+ 0x59b33d17,
+ 0x2eb40d81,
+ 0xb7bd5c3b,
+ 0xc0ba6cad,
+ 0xedb88320,
+ 0x9abfb3b6,
+ 0x03b6e20c,
+ 0x74b1d29a,
+ 0xead54739,
+ 0x9dd277af,
+ 0x04db2615,
+ 0x73dc1683,
+ 0xe3630b12,
+ 0x94643b84,
+ 0x0d6d6a3e,
+ 0x7a6a5aa8,
+ 0xe40ecf0b,
+ 0x9309ff9d,
+ 0x0a00ae27,
+ 0x7d079eb1,
+ 0xf00f9344,
+ 0x8708a3d2,
+ 0x1e01f268,
+ 0x6906c2fe,
+ 0xf762575d,
+ 0x806567cb,
+ 0x196c3671,
+ 0x6e6b06e7,
+ 0xfed41b76,
+ 0x89d32be0,
+ 0x10da7a5a,
+ 0x67dd4acc,
+ 0xf9b9df6f,
+ 0x8ebeeff9,
+ 0x17b7be43,
+ 0x60b08ed5,
+ 0xd6d6a3e8,
+ 0xa1d1937e,
+ 0x38d8c2c4,
+ 0x4fdff252,
+ 0xd1bb67f1,
+ 0xa6bc5767,
+ 0x3fb506dd,
+ 0x48b2364b,
+ 0xd80d2bda,
+ 0xaf0a1b4c,
+ 0x36034af6,
+ 0x41047a60,
+ 0xdf60efc3,
+ 0xa867df55,
+ 0x316e8eef,
+ 0x4669be79,
+ 0xcb61b38c,
+ 0xbc66831a,
+ 0x256fd2a0,
+ 0x5268e236,
+ 0xcc0c7795,
+ 0xbb0b4703,
+ 0x220216b9,
+ 0x5505262f,
+ 0xc5ba3bbe,
+ 0xb2bd0b28,
+ 0x2bb45a92,
+ 0x5cb36a04,
+ 0xc2d7ffa7,
+ 0xb5d0cf31,
+ 0x2cd99e8b,
+ 0x5bdeae1d,
+ 0x9b64c2b0,
+ 0xec63f226,
+ 0x756aa39c,
+ 0x026d930a,
+ 0x9c0906a9,
+ 0xeb0e363f,
+ 0x72076785,
+ 0x05005713,
+ 0x95bf4a82,
+ 0xe2b87a14,
+ 0x7bb12bae,
+ 0x0cb61b38,
+ 0x92d28e9b,
+ 0xe5d5be0d,
+ 0x7cdcefb7,
+ 0x0bdbdf21,
+ 0x86d3d2d4,
+ 0xf1d4e242,
+ 0x68ddb3f8,
+ 0x1fda836e,
+ 0x81be16cd,
+ 0xf6b9265b,
+ 0x6fb077e1,
+ 0x18b74777,
+ 0x88085ae6,
+ 0xff0f6a70,
+ 0x66063bca,
+ 0x11010b5c,
+ 0x8f659eff,
+ 0xf862ae69,
+ 0x616bffd3,
+ 0x166ccf45,
+ 0xa00ae278,
+ 0xd70dd2ee,
+ 0x4e048354,
+ 0x3903b3c2,
+ 0xa7672661,
+ 0xd06016f7,
+ 0x4969474d,
+ 0x3e6e77db,
+ 0xaed16a4a,
+ 0xd9d65adc,
+ 0x40df0b66,
+ 0x37d83bf0,
+ 0xa9bcae53,
+ 0xdebb9ec5,
+ 0x47b2cf7f,
+ 0x30b5ffe9,
+ 0xbdbdf21c,
+ 0xcabac28a,
+ 0x53b39330,
+ 0x24b4a3a6,
+ 0xbad03605,
+ 0xcdd70693,
+ 0x54de5729,
+ 0x23d967bf,
+ 0xb3667a2e,
+ 0xc4614ab8,
+ 0x5d681b02,
+ 0x2a6f2b94,
+ 0xb40bbe37,
+ 0xc30c8ea1,
+ 0x5a05df1b,
+ 0x2d02ef8d
+};
+
+
+#define GET_MAC_ADDR_CRC(addr, crc) \
+{ \
+ uint32_t i; \
+ uint8_t data; \
+ \
+ /* CRC calculation */ \
+ crc = 0xffffffff; \
+ for (i=0; i < 6; i++) \
+ { \
+ data = (uint8_t)(addr >> ((5-i)*8)); \
+ crc = crc^data; \
+ crc = crc_table[crc&0xff] ^ (crc>>8); \
+ } \
+} \
+
+/* Define a macro for getting the mirrored value of */
+/* a byte size number. (0x11010011 --> 0x11001011) */
+/* Sometimes the mirrored value of the CRC is required */
+static __inline__ uint8_t GetMirror(uint8_t n)
+{
+ uint8_t mirror[16] =
+ {
+ 0x00,
+ 0x08,
+ 0x04,
+ 0x0c,
+ 0x02,
+ 0x0a,
+ 0x06,
+ 0x0e,
+ 0x01,
+ 0x09,
+ 0x05,
+ 0x0d,
+ 0x03,
+ 0x0b,
+ 0x07,
+ 0x0f
+ };
+ return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
+}
+
+static __inline__ uint32_t GetMirror32(uint32_t n)
+{
+ return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
+ ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
+ ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
+ ((uint32_t)GetMirror((uint8_t)(n>>24))));
+}
+
+#define MIRROR GetMirror
+#define MIRROR_32 GetMirror32
+
+
+#endif /* __crc_mac_addr_ext_h */
diff --git a/sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h b/sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h
new file mode 100644
index 0000000..282f415
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/dpaa_ext.h
@@ -0,0 +1,206 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+ @File dpaa_ext.h
+
+ @Description DPAA Application Programming Interface.
+*//***************************************************************************/
+#ifndef __DPAA_EXT_H
+#define __DPAA_EXT_H
+
+#include "std_ext.h"
+#include "error_ext.h"
+
+
+/**************************************************************************//**
+ @Group DPAA_grp Data Path Acceleration Architecture API
+
+ @Description DPAA API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/**************************************************************************//**
+ @Description Frame descriptor
+*//***************************************************************************/
+typedef _Packed struct t_DpaaFD {
+ volatile uint32_t id; /**< FD id */
+ volatile uint32_t addrl; /**< Data Address */
+ volatile uint32_t length; /**< Frame length */
+ volatile uint32_t status; /**< FD status */
+} _PackedType t_DpaaFD;
+
+/**************************************************************************//**
+ @Description enum for defining frame format
+*//***************************************************************************/
+typedef enum e_DpaaFDFormatType {
+ e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
+ small length (9b OFFSET, 20b LENGTH) */
+ e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
+ (29b LENGTH ,No OFFSET) */
+ e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
+ and small length (9b OFFSET, 20b LENGTH) */
+ e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
+ big length (29b LENGTH ,No OFFSET) */
+ e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
+ No LENGTH or OFFSET) */
+ e_DPAA_FD_FORMAT_TYPE_DUMMY
+} e_DpaaFDFormatType;
+
+/**************************************************************************//**
+ @Collection Frame descriptor macros
+*//***************************************************************************/
+#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
+#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
+#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
+#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
+#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
+#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
+#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
+#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
+#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
+
+#define DPAA_FD_GET_DD(fd) ((((t_DpaaFD *)fd)->id & DPAA_FD_DD_MASK) >> (31-1)) /**< Macro to get FD DD field */
+#define DPAA_FD_GET_PID(fd) (((((t_DpaaFD *)fd)->id & DPAA_FD_PID_MASK) >> (31-7)) | \
+ ((((t_DpaaFD *)fd)->id & DPAA_FD_ELIODN_MASK) >> (31-19-6))) /**< Macro to get FD PID field */
+#define DPAA_FD_GET_BPID(fd) ((((t_DpaaFD *)fd)->id & DPAA_FD_BPID_MASK) >> (31-15)) /**< Macro to get FD BPID field */
+#define DPAA_FD_GET_ADDRH(fd) (((t_DpaaFD *)fd)->id & DPAA_FD_ADDRH_MASK) /**< Macro to get FD ADDRH field */
+#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
+#define DPAA_FD_GET_PHYS_ADDR(fd) ((physAddress_t)(((uint64_t)DPAA_FD_GET_ADDRH(fd) << 32) | (uint64_t)DPAA_FD_GET_ADDRL(fd))) /**< Macro to get FD ADDR field */
+#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
+#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
+#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
+#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
+#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd))
+
+#define DPAA_FD_SET_DD(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_DD_MASK) | (((val) << (31-1)) & DPAA_FD_DD_MASK ))) /**< Macro to set FD DD field */
+ /**< Macro to set FD PID field or LIODN offset*/
+#define DPAA_FD_SET_PID(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~(DPAA_FD_PID_MASK|DPAA_FD_ELIODN_MASK)) | ((((val) << (31-7)) & DPAA_FD_PID_MASK) | ((((val)>>6) << (31-19)) & DPAA_FD_ELIODN_MASK))))
+#define DPAA_FD_SET_BPID(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_BPID_MASK) | (((val) << (31-15)) & DPAA_FD_BPID_MASK))) /**< Macro to set FD BPID field */
+#define DPAA_FD_SET_ADDRH(fd,val) (((t_DpaaFD *)fd)->id = ((((t_DpaaFD *)fd)->id & ~DPAA_FD_ADDRH_MASK) | ((val) & DPAA_FD_ADDRH_MASK))) /**< Macro to set FD ADDRH field */
+#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
+#define DPAA_FD_SET_ADDR(fd,val) \
+do { \
+ uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
+ DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
+ DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
+} while (0) /**< Macro to set FD ADDR field */
+#define DPAA_FD_SET_FORMAT(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_FORMAT_MASK) | (((val) << (31-2))& DPAA_FD_FORMAT_MASK))) /**< Macro to set FD FORMAT field */
+#define DPAA_FD_SET_OFFSET(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_OFFSET_MASK) | (((val) << (31-11))& DPAA_FD_OFFSET_MASK) )) /**< Macro to set FD OFFSET field */
+#define DPAA_FD_SET_LENGTH(fd,val) (((t_DpaaFD *)fd)->length = (((t_DpaaFD *)fd)->length & ~DPAA_FD_LENGTH_MASK) | ((val) & DPAA_FD_LENGTH_MASK)) /**< Macro to set FD LENGTH field */
+#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
+/* @} */
+
+/**************************************************************************//**
+ @Description Frame Scatter/Gather Table Entry
+*//***************************************************************************/
+typedef _Packed struct t_DpaaSGTE {
+ volatile uint32_t addrh; /**< Buffer Address high */
+ volatile uint32_t addrl; /**< Buffer Address low */
+ volatile uint32_t length; /**< Buffer length */
+ volatile uint32_t offset; /**< SGTE offset */
+} _PackedType t_DpaaSGTE;
+
+#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
+
+/**************************************************************************//**
+ @Description Frame Scatter/Gather Table
+*//***************************************************************************/
+typedef _Packed struct t_DpaaSGT {
+ t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
+ /**< structure that hold the information about
+ a single S/G entry. */
+} _PackedType t_DpaaSGT;
+
+/**************************************************************************//**
+ @Description Compound Frame Table
+*//***************************************************************************/
+typedef _Packed struct t_DpaaCompTbl {
+ t_DpaaSGTE outputBuffInfo; /**< structure that holds the information about
+ the compound-frame output buffer;
+ NOTE: this may point to a S/G table */
+ t_DpaaSGTE inputBuffInfo; /**< structure that holds the information about
+ the compound-frame input buffer;
+ NOTE: this may point to a S/G table */
+} _PackedType t_DpaaCompTbl;
+
+/**************************************************************************//**
+ @Collection Frame Scatter/Gather Table Entry macros
+*//***************************************************************************/
+#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
+#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
+#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
+#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
+#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
+#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
+#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
+
+#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
+#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
+#define DPAA_SGTE_GET_PHYS_ADDR(sgte) ((physAddress_t)(((uint64_t)DPAA_SGTE_GET_ADDRH(sgte) << 32) | (uint64_t)DPAA_SGTE_GET_ADDRL(sgte))) /**< Macro to get FD ADDR field */
+#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
+#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
+#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
+#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
+#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
+#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
+
+#define DPAA_SGTE_SET_ADDRH(sgte,val) (((t_DpaaSGTE *)sgte)->addrh = ((((t_DpaaSGTE *)sgte)->addrh & ~DPAA_SGTE_ADDRH_MASK) | ((val) & DPAA_SGTE_ADDRH_MASK))) /**< Macro to set SGTE ADDRH field */
+#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
+#define DPAA_SGTE_SET_ADDR(sgte,val) \
+do { \
+ uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
+ DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
+ DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
+} while (0) /**< Macro to set SGTE ADDR field */
+#define DPAA_SGTE_SET_EXTENSION(sgte,val) (((t_DpaaSGTE *)sgte)->length = ((((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_E_MASK) | (((val) << (31-0))& DPAA_SGTE_E_MASK))) /**< Macro to set SGTE EXTENSION field */
+#define DPAA_SGTE_SET_FINAL(sgte,val) (((t_DpaaSGTE *)sgte)->length = ((((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_F_MASK) | (((val) << (31-1))& DPAA_SGTE_F_MASK))) /**< Macro to set SGTE FINAL field */
+#define DPAA_SGTE_SET_LENGTH(sgte,val) (((t_DpaaSGTE *)sgte)->length = (((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_LENGTH_MASK) | ((val) & DPAA_SGTE_LENGTH_MASK)) /**< Macro to set SGTE LENGTH field */
+#define DPAA_SGTE_SET_BPID(sgte,val) (((t_DpaaSGTE *)sgte)->offset = ((((t_DpaaSGTE *)sgte)->offset & ~DPAA_SGTE_BPID_MASK) | (((val) << (31-15))& DPAA_SGTE_BPID_MASK))) /**< Macro to set SGTE BPID field */
+#define DPAA_SGTE_SET_OFFSET(sgte,val) (((t_DpaaSGTE *)sgte)->offset = ((((t_DpaaSGTE *)sgte)->offset & ~DPAA_SGTE_OFFSET_MASK) | (((val) << (31-31))& DPAA_SGTE_OFFSET_MASK) )) /**< Macro to set SGTE OFFSET field */
+/* @} */
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+/** @} */ /* end of DPAA_grp group */
+
+
+#endif /* __DPAA_EXT_H */
diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_ext.h
new file mode 100644
index 0000000..9b5db04
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/fm_ext.h
@@ -0,0 +1,1347 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_ext.h
+
+ @Description FM Application Programming Interface.
+*//***************************************************************************/
+#ifndef __FM_EXT
+#define __FM_EXT
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "dpaa_ext.h"
+
+
+/**************************************************************************//**
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_lib_grp FM library
+
+ @Description FM API functions, definitions and enums
+ The FM module is the main driver module and is a mandatory module
+ for FM driver users. Before any further module initialization,
+ this module must be initialized.
+ The FM is a "singletone" module. It is responsible of the common
+ HW modules: FPM, DMA, common QMI, common BMI initializations and
+ run-time control routines. This module must be initialized always
+ when working with any of the FM modules.
+ NOTE - We assumes that the FML will be initialize only by core No. 0!
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for defining port types
+*//***************************************************************************/
+typedef enum e_FmPortType {
+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port (id's: 0-6, share id's with
+ host command, so must have exclusive id) */
+ e_FM_PORT_TYPE_OH_HOST_COMMAND, /**< Host command port (id's: 0-6, share id's with
+ offline parsing ports, so must have exclusive id) */
+ e_FM_PORT_TYPE_RX, /**< 1G Rx port (id's: 0-3) */
+ e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port (id's: 0) */
+ e_FM_PORT_TYPE_TX, /**< 1G Tx port (id's: 0-3) */
+ e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port (id's: 0) */
+ e_FM_PORT_TYPE_DUMMY
+} e_FmPortType;
+
+/**************************************************************************//**
+ @Collection General FM defines
+*//***************************************************************************/
+#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
+#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
+/* @} */
+
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+
+/**************************************************************************//**
+ @Description FM physical Address
+*//***************************************************************************/
+typedef _Packed struct t_FmPhysAddr {
+ volatile uint8_t high; /**< High part of the physical address */
+ volatile uint32_t low; /**< Low part of the physical address */
+} _PackedType t_FmPhysAddr;
+
+/**************************************************************************//**
+ @Description Parse results memory layout
+*//***************************************************************************/
+typedef _Packed struct t_FmPrsResult {
+ volatile uint8_t lpid; /**< Logical port id */
+ volatile uint8_t shimr; /**< Shim header result */
+ volatile uint16_t l2r; /**< Layer 2 result */
+ volatile uint16_t l3r; /**< Layer 3 result */
+ volatile uint8_t l4r; /**< Layer 4 result */
+ volatile uint8_t cplan; /**< Classification plan id */
+ volatile uint16_t nxthdr; /**< Next Header */
+ volatile uint16_t cksum; /**< Checksum */
+ volatile uint32_t lcv; /**< LCV */
+ volatile uint8_t shim_off[3]; /**< Shim offset */
+ volatile uint8_t eth_off; /**< ETH offset */
+ volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
+ volatile uint8_t vlan_off[2]; /**< VLAN offset */
+ volatile uint8_t etype_off; /**< ETYPE offset */
+ volatile uint8_t pppoe_off; /**< PPP offset */
+ volatile uint8_t mpls_off[2]; /**< MPLS offset */
+ volatile uint8_t ip_off[2]; /**< IP offset */
+ volatile uint8_t gre_off; /**< GRE offset */
+ volatile uint8_t l4_off; /**< Layer 4 offset */
+ volatile uint8_t nxthdr_off; /**< Parser end point */
+} _PackedType t_FmPrsResult;
+
+/**************************************************************************//**
+ @Collection FM Parser results
+*//***************************************************************************/
+#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
+#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
+#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
+#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
+#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
+#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
+/* @} */
+
+/**************************************************************************//**
+ @Collection FM Frame descriptor macros
+*//***************************************************************************/
+#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
+#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
+#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
+#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
+#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
+#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
+
+#define FM_FD_TX_STATUS_ERR_MASK 0x07000000 /**< TX Error FD bits */
+#define FM_FD_RX_STATUS_ERR_MASK 0x070ee3f8 /**< RX Error FD bits */
+/* @} */
+
+/**************************************************************************//**
+ @Description Context A
+*//***************************************************************************/
+typedef _Packed struct t_FmContextA {
+ volatile uint32_t command; /**< ContextA Command */
+ volatile uint8_t res0[4]; /**< ContextA Reserved bits */
+} _PackedType t_FmContextA;
+
+/**************************************************************************//**
+ @Description Context B
+*//***************************************************************************/
+typedef uint32_t t_FmContextB;
+
+/**************************************************************************//**
+ @Collection Context A macros
+*//***************************************************************************/
+#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
+#define FM_CONTEXTA_ICMD_MASK 0x40000000
+#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
+#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
+#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
+#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
+#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
+#define FM_CONTEXTA_A1_MASK 0x0000ffff
+
+#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
+#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
+#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
+#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
+#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
+#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
+#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
+#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
+
+#define FM_CONTEXTA_SET_OVERRIDE(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_OVERRIDE_MASK) | (((uint32_t)(val) << (31-0)) & FM_CONTEXTA_OVERRIDE_MASK) ))
+#define FM_CONTEXTA_SET_ICMD(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_ICMD_MASK) | (((val) << (31-1)) & FM_CONTEXTA_ICMD_MASK) ))
+#define FM_CONTEXTA_SET_A1_VALID(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_A1_VALID_MASK) | (((val) << (31-2)) & FM_CONTEXTA_A1_VALID_MASK) ))
+#define FM_CONTEXTA_SET_A1(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_A1_MASK) | (((val) << (31-31)) & FM_CONTEXTA_A1_MASK) ))
+#define FM_CONTEXTA_SET_MACCMD(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_MASK) | (((val) << (31-15)) & FM_CONTEXTA_MACCMD_MASK) ))
+#define FM_CONTEXTA_SET_MACCMD_VALID(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_VALID_MASK) | (((val) << (31-8)) & FM_CONTEXTA_MACCMD_VALID_MASK) ))
+#define FM_CONTEXTA_SET_MACCMD_SECURED(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_SECURED_MASK) | (((val) << (31-11)) & FM_CONTEXTA_MACCMD_SECURED_MASK) ))
+#define FM_CONTEXTA_SET_MACCMD_SECURE_CHANNEL(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_SC_MASK) | (((val) << (31-15)) & FM_CONTEXTA_MACCMD_SC_MASK) ))
+/* @} */
+
+/**************************************************************************//**
+ @Collection Context B macros
+*//***************************************************************************/
+#define FM_CONTEXTB_FQID_MASK 0x00ffffff
+
+#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
+#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
+/* @} */
+
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+
+/**************************************************************************//**
+ @Description FM Exceptions
+*//***************************************************************************/
+typedef enum e_FmExceptions {
+ e_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
+ e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
+ e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side */
+ e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
+ e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
+ e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
+ e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
+ e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
+ e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
+ e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeu from unknown port id */
+ e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
+ e_FM_EX_BMI_PIPELINE_ECC, /**< Pipeline Table ECC Error */
+ e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
+ e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
+ e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
+ e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
+} e_FmExceptions;
+
+/**************************************************************************//**
+ @Group FM_init_grp FM Initialization Unit
+
+ @Description FM Initialization Unit
+
+ Initialization Flow
+ Initialization of the FM Module will be carried out by the application
+ according to the following sequence:
+ a. Calling the configuration routine with basic parameters.
+ b. Calling the advance initialization routines to change driver's defaults.
+ c. Calling the initialization routine.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function t_FmExceptionsCallback
+
+ @Description Exceptions user callback routine, will be called upon an
+ exception passing the exception identification.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] exception - The exception.
+*//***************************************************************************/
+typedef void (t_FmExceptionsCallback) (t_Handle h_App,
+ e_FmExceptions exception);
+
+/**************************************************************************//**
+ @Function t_FmBusErrorCallback
+
+ @Description Bus error user callback routine, will be called upon a
+ bus error, passing parameters describing the errors and the owner.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] portType - Port type (e_FmPortType)
+ @Param[in] portId - Port id - relative to type.
+ @Param[in] addr - Address that caused the error
+ @Param[in] tnum - Owner of error
+ @Param[in] liodn - Logical IO device number
+*//***************************************************************************/
+typedef void (t_FmBusErrorCallback) (t_Handle h_App,
+ e_FmPortType portType,
+ uint8_t portId,
+ uint64_t addr,
+ uint8_t tnum,
+ uint16_t liodn);
+
+/**************************************************************************//**
+ @Description structure for defining Ucode patch for loading.
+*//***************************************************************************/
+typedef struct t_FmPcdFirmwareParams {
+ uint32_t size; /**< Size of uCode */
+ uint32_t *p_Code; /**< A pointer to the uCode */
+} t_FmPcdFirmwareParams;
+
+/**************************************************************************//**
+ @Description structure representing FM initialization parameters
+*//***************************************************************************/
+#define FM_SIZE_OF_LIODN_TABLE 64
+typedef struct t_FmParams {
+ uint8_t fmId; /**< Index of the FM */
+
+ uint8_t guestId; /**< FM Partition Id */
+
+ uintptr_t baseAddr; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ A pointer to base of memory mapped FM registers (virtual);
+ NOTE that this should include ALL common regs of the FM including
+ the PCD regs area. */
+ t_Handle h_FmMuram; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ A handle of an initialized MURAM object,
+ to be used by the FM */
+ uint16_t fmClkFreq; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ In Mhz */
+#ifdef FM_PARTITION_ARRAY
+ uint16_t liodnBasePerPort[FM_SIZE_OF_LIODN_TABLE];
+ /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ For each partition, LIODN should be configured here. */
+#endif /* FM_PARTITION_ARRAY */
+ t_FmExceptionsCallback *f_Exception; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ An application callback routine to
+ handle exceptions.*/
+ t_FmBusErrorCallback *f_BusError; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ An application callback routine to
+ handle exceptions.*/
+ t_Handle h_App; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+ int irq; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ FM interrupt source for normal events */
+ int errIrq; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ FM interrupt source for errors */
+ t_FmPcdFirmwareParams firmware; /**< Relevant when guestId = NCSW_MASSTER_ID only.
+ Ucode */
+} t_FmParams;
+
+
+/**************************************************************************//**
+ @Function FM_Config
+
+ @Description Creates descriptor for the FM module.
+
+ The routine returns a handle (descriptor) to the FM object.
+ This descriptor must be passed as first parameter to all other
+ FM function calls.
+
+ No actual initialization or configuration of FM hardware is
+ done by this routine.
+
+ @Param[in] p_FmParams - A pointer to data structure of parameters
+
+ @Return Handle to FM object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle FM_Config(t_FmParams *p_FmParams);
+
+/**************************************************************************//**
+ @Function FM_Init
+
+ @Description Initializes the FM module
+
+ @Param[in] h_Fm - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_Init(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_Free
+
+ @Description Frees all resources that were assigned to FM module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_Fm - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_Free(t_Handle h_Fm);
+
+
+/**************************************************************************//**
+ @Group FM_advanced_init_grp FM Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values;
+ Note: Advanced init routines are not available for guest partition.
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description DMA debug mode
+*//***************************************************************************/
+typedef enum e_FmDmaDbgCntMode {
+ e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
+ e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
+ e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
+ e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
+ e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
+ e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
+ e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
+ e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
+} e_FmDmaDbgCntMode;
+
+/**************************************************************************//**
+ @Description DMA Cache Override
+*//***************************************************************************/
+typedef enum e_FmDmaCacheOverride {
+ e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
+ e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
+ e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
+ e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
+} e_FmDmaCacheOverride;
+
+/**************************************************************************//**
+ @Description DMA External Bus Priority
+*//***************************************************************************/
+typedef enum e_FmDmaExtBusPri {
+ e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
+ e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
+ e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
+ e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
+} e_FmDmaExtBusPri;
+
+/**************************************************************************//**
+ @Description enum for choosing the field that will be output on AID
+*//***************************************************************************/
+typedef enum e_FmDmaAidMode {
+ e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
+ e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
+} e_FmDmaAidMode;
+
+/**************************************************************************//**
+ @Description FPM Catasrophic error behaviour
+*//***************************************************************************/
+typedef enum e_FmCatastrophicErr {
+ e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
+ e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only errornous task is stalled */
+} e_FmCatastrophicErr;
+
+/**************************************************************************//**
+ @Description FPM DMA error behaviour
+*//***************************************************************************/
+typedef enum e_FmDmaErr {
+ e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic error */
+ e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
+} e_FmDmaErr;
+
+/**************************************************************************//**
+ @Description DMA Emergency level by BMI emergency signal
+*//***************************************************************************/
+typedef enum e_FmDmaEmergencyLevel {
+ e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
+ e_FM_DMA_EM_SOS /**< SOS emergency */
+} e_FmDmaEmergencyLevel;
+
+/**************************************************************************//**
+ @Collection DMA emergency options
+*//***************************************************************************/
+typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
+
+#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
+#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
+#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
+/* @} */
+
+/**************************************************************************//**
+ @Description A structure for defining DMA emergency level
+*//***************************************************************************/
+typedef struct t_FmDmaEmergency {
+ fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
+ should be enabled */
+ e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
+} t_FmDmaEmergency;
+
+/**************************************************************************//**
+ @Description structure for defining FM threshold
+*//***************************************************************************/
+typedef struct t_FmThresholds {
+ uint8_t dispLimit; /**< The number of times a frames may
+ be passed in the FM before assumed to
+ be looping. */
+ uint8_t prsDispTh; /**< This is the number pf packets that may be
+ queued in the parser dispatch queue*/
+ uint8_t plcrDispTh; /**< This is the number pf packets that may be
+ queued in the policer dispatch queue*/
+ uint8_t kgDispTh; /**< This is the number pf packets that may be
+ queued in the keygen dispatch queue*/
+ uint8_t bmiDispTh; /**< This is the number pf packets that may be
+ queued in the BMI dispatch queue*/
+ uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
+ queued in the QMI enqueue dispatch queue*/
+ uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
+ queued in the QMI dequeue dispatch queue*/
+ uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
+ queued in fmCtl1 dispatch queue*/
+ uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
+ queued in fmCtl2 dispatch queue*/
+} t_FmThresholds;
+
+
+/**************************************************************************//**
+ @Description structure for defining DMA thresholds
+*//***************************************************************************/
+typedef struct t_FmDmaThresholds {
+ uint8_t assertEmergency; /**< When this value is reached,
+ assert emergency (Threshold)*/
+ uint8_t clearEmergency; /**< After emergency is asserted, it is held
+ until this value is reached (Hystheresis) */
+} t_FmDmaThresholds;
+
+
+/**************************************************************************//**
+ @Function FM_ConfigResetOnInit
+
+ @Description Tell the driver whether to reset the FM before initialization or
+ not. It changes the default configuration [FALSE].
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] enable When TRUE, FM will be reset before any initialization.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
+
+/**************************************************************************//**
+ @Function FM_ConfigTotalNumOfTasks
+
+ @Description Change the total number of tasks from its default
+ configuration [BMI_MAX_NUM_OF_TASKS]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] totalNumOfTasks The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigTotalNumOfTasks(t_Handle h_Fm, uint8_t totalNumOfTasks);
+
+/**************************************************************************//**
+ @Function FM_ConfigTotalFifoSize
+
+ @Description Change the total Fifo size from its default
+ configuration [BMI_MAX_FIFO_SIZE]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] totalFifoSize The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
+
+/**************************************************************************//**
+ @Function FM_ConfigMaxNumOfOpenDmas
+
+ @Description Change the maximum allowed open DMA's for this FM from its default
+ configuration [BMI_MAX_NUM_OF_DMAS]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] maxNumOfOpenDmas The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigMaxNumOfOpenDmas(t_Handle h_Fm, uint8_t maxNumOfOpenDmas);
+
+/**************************************************************************//**
+ @Function FM_ConfigThresholds
+
+ @Description Calling this routine changes the internal driver data base
+ from its default FM threshold configuration:
+ dispLimit: [0]
+ prsDispTh: [16]
+ plcrDispTh: [16]
+ kgDispTh: [16]
+ bmiDispTh: [16]
+ qmiEnqDispTh: [16]
+ qmiDeqDispTh: [16]
+ fmCtl1DispTh: [16]
+ fmCtl2DispTh: [16]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] p_FmThresholds A structure of threshold parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
+
+ /**************************************************************************//**
+ @Function FM_ConfigDmaCacheOverride
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of cache override mode [e_FM_DMA_NO_CACHE_OR]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] cacheOverride The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaAidOverride
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of aid override mode [TRUE]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] aidOverride The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaAidMode
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of aid mode [e_FM_DMA_AID_OUT_TNUM]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] aidMode The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaAxiDbgNumOfBeats
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of axi debug [1]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] axiDbgNumOfBeats The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaCamNumOfEntries
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of number of CAM entries [32]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] numOfEntries The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaWatchdog
+
+ @Description Calling this routine changes the internal driver data base
+ from its default watchdog configuration, which is disabled
+ [0].
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] watchDogValue The selected new value - in microseconds.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaWriteBufThresholds
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of DMA write buffer threshold
+ assertEmergency: [DMA_THRESH_MAX_BUF]
+ clearEmergency: [DMA_THRESH_MAX_BUF]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
+ When 'assertEmergency' value is reached, emergency is asserted,
+ then it is held until 'clearEmergency' value is reached.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
+
+ /**************************************************************************//**
+ @Function FM_ConfigDmaCommQThresholds
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of DMA command queue threshold
+ assertEmergency: [DMA_THRESH_MAX_COMMQ]
+ clearEmergency: [DMA_THRESH_MAX_COMMQ]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
+ When 'assertEmergency' value is reached, emergency is asserted,
+ then it is held until 'clearEmergency' value is reached..
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaReadBufThresholds
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration of DMA read buffer threshold
+ assertEmergency: [DMA_THRESH_MAX_BUF]
+ clearEmergency: [DMA_THRESH_MAX_BUF]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
+ When 'assertEmergency' value is reached, emergency is asserted,
+ then it is held until 'clearEmergency' value is reached..
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaSosEmergencyThreshold
+
+ @Description Calling this routine changes the internal driver data base
+ from its default dma SOS emergency configuration [0]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] dmaSosEmergency The selected new value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
+
+/**************************************************************************//**
+ @Function FM_ConfigEnableCounters
+
+ @Description Calling this routine changes the internal driver data base
+ from its default counters configuration where counters are disabled.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaDbgCounter
+
+ @Description Calling this routine changes the internal driver data base
+ from its default DMA debug counters configuration [e_FM_DMA_DBG_NO_CNT]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaStopOnBusErr
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of bus error behavior [FALSE]
+
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] stop TRUE to stop on bus error, FALSE to continue.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+ Only if bus error is enabled.
+*//***************************************************************************/
+t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaEmergency
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of DMA emergency where's it's disabled.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] p_Emergency An OR mask of all required options.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaEmergencySmoother
+
+ @Description sets the minimum amount of DATA beats transferred on the AXI
+ READ and WRITE ports before lowering the emergency level.
+ By default smother is disabled.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] emergencyCnt emergency switching counter.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
+
+/**************************************************************************//**
+ @Function FM_ConfigDmaErr
+
+ @Description Calling this routine changes the internal driver data base
+ from its default DMA error treatment [e_FM_DMA_ERR_CATASTROPHIC]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] dmaErr The selected new choice.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
+
+/**************************************************************************//**
+ @Function FM_ConfigCatastrophicErr
+
+ @Description Calling this routine changes the internal driver data base
+ from its default behavior on catastrophic error [e_FM_CATASTROPHIC_ERR_STALL_PORT]
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] catastrophicErr The selected new choice.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
+
+/**************************************************************************//**
+ @Function FM_ConfigEnableMuramTestMode
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of test mode where it's disabled.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_ConfigEnableIramTestMode
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of test mode where it's disabled.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_ConfigHaltOnExternalActivation
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of FM behaviour on external halt
+ activation [FALSE].
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] enable TRUE to enable halt on external halt
+ activation.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
+
+/**************************************************************************//**
+ @Function FM_ConfigHaltOnUnrecoverableEccError
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of FM behaviour on unrecoverable
+ Ecc error [FALSE].
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
+
+/**************************************************************************//**
+ @Function FM_ConfigException
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of exceptions enablement.
+ By default all exceptions are enabled.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function FM_ConfigExternalEccRamsEnable
+
+ @Description Calling this routine changes the internal driver data base
+ from its default [FALSE].
+ When this option is enabled Rams ECC enable is not effected
+ by the FPM RCR bit, but by a JTAG.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] enable TRUE to enable this option.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
+
+/**************************************************************************//**
+ @Function FM_ConfigTnumAgingPeriod
+
+ @Description Calling this routine changes the internal driver data base
+ from its default configuration for aging of dequeue TNUM's
+ in the QMI.[0]
+ Note that this functionality is not available in all chips.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
+ Note that period is recalculated in units of
+ 64 FM clocks. Driver will pick the closest
+ possible period.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
+
+/** @} */ /* end of FM_advanced_init_grp group */
+/** @} */ /* end of FM_init_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_runtime_control_grp FM Runtime Control Unit
+
+ @Description FM Runtime control unit API functions, definitions and enums.
+ The FM driver provides a set of control routines for each module.
+ These routines may only be called after the module was fully
+ initialized (both configuration and initialization routines were
+ called). They are typically used to get information from hardware
+ (status, counters/statistics, revision etc.), to modify a current
+ state or to force/enable a required action. Run-time control may
+ be called whenever necessary and as many times as needed.
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Collection General FM defines.
+*//***************************************************************************/
+#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
+ FM_MAX_NUM_OF_1G_RX_PORTS + \
+ FM_MAX_NUM_OF_10G_RX_PORTS + \
+ FM_MAX_NUM_OF_1G_TX_PORTS + \
+ FM_MAX_NUM_OF_10G_TX_PORTS)
+/* @} */
+
+/**************************************************************************//**
+ @Description Structure for Port bandwidth requirement. Port is identified
+ by type and relative id.
+*//***************************************************************************/
+typedef struct t_FmPortBandwidth {
+ e_FmPortType type; /**< FM port type */
+ uint8_t relativePortId; /**< Type relative port id */
+ uint8_t bandwidth; /**< bandwidth - (in term of percents) */
+} t_FmPortBandwidth;
+
+/**************************************************************************//**
+ @Description A Structure containing an array of Port bandwidth requirements.
+ The user should state the ports requiring bandwidth in terms of
+ percentage - i.e. all port's bandwidths in the array must add
+ up to 100.
+*//***************************************************************************/
+typedef struct t_FmPortsBandwidthParams {
+ uint8_t numOfPorts; /**< num of ports listed in the array below */
+ t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
+ /**< for each port, it's bandwidth (all port's
+ bandwidths must add up to 100.*/
+} t_FmPortsBandwidthParams;
+
+/**************************************************************************//**
+ @Description DMA Emergency control on MURAM
+*//***************************************************************************/
+typedef enum e_FmDmaMuramPort {
+ e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
+ e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
+} e_FmDmaMuramPort;
+
+/**************************************************************************//**
+ @Description enum for defining FM counters
+*//***************************************************************************/
+typedef enum e_FmCounters {
+ e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
+ e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
+ e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
+ e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
+ e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
+ e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
+ e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
+ e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
+ e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
+ e_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
+ e_FM_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA semaphor reject due to full entry counter */
+ e_FM_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA semaphor reject due to full CAM queue counter */
+ e_FM_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA semaphor reject due to sync counter */
+} e_FmCounters;
+
+/**************************************************************************//**
+ @Description structure for returning revision information
+*//***************************************************************************/
+typedef struct t_FmRevisionInfo {
+ uint8_t majorRev; /**< Major revision */
+ uint8_t minorRev; /**< Minor revision */
+} t_FmRevisionInfo;
+
+/**************************************************************************//**
+ @Description struct for defining DMA status
+*//***************************************************************************/
+typedef struct t_FmDmaStatus {
+ bool cmqNotEmpty; /**< Command queue is not empty */
+ bool busError; /**< Bus error occurred */
+ bool readBufEccError; /**< Double ECC error on buffer Read */
+ bool writeBufEccSysError; /**< Double ECC error on buffer write from system side */
+ bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side */
+} t_FmDmaStatus;
+
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function FM_DumpRegs
+
+ @Description Dumps all FM registers
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success;
+
+ @Cautions Allowed only FM_Init().
+*//***************************************************************************/
+t_Error FM_DumpRegs(t_Handle h_Fm);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+/**************************************************************************//**
+ @Function FM_SetException
+
+ @Description Calling this routine enables/disables the specified exception.
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function FM_SetPortsBandwidth
+
+ @Description Sets relative weights between ports when accessing common resources.
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
+ total must equal 100.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
+
+/**************************************************************************//**
+ @Function FM_EnableRamsEcc
+
+ @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
+ MURAM, Parser, Keygen, Policer, etc.
+ Note:
+ If FM_ConfigExternalEccRamsEnable was called to enable external
+ setting of ECC, this routine effects IRAM ECC only.
+ This routine is also called by the driver if an ECC exception is
+ enabled.
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_EnableRamsEcc(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_DisableRamsEcc
+
+ @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
+ MURAM, Parser, Keygen, Policer, etc.
+ Note:
+ If FM_ConfigExternalEccRamsEnable was called to enable external
+ setting of ECC, this routine effects IRAM ECC only.
+ In opposed to FM_EnableRamsEcc, this routine must be called
+ explicitly to disable all Rams ECC.
+ Note: Not available for guest partition.
+
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Config() and before FM_Init().
+*//***************************************************************************/
+t_Error FM_DisableRamsEcc(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_GetRevision
+
+ @Description Returns the FM revision
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[out] p_FmRevisionInfo A structure of revision information parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
+
+/**************************************************************************//**
+ @Function FM_GetCounter
+
+ @Description Reads one of the FM counters.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] counter The requested counter.
+
+ @Return Counter's current value.
+
+ @Cautions Allowed only following FM_Init().
+ Note that it is user's responsibility to call this routine only
+ for enabled counters, and there will be no indication if a
+ disabled counter is accessed.
+*//***************************************************************************/
+uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
+
+/**************************************************************************//**
+ @Function FM_ModifyCounter
+
+ @Description Sets a value to an enabled counter. Use "0" to reset the counter.
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] counter The requested counter.
+ @Param[in] val The requested value to be written into the counter.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
+
+/**************************************************************************//**
+ @Function FM_Resume
+
+ @Description Release FM after halt FM command or after unrecoverable ECC error.
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+void FM_Resume(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_SetDmaEmergency
+
+ @Description Manual emergency set
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] muramPort MURAM direction select.
+ @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
+
+ @Return None.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
+
+/**************************************************************************//**
+ @Function FM_SetDmaExtBusPri
+
+ @Description Manual emergency set
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] pri External bus priority select
+
+ @Return None.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
+
+/**************************************************************************//**
+ @Function FM_ForceIntr
+
+ @Description Causes an interrupt event on the requested source.
+ Note: Not available for guest partition.
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] exception An exception to be forced.
+
+ @Return E_OK on success; Error code if the exception is not enabled,
+ or is not able to create interrupt.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
+
+/**************************************************************************//**
+ @Function FM_GetDmaStatus
+
+ @Description Reads the DMA current status
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[out] p_FmDmaStatus A structure of DMA status parameters.
+
+ @Return None
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
+
+/**************************************************************************//**
+ @Function FM_GetPcdHandle
+
+ @Description Used by FMC in order to get PCD handle
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return A handle to the PCD module, NULL if uninitialized.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Handle FM_GetPcdHandle(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_ErrorIsr
+ Note: Not available for guest partition.
+
+ @Description FM interrupt-service-routine for errors.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Return E_OK on success; E_EMPTY if no errors found in register, other
+ error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+ This routine should NOT be called from guest-partition
+ (i.e. guestId != NCSW_MASTER_ID)
+*//***************************************************************************/
+t_Error FM_ErrorIsr(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_EventIsr
+ Note: Not available for guest partition.
+
+ @Description FM interrupt-service-routine for normal events.
+
+ @Param[in] h_Fm A handle to an FM Module.
+
+ @Cautions Allowed only following FM_Init().
+ This routine should NOT be called from guest-partition
+ (i.e. guestId != NCSW_MASTER_ID)
+*//***************************************************************************/
+void FM_EventIsr(t_Handle h_Fm);
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function FmDumpPortRegs
+
+ @Description Dumps FM port registers which are part of FM common registers
+
+ @Param[in] h_Fm A handle to an FM Module.
+ @Param[in] hardwarePortId HW port id.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only FM_Init().
+*//***************************************************************************/
+t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+
+/** @} */ /* end of FM_runtime_control_grp group */
+/** @} */ /* end of FM_lib_grp group */
+/** @} */ /* end of FM_grp group */
+
+#endif /* __FM_EXT */
diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h
new file mode 100644
index 0000000..5abb600
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/fm_mac_ext.h
@@ -0,0 +1,713 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_mac_ext.h
+
+ @Description FM MAC ...
+*//***************************************************************************/
+#ifndef __FM_MAC_EXT_H
+#define __FM_MAC_EXT_H
+
+#include "std_ext.h"
+#include "enet_ext.h"
+
+
+/**************************************************************************//**
+
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_mac_grp FM MAC
+
+ @Description FM MAC API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+
+/**************************************************************************//**
+ @Description FM MAC Exceptions
+*//***************************************************************************/
+typedef enum e_FmMacExceptions {
+ e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0
+ ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL
+ ,e_FM_MAC_EX_10G_REM_FAULT
+ ,e_FM_MAC_EX_10G_LOC_FAULT
+ ,e_FM_MAC_EX_10G_1TX_ECC_ER
+ ,e_FM_MAC_EX_10G_TX_FIFO_UNFL
+ ,e_FM_MAC_EX_10G_TX_FIFO_OVFL
+ ,e_FM_MAC_EX_10G_TX_ER
+ ,e_FM_MAC_EX_10G_RX_FIFO_OVFL
+ ,e_FM_MAC_EX_10G_RX_ECC_ER
+ ,e_FM_MAC_EX_10G_RX_JAB_FRM
+ ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM
+ ,e_FM_MAC_EX_10G_RX_RUNT_FRM
+ ,e_FM_MAC_EX_10G_RX_FRAG_FRM
+ ,e_FM_MAC_EX_10G_RX_LEN_ER
+ ,e_FM_MAC_EX_10G_RX_CRC_ER
+ ,e_FM_MAC_EX_10G_RX_ALIGN_ER
+ ,e_FM_MAC_EX_1G_BAB_RX
+ ,e_FM_MAC_EX_1G_RX_CTL
+ ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET
+ ,e_FM_MAC_EX_1G_BAB_TX
+ ,e_FM_MAC_EX_1G_TX_CTL
+ ,e_FM_MAC_EX_1G_TX_ERR
+ ,e_FM_MAC_EX_1G_LATE_COL
+ ,e_FM_MAC_EX_1G_COL_RET_LMT
+ ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN
+ ,e_FM_MAC_EX_1G_MAG_PCKT
+ ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET
+ ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET
+ ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET
+ ,e_FM_MAC_EX_1G_TX_DATA_ERR
+ ,e_FM_MAC_EX_1G_RX_DATA_ERR
+ ,e_FM_MAC_EX_1G_1588_TS_RX_ERR
+ ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL
+} e_FmMacExceptions;
+
+/**************************************************************************//**
+ @Description TM MAC statistics level
+*//***************************************************************************/
+typedef enum e_FmMacStatisticsLevel {
+ e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
+ e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available. Optimized for performance */
+ e_FM_MAC_FULL_STATISTICS /**< All counters available. Not optimized for performance */
+} e_FmMacStatisticsLevel;
+
+
+/**************************************************************************//**
+ @Function t_FmMacExceptionCallback
+
+ @Description Fm Mac Exception Callback from FM MAC to the user
+
+ @Param[in] h_App - Handle to the upper layer handler
+
+ @Param[in] exceptions - The exception that occurred
+
+
+ @Return void.
+*//***************************************************************************/
+typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
+
+
+/**************************************************************************//**
+ @Description TM MAC statistics rfc3635
+*//***************************************************************************/
+typedef struct t_FmMacStatistics {
+/* RMON */
+ uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
+ uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
+ uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
+ uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
+ uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
+ uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
+ uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
+/* */
+ uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
+ uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
+ uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client. */
+ uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
+ uint64_t eStatUndersizePkts; /**< Total number of packets that were less than 64 octets long with a good CRC.*/
+ uint64_t eStatOversizePkts; /**< T,B.D*/
+/* Pause */
+ uint64_t teStatPause; /**< Pause MAC Control received */
+ uint64_t reStatPause; /**< Pause MAC Control sent */
+
+/* MIB II */
+ uint64_t ifInOctets; /**< Total number of byte received. */
+ uint64_t ifInPkts; /**< Total number of packets received.*/
+ uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
+ uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
+ uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
+ uint64_t ifInErrors; /**< Number of frames received with error:
+ - FIFO Overflow Error
+ - CRC Error
+ - Frame Too Long Error
+ - Alignment Error
+ - The dedicated Error Code (0xfe, not a code error) was received */
+ uint64_t ifOutOctets; /**< Total number of byte sent. */
+ uint64_t ifOutPkts; /**< Total number of packets sent .*/
+ uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
+ uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
+ uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
+ uint64_t ifOutErrors; /**< Number of frames transmitted with error:
+ - FIFO Overflow Error
+ - FIFO Underflow Error
+ - Other */
+} t_FmMacStatistics;
+
+
+/**************************************************************************//**
+ @Group FM_mac_init_grp Initialization Unit
+
+ @Description FM MAC Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description FM MAC config input
+*//***************************************************************************/
+typedef struct t_FmMacParams {
+ uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
+ t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
+ uint8_t macId; /**< MAC ID <dTSEC 0-3> <10G 0> */
+ e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed) */
+ t_Handle h_Fm; /**< A handle to the FM object this port related to */
+ int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
+ MACs; MUST be set to 'NO_IRQ' for MACs that don't have
+ mdio-irq, or for polling */
+ t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
+ t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+} t_FmMacParams;
+
+
+/**************************************************************************//**
+ @Function FM_MAC_Config
+
+ @Description Creates descriptor for the FM MAC module.
+
+ The routine returns a handle (descriptor) to the FM MAC object.
+ This descriptor must be passed as first parameter to all other
+ FM MAC function calls.
+
+ No actual initialization or configuration of FM MAC hardware is
+ done by this routine.
+
+ @Param[in] p_FmMacParam - Pointer to data structure of parameters
+
+ @Retval Handle to FM MAC object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam);
+
+/**************************************************************************//**
+ @Function FM_MAC_Init
+
+ @Description Initializes the FM MAC module
+
+ @Param[in] h_FmMac - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MAC_Init (t_Handle h_FmMac);
+
+/**************************************************************************//**
+ @Function FM_Free
+
+ @Description Frees all resources that were assigned to FM MAC module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmMac - FM module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MAC_Free (t_Handle h_FmMac);
+
+
+/**************************************************************************//**
+ @Group FM_mac_advanced_init_grp Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigResetOnInit
+
+ @Description Tell the driver whether to reset the FM MAC before initialization or
+ not. It changes the default configuration [FALSE].
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] enable When TRUE, FM will be reset before any initialization.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigLoopback
+
+ @Description Enable/Disable internal loopback mode
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] enable TRUE to enable or FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigMaxFrameLength
+
+ @Description Setup maximum Frame Length
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] newVal MAX Frame length
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal);
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigWan
+
+ @Description ENABLE WAN mode in 10G MAC
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] enable TRUE to enable or FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigPadAndCrc
+
+ @Description Config PAD and CRC mode
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] enable TRUE to enable or FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigHalfDuplex
+
+ @Description Config Half Duplex Mode
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] enable TRUE to enable or FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigLengthCheck
+
+ @Description Configure thef frame length checking.
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] enable TRUE to enable or FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_ConfigException
+
+ @Description Change Exception selection from default
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] ex Type of the desired exceptions
+ @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
+
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
+
+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
+/** @} */ /* end of FM_mac_advanced_init_grp group */
+/** @} */ /* end of FM_mac_init_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_mac_runtime_control_grp Runtime Control Unit
+
+ @Description FM MAC Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_MAC_Enable
+
+ @Description Enable the MAC
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] mode Mode of operation (RX, TX, Both)
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode);
+
+/**************************************************************************//**
+ @Function FM_MAC_Disable
+
+ @Description DISABLE the MAC
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] mode Define what part to Disable (RX, TX or BOTH)
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode);
+
+/**************************************************************************//**
+ @Function FM_MAC_Enable1588TimeStamp
+
+ @Description Enables the TSU operation.
+
+ @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_MAC_Disable1588TimeStamp
+
+ @Description Disables the TSU operation.
+
+ @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
+
+/**************************************************************************//**
+ @Function FM_MAC_SetTxAutoPauseFrames
+
+ @Description Enable/Disable transmition of Pause-Frames.
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] pauseTime Pause quanta value used with transmitted pause frames.
+ Each quanta represents a 512 bit-times; Note that '0'
+ as an input here will be used as disabling the
+ transmission of the pause-frames.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_SetTxAutoPauseFrames (t_Handle h_FmMac, uint16_t pauseTime);
+
+/**************************************************************************//**
+ @Function FM_MAC_SetRxIgnorePauseFrames
+
+ @Description Enable/Disable ignoring of Pause-Frames.
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] en boolean indicates whether to ignore the incoming pause
+ frames or not.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en);
+
+/**************************************************************************//**
+ @Function FM_MAC_ResetCounters
+
+ @Description reset all statistics counters
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ResetCounters (t_Handle h_FmMac);
+
+/**************************************************************************//**
+ @Function FM_MAC_SetException
+
+ @Description Enable/Disable a specific Exception
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] ex Type of the desired exceptions
+ @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
+
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_SetStatistics
+
+ @Description Define Statistics level.
+ Where applicable, the routine also enables the MIB counters
+ overflow interrupt in order to keep counters accurate
+ and account for overflows.
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] statisticsLevel Full statistics level provides all standard counters but may
+ reduce performance. Partial statistics provides only special
+ event counters (errors etc.). If selected, regular counters (such as
+ byte/packet) will be invalid and will return -1.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
+
+/**************************************************************************//**
+ @Function FM_MAC_GetStatistics
+
+ @Description get all statistics counters
+
+ @Param[in] h_FmMac A handle to a FM MAC Module.
+ @Param[in] p_Statistics Staructure with statistics
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_Init().
+*//***************************************************************************/
+t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
+
+/**************************************************************************//**
+ @Function FM_MAC_ModifyMacAddr
+
+ @Description Replace the main MAC Address
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] p_EnetAddr - Ethernet Mac address
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+
+/**************************************************************************//**
+ @Function FM_MAC_AddHashMacAddr
+
+ @Description Add an Address to the hash table. This is for filter purpose only.
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] p_EnetAddr - Ethernet Mac address
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
+ @Cautions Some address need to be filterd out in upper FM blocks.
+*//***************************************************************************/
+t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+
+/**************************************************************************//**
+ @Function FM_MAC_RemoveHashMacAddr
+
+ @Description Delete an Address to the hash table. This is for filter purpose only.
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] p_EnetAddr - Ethernet Mac address
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+
+/**************************************************************************//**
+ @Function FM_MAC_AddExactMatchMacAddr
+
+ @Description Add a unicast or multicast mac address for exact-match filtering
+ (8 on dTSEC, 2 for 10G-MAC)
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] p_EnetAddr - MAC Address to ADD
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+
+/**************************************************************************//**
+ @Function FM_MAC_RemovelExactMatchMacAddr
+
+ @Description Remove a uni cast or multi cast mac address.
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] p_EnetAddr - MAC Address to remove
+
+ @Return E_OK on success; Error code otherwise..
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
+
+/**************************************************************************//**
+ @Function FM_MAC_SetPromiscuous
+
+ @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
+
+ @Param[in] h_FmMac - A handle to a FM MAC Module.
+ @Param[in] enable - TRUE to enable or FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool enable);
+
+/**************************************************************************//**
+ @Function FM_MAC_AdjustLink
+
+ @Description Adjusts the Ethernet link with new speed/duplex setup.
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] speed - Ethernet speed.
+ @Param[in] fullDuplex - TRUE for Full-Duplex mode;
+ FALSE for Half-Duplex mode.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
+
+/**************************************************************************//**
+ @Function FM_MAC_GetId
+
+ @Description Return the MAC ID
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[out] p_MacId - MAC ID of device
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *p_MacId);
+
+/**************************************************************************//**
+ @Function FM_MAC_GetVesrion
+
+ @Description Return Mac HW chip version
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[out] p_MacVresion - Mac version as defined by the chip
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *p_MacVresion);
+
+/**************************************************************************//**
+ @Function FM_MAC_MII_WritePhyReg
+
+ @Description Write data into Phy Register
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] phyAddr - Phy Address on the MII bus
+ @Param[in] reg - Register Number.
+ @Param[in] data - Data to write.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
+
+/**************************************************************************//**
+ @Function FM_MAC_MII_ReadPhyReg
+
+ @Description Read data from Phy Register
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+ @Param[in] phyAddr - Phy Address on the MII bus
+ @Param[in] reg - Register Number.
+ @Param[out] p_Data - Data from PHY.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function FM_MAC_DumpRegs
+
+ @Description Dump internal registers
+
+ @Param[in] h_FmMac - A handle to a FM Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only after FM_MAC_Init().
+*//***************************************************************************/
+t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+/** @} */ /* end of FM_mac_runtime_control_grp group */
+/** @} */ /* end of FM_mac_grp group */
+/** @} */ /* end of FM_grp group */
+
+
+
+#endif /* __FM_MAC_EXT_H */
diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h
new file mode 100644
index 0000000..0c99ef3
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/fm_muram_ext.h
@@ -0,0 +1,158 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_muram_ext.h
+
+ @Description FM MURAM Application Programming Interface.
+*//***************************************************************************/
+#ifndef __FM_MURAM_EXT
+#define __FM_MURAM_EXT
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_muram_grp FM MURAM
+
+ @Description FM MURAM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_muram_init_grp FM MURAM Initialization
+
+ @Description FM MURAM initialization API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_MURAM_ConfigAndInit
+
+ @Description Creates partition in the MURAM.
+
+ The routine returns a handle (descriptor) to the MURAM partition.
+ This descriptor must be passed as first parameter to all other
+ FM-MURAM function calls.
+
+ No actual initialization or configuration of FM_MURAM hardware is
+ done by this routine.
+
+ @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
+ @Param[in] size - Size of the FM-MURAM partition.
+
+ @Return Handle to FM-MURAM object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
+
+/**************************************************************************//**
+ @Function FM_MURAM_Free
+
+ @Description Frees all resources that were assigned to FM-MURAM module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmMuram - FM-MURAM module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MURAM_Free(t_Handle h_FmMuram);
+
+/** @} */ /* end of FM_muram_init_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_muram_ctrl_grp FM MURAM Control
+
+ @Description FM MURAM control API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_MURAM_AllocMem
+
+ @Description Allocate some memory from FM-MURAM partition.
+
+ @Param[in] h_FmMuram - FM-MURAM module descriptor.
+ @Param[in] size - size of the memory to be allocated.
+ @Param[in] align - Alignment of the memory.
+
+ @Return address of the allocated memory; NULL otherwise.
+*//***************************************************************************/
+void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
+
+/**************************************************************************//**
+ @Function FM_MURAM_AllocMemForce
+
+ @Description Allocate some specific memory from FM-MURAM partition (according
+ to base).
+
+ @Param[in] h_FmMuram - FM-MURAM module descriptor.
+ @Param[in] base - the desired base-address to be allocated.
+ @Param[in] size - size of the memory to be allocated.
+
+ @Return address of the allocated memory; NULL otherwise.
+*//***************************************************************************/
+void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
+
+/**************************************************************************//**
+ @Function FM_MURAM_FreeMem
+
+ @Description Free an allocated memory from FM-MURAM partition.
+
+ @Param[in] h_FmMuram - FM-MURAM module descriptor.
+ @Param[in] ptr - A pointer to an allocated memory.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
+
+/** @} */ /* end of FM_muram_ctrl_grp group */
+/** @} */ /* end of FM_muram_grp group */
+/** @} */ /* end of FM_grp group */
+
+
+
+#endif /* __FM_MURAM_EXT */
diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h
new file mode 100644
index 0000000..6de21e7
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/fm_pcd_ext.h
@@ -0,0 +1,2160 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_pcd_ext.h
+
+ @Description FM PCD ...
+*//***************************************************************************/
+#ifndef __FM_PCD_EXT
+#define __FM_PCD_EXT
+
+#include "std_ext.h"
+#include "net_ext.h"
+#include "list_ext.h"
+#include "fm_ext.h"
+
+
+/**************************************************************************//**
+
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_PCD_grp FM PCD
+
+ @Description FM PCD API functions, definitions and enums
+
+ The FM PCD module is responsible for the initialization of all
+ global classifying FM modules. This includes the parser general and
+ common registers, the key generator global and common registers,
+ and the Policer global and common registers.
+ In addition, the FM PCD SW module will initialize all required
+ key generator schemes, coarse classification flows, and Policer
+ profiles. When An FM module is configured to work with one of these
+ entities, it will register to it using the FM PORT API. The PCD
+ module will manage the PCD resources - i.e. resource management of
+ Keygen schemes, etc.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Collection General PCD defines
+*//***************************************************************************/
+typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
+
+#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
+#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
+#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
+#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
+#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
+#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
+
+#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
+
+#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
+#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
+ /**< number of distinction units is limited by
+ register size (32), - reserved bits for
+ private headers. */
+
+#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers in a distinction unit */
+#define FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KG registers */
+#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration.
+ For reason of HW implementation, in most
+ cases less than this will be allowed. The
+ driver will return error in initialization
+ time if resource is overused. */
+#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KG extractions. */
+#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
+
+#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Max number of SW parser label */
+#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of sw parser area */
+#define FM_PCD_PRS_SW_OFFSET 0x00000040 /**< Size of illegal addresses at the beginning
+ of the SW parser area */
+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
+#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
+ the end of the SW parser area */
+#define FM_SW_PRS_MAX_IMAGE_SIZE (FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_OFFSET-FM_PCD_PRS_SW_TAIL_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE)
+ /**< Max possible size of SW parser code */
+
+#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Max possible size of insertion template for
+ insert manipulation*/
+/* @} */
+
+
+/**************************************************************************//**
+ @Group FM_PCD_init_grp FM PCD Initialization Unit
+
+ @Description FM PCD Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description PCD counters
+*//***************************************************************************/
+typedef enum e_FmPcdCounters {
+ e_FM_PCD_KG_COUNTERS_TOTAL, /**< Policer counter */
+ e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter */
+ e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter */
+ e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter */
+ e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter */
+ e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter */
+ e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter */
+ e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter */
+ e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter */
+ e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter */
+ e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter */
+ e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter */
+ e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter */
+} e_FmPcdCounters;
+
+/**************************************************************************//**
+ @Description PCD interrupts
+*//***************************************************************************/
+typedef enum e_FmPcdExceptions {
+ e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< Keygen ECC error */
+ e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Read Buffer ECC error */
+ e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< Write Buffer ECC error on system side */
+ e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Write Buffer ECC error on FM side */
+ e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Self init complete */
+ e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Atomic action complete */
+ e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser ECC error */
+ e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single ECC */
+} e_FmPcdExceptions;
+
+
+/**************************************************************************//**
+ @Description Exceptions user callback routine, will be called upon an
+ exception passing the exception identification.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] exception - The exception.
+ *//***************************************************************************/
+typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
+
+/**************************************************************************//**
+ @Description Exceptions user callback routine, will be called upon an exception
+ passing the exception identification.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] exception - The exception.
+ @Param[in] index - id of the relevant source (may be scheme or profile id).
+ *//***************************************************************************/
+typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
+ e_FmPcdExceptions exception,
+ uint16_t index);
+
+/**************************************************************************//**
+ @Description A callback for enqueuing frame onto a QM queue.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] p_Fd - Frame descriptor for the frame.
+
+ @Return E_OK on success; Error code otherwise.
+ *//***************************************************************************/
+typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
+
+/**************************************************************************//**
+ @Description A structure for Host-Command
+ When using Host command for PCD functionalities, a dedicated port
+ must be used. If this routine is called for a PCD in a single partition
+ environment, or it is the Master partition in a Multi partition
+ environment, The port will be initialized by the PCD driver
+ initialization routine.
+ *//***************************************************************************/
+typedef struct t_FmPcdHcParams {
+ uintptr_t portBaseAddr; /**< Host-Command Port Virtual Address of
+ memory mapped registers.*/
+ uint8_t portId; /**< Host-Command Port Id (0-6 relative
+ to Host-Command/Offline parsing ports) */
+ uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
+ used together with LIODN offset. */
+ uint32_t errFqid; /**< Host-Command Port Error Queue Id. */
+ uint32_t confFqid; /**< Host-Command Port Confirmation queue Id. */
+ uint32_t qmChannel; /**< Host-Command port - QM-channel dedicated to
+ this port will be used by the FM for dequeue. */
+ t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Call back routine for enqueuing a frame to the QM */
+ t_Handle h_QmArg; /**< A handle of the QM module */
+} t_FmPcdHcParams;
+
+/**************************************************************************//**
+ @Description The main structure for PCD initialization
+ *//***************************************************************************/
+typedef struct t_FmPcdParams {
+ bool prsSupport; /**< TRUE if Parser will be used for any
+ of the FM ports */
+ bool ccSupport; /**< TRUE if Coarse Classification will be used for any
+ of the FM ports */
+ bool kgSupport; /**< TRUE if Keygen will be used for any
+ of the FM ports */
+ bool plcrSupport; /**< TRUE if Policer will be used for any
+ of the FM ports */
+ t_Handle h_Fm; /**< A handle to the FM module */
+ uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition. */
+ bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
+ t_FmPcdHcParams hc; /**< Relevant only if useHostCommand=TRUE.
+ Host Command parameters. */
+
+ t_FmPcdExceptionCallback *f_Exception; /**< Relevant for master (or single) partition only: Callback routine
+ to be called of PCD exception */
+ t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Relevant for master (or single) partition only: Callback routine
+ to be used for a single scheme and
+ profile exceptions */
+ t_Handle h_App; /**< Relevant for master (or single) partition only: A handle to an
+ application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+} t_FmPcdParams;
+
+
+/**************************************************************************//**
+ @Function FM_PCD_Config
+
+ @Description Basic configuration of the PCD module.
+ Creates descriptor for the FM PCD module.
+
+ @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
+
+ @Return A handle to the initialized module.
+*//***************************************************************************/
+t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_Init
+
+ @Description Initialization of the PCD module.
+
+ @Param[in] h_FmPcd - FM PCD module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PCD_Init(t_Handle h_FmPcd);
+
+/**************************************************************************//**
+ @Function FM_PCD_Free
+
+ @Description Frees all resources that were assigned to FM module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmPcd - FM PCD module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PCD_Free(t_Handle h_FmPcd);
+
+/**************************************************************************//**
+ @Group FM_PCD_advanced_init_grp FM PCD Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of exceptions enablement.
+ [4].
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] numOfSharedPlcrProfiles Number of profiles to
+ be shared between ports on this partition
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
+
+/**************************************************************************//**
+ @Function FM_PCD_ConfigException
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of exceptions enablement.
+ By default all exceptions are enabled.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PCD_ConfigPlcrAutoRefreshMode
+
+ @Description Calling this routine changes the internal driver data base
+ from its default selection of exceptions enablement.
+ By default autorefresh is enabled.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] enable TRUE to enable, FALSE to disable
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PCD_ConfigPrsMaxCycleLimit
+
+ @Description Calling this routine changes the internal data structure for
+ the maximum parsing time from its default value
+ [0].
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] value 0 to disable the mechanism, or new
+ maximum parsing time.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
+
+/** @} */ /* end of FM_PCD_advanced_init_grp group */
+/** @} */ /* end of FM_PCD_init_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
+
+ @Description FM PCD Runtime Unit
+
+ The runtime control allows creation of PCD infrastructure modules
+ such as Network Environment Characteristics, Classification Plan
+ Groups and Coarse Classification Trees.
+ It also allows on-the-fly initialization, modification and removal
+ of PCD modules such as Keygen schemes, coarse classification nodes
+ and Policer profiles.
+
+
+ In order to explain the programming model of the PCD driver interface
+ a few terms should be explained, and will be used below.
+ * Distinction Header - One of the 16 protocols supported by the FM parser,
+ or one of the shim headers (1 or 2). May be a header with a special
+ option (see below).
+ * Interchangeable Headers Group- This is a group of Headers recognized
+ by either one of them. For example, if in a specific context the user
+ chooses to treat IPv4 and IPV6 in the same way, they may create an
+ interchangeable Headers Unit consisting of these 2 headers.
+ * A Distinction Unit - a Distinction Header or an Interchangeable Headers
+ Group.
+ * Header with special option - applies to ethernet, mpls, vlan, ipv4 and
+ ipv6, includes multicast, broadcast and other protocol specific options.
+ In terms of hardware it relates to the options available in the classification
+ plan.
+ * Network Environment Characteristics - a set of Distinction Units that define
+ the total recognizable header selection for a certain environment. This is
+ NOT the list of all headers that will ever appear in a flow, but rather
+ everything that needs distinction in a flow, where distinction is made by keygen
+ schemes and coarse classification action descriptors.
+
+ The PCD runtime modules initialization is done in stages. The first stage after
+ initializing the PCD module itself is to establish a Network Flows Environment
+ Definition. The application may choose to establish one or more such environments.
+ Later, when needed, the application will have to state, for some of its modules,
+ to which single environment it belongs.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description A structure for sw parser labels
+ *//***************************************************************************/
+typedef struct t_FmPcdPrsLabelParams {
+ uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
+ resolution), relative to Parser RAM. */
+ e_NetHeaderType hdr; /**< The existance of this header will envoke
+ the sw parser code. */
+ uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
+ attachments for the same header, use this
+ index to distinguish between them. */
+} t_FmPcdPrsLabelParams;
+
+/**************************************************************************//**
+ @Description A structure for sw parser
+ *//***************************************************************************/
+typedef struct t_FmPcdPrsSwParams {
+ bool override; /**< FALSE to invoke a check that nothing else
+ was loaded to this address, including
+ internal patches.
+ TRUE to override any existing code.*/
+ uint32_t size; /**< SW parser code size */
+ uint16_t base; /**< SW parser base (in instruction counts!
+ must be larger than 0x20)*/
+ uint8_t *p_Code; /**< SW parser code */
+ uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
+ /**< SW parser data (parameters) */
+ uint8_t numOfLabels; /**< Number of labels for SW parser. */
+ t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
+ /**< SW parser labels table, containing
+ numOfLabels entries */
+} t_FmPcdPrsSwParams;
+
+
+/**************************************************************************//**
+ @Function FM_PCD_Enable
+
+ @Description This routine should be called after PCD is initialized for enabling all
+ PCD engines according to their existing configuration.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
+*//***************************************************************************/
+t_Error FM_PCD_Enable(t_Handle h_FmPcd);
+
+/**************************************************************************//**
+ @Function FM_PCD_Disable
+
+ @Description This routine may be called when PCD is enabled in order to
+ disable all PCD engines. It may be called
+ only when none of the ports in the system are using the PCD.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
+*//***************************************************************************/
+t_Error FM_PCD_Disable(t_Handle h_FmPcd);
+
+
+/**************************************************************************//**
+ @Function FM_PCD_GetCounter
+
+ @Description Reads one of the FM PCD counters.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] counter The requested counter.
+
+ @Return Counter's current value.
+
+ @Cautions Allowed only following FM_PCD_Init().
+ Note that it is user's responsibility to call this routine only
+ for enabled counters, and there will be no indication if a
+ disabled counter is accessed.
+*//***************************************************************************/
+uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
+
+/**************************************************************************//**
+@Function FM_PCD_PrsLoadSw
+
+@Description This routine may be called in order to load software parsing code.
+
+
+@Param[in] h_FmPcd FM PCD module descriptor.
+@Param[in] p_SwPrs A pointer to a structure of software
+ parser parameters, including the software
+ parser image.
+
+@Return E_OK on success; Error code otherwise.
+
+@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
+ Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
+
+/**************************************************************************//**
+ @Function FM_PCD_KgSetDfltValue
+
+ @Description Calling this routine sets a global default value to be used
+ by the keygen when parser does not recognize a required
+ field/header.
+ By default default values are 0.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] valueId 0,1 - one of 2 global default values.
+ @Param[in] value The requested default value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
+ Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
+
+/**************************************************************************//**
+ @Function FM_PCD_KgSetAdditionalDataAfterParsing
+
+ @Description Calling this routine allows the keygen to access data past
+ the parser finishing point.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] payloadOffset the number of bytes beyond the parser location.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
+ Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
+
+/**************************************************************************//**
+ @Function FM_PCD_SetException
+
+ @Description Calling this routine enables/disables PCD interrupts.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+ Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PCD_ModifyCounter
+
+ @Description Sets a value to an enabled counter. Use "0" to reset the counter.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] counter The requested counter.
+ @Param[in] value The requested value to be written into the counter.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+ Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
+
+/**************************************************************************//**
+ @Function FM_PCD_SetPlcrStatistics
+
+ @Description This routine may be used to enable/disable policer statistics
+ counter. By default the statistics is enabled.
+
+ @Param[in] h_FmPcd FM PCD module descriptor
+ @Param[in] enable TRUE to enable, FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+ Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PCD_SetPrsStatistics
+
+ @Description Defines whether to gather parser statistics including all ports.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] enable TRUE to enable, FALSE to disable.
+
+ @Return None
+
+ @Cautions Allowed only following FM_PCD_Init().
+ Not available for guest partition.
+*//***************************************************************************/
+void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PCD_ForceIntr
+
+ @Description Causes an interrupt event on the requested source.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] exception An exception to be forced.
+
+ @Return E_OK on success; Error code if the exception is not enabled,
+ or is not able to create interrupt.
+
+ @Cautions Allowed only following FM_PCD_Init().
+ Not available for guest partition.
+*//***************************************************************************/
+t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
+
+/**************************************************************************//**
+ @Function FM_PCD_HcTxConf
+
+ @Description This routine should be called to confirm frames that were
+ received on the HC confirmation queue.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] p_Fd Frame descriptor of the received frame.
+
+ @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
+ option was selected in the initialization.
+*//***************************************************************************/
+void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function FM_PCD_DumpRegs
+
+ @Description Dumps all PCD registers
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
+
+/**************************************************************************//**
+ @Function FM_PCD_KgDumpRegs
+
+ @Description Dumps all PCD KG registers
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
+
+/**************************************************************************//**
+ @Function FM_PCD_PlcrDumpRegs
+
+ @Description Dumps all PCD Plcr registers
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
+
+/**************************************************************************//**
+ @Function FM_PCD_PlcrProfileDumpRegs
+
+ @Description Dumps all PCD Plcr registers
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_Profile A handle to a profile.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_FmPcd, t_Handle h_Profile);
+
+/**************************************************************************//**
+ @Function FM_PCD_PrsDumpRegs
+
+ @Description Dumps all PCD Prs registers
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
+
+/**************************************************************************//**
+ @Function FM_PCD_HcDumpRegs
+
+ @Description Dumps HC Port registers
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+
+
+/**************************************************************************//**
+ @Group FM_PCD_Runtime_tree_buildgrp FM PCD Tree building Unit
+
+ @Description FM PCD Runtime Unit
+
+ This group contains routines for setting, deleting and modifying
+ PCD resources, for defining the total PCD tree.
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Collection Definitions of coarse classification
+ parameters as required by keygen (when coarse classification
+ is the next engine after this scheme).
+*//***************************************************************************/
+#define FM_PCD_MAX_NUM_OF_CC_NODES 255
+#define FM_PCD_MAX_NUM_OF_CC_TREES 8
+#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
+#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
+#define FM_PCD_MAX_NUM_OF_KEYS 256
+#define FM_PCD_MAX_SIZE_OF_KEY 56
+#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
+/* @} */
+
+/**************************************************************************//**
+ @Collection A set of definitions to allow protocol
+ special option description.
+*//***************************************************************************/
+typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
+
+typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
+#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
+#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
+
+typedef protocolOpt_t vlanProtocolOpt_t; /**< Vlan protocol options. */
+#define VLAN_STACKED 0x20000000 /**< Vlan Stacked. */
+
+typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
+#define MPLS_STACKED 0x10000000 /**< MPLS Stacked. */
+
+typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
+#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
+#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
+#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
+#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
+
+typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
+#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
+#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
+#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
+/* @} */
+
+/**************************************************************************//**
+ @Description A type used for returning the order of the key extraction.
+ each value in this array represents the index of the extraction
+ command as defined by the user in the initialization extraction array.
+ The valid size of this array is the user define number of extractions
+ required (also marked by the second '0' in this array).
+*//***************************************************************************/
+typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
+
+/**************************************************************************//**
+ @Description All PCD engines
+*//***************************************************************************/
+typedef enum e_FmPcdEngine {
+ e_FM_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
+ e_FM_PCD_DONE, /**< No PCD Engine indicated */
+ e_FM_PCD_KG, /**< Keygen indicated */
+ e_FM_PCD_CC, /**< Coarse classification indicated */
+ e_FM_PCD_PLCR, /**< Policer indicated */
+ e_FM_PCD_PRS /**< Parser indicated */
+} e_FmPcdEngine;
+
+/**************************************************************************//**
+ @Description An enum for selecting extraction by header types
+*//***************************************************************************/
+typedef enum e_FmPcdExtractByHdrType {
+ e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
+ e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
+ e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
+} e_FmPcdExtractByHdrType;
+
+/**************************************************************************//**
+ @Description An enum for selecting extraction source
+ (when it is not the header)
+*//***************************************************************************/
+typedef enum e_FmPcdExtractFrom {
+ e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
+ e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
+ e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
+ e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
+ e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
+ e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
+ e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
+ e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
+} e_FmPcdExtractFrom;
+
+/**************************************************************************//**
+ @Description An enum for selecting extraction type
+*//***************************************************************************/
+typedef enum e_FmPcdExtractType {
+ e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
+ e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
+ e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
+} e_FmPcdExtractType;
+
+/**************************************************************************//**
+ @Description An enum for selecting a default
+*//***************************************************************************/
+typedef enum e_FmPcdKgExtractDfltSelect {
+ e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
+ e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
+ e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
+ e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
+ e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
+} e_FmPcdKgExtractDfltSelect;
+
+/**************************************************************************//**
+ @Description An enum defining all default groups -
+ each group shares a default value, one of 4 user
+ initialized values.
+*//***************************************************************************/
+typedef enum e_FmPcdKgKnownFieldsDfltTypes {
+ e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
+ e_FM_PCD_KG_TCI, /**< TCI field */
+ e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
+ e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
+ e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
+ e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
+ e_FM_PCD_KG_IP_ADDR, /**< IP addr */
+ e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
+ e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
+ e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
+ e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
+ e_FM_PCD_KG_L4_PORT, /**< L4 Port */
+ e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
+ e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by sw,
+ any data extraction that is not the full
+ field described above */
+ e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by sw,
+ any data extraction without validation */
+ e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by sw,
+ extraction from parser result or
+ direct use of default value */
+} e_FmPcdKgKnownFieldsDfltTypes;
+
+/**************************************************************************//**
+ @Description enum for defining header index when headers may repeat
+*//***************************************************************************/
+typedef enum e_FmPcdHdrIndex {
+ e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
+ to specify regular IP (not tunneled). */
+ e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
+ e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
+ e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
+ e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
+} e_FmPcdHdrIndex;
+
+/**************************************************************************//**
+ @Description A structure for selcting the policer profile functional type
+*//***************************************************************************/
+typedef enum e_FmPcdProfileTypeSelection {
+ e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
+ e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
+} e_FmPcdProfileTypeSelection;
+
+/**************************************************************************//**
+ @Description A structure for selcting the policer profile algorithem
+*//***************************************************************************/
+typedef enum e_FmPcdPlcrAlgorithmSelection {
+ e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
+ e_FM_PCD_PLCR_RFC_2698, /**< Policer algorythm RFC 2698 */
+ e_FM_PCD_PLCR_RFC_4115 /**< Policer algorythm RFC 4115 */
+} e_FmPcdPlcrAlgorithmSelection;
+
+/**************************************************************************//**
+ @Description A structure for selcting the policer profile color mode
+*//***************************************************************************/
+typedef enum e_FmPcdPlcrColorMode {
+ e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
+ e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
+} e_FmPcdPlcrColorMode;
+
+/**************************************************************************//**
+ @Description A structure for selcting the policer profile color functional mode
+*//***************************************************************************/
+typedef enum e_FmPcdPlcrColor {
+ e_FM_PCD_PLCR_GREEN, /**< Green */
+ e_FM_PCD_PLCR_YELLOW, /**< Yellow */
+ e_FM_PCD_PLCR_RED, /**< Red */
+ e_FM_PCD_PLCR_OVERRIDE /**< Color override */
+} e_FmPcdPlcrColor;
+
+/**************************************************************************//**
+ @Description A structure for selcting the policer profile packet frame length selector
+*//***************************************************************************/
+typedef enum e_FmPcdPlcrFrameLengthSelect {
+ e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
+ e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
+ e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
+ e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
+} e_FmPcdPlcrFrameLengthSelect;
+
+/**************************************************************************//**
+ @Description An enum for selecting rollback frame
+*//***************************************************************************/
+typedef enum e_FmPcdPlcrRollBackFrameSelect {
+ e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
+ e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
+} e_FmPcdPlcrRollBackFrameSelect;
+
+/**************************************************************************//**
+ @Description A structure for selcting the policer profile packet or byte mode
+*//***************************************************************************/
+typedef enum e_FmPcdPlcrRateMode {
+ e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
+ e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
+} e_FmPcdPlcrRateMode;
+
+/**************************************************************************//**
+ @Description An enum for defining action of frame
+*//***************************************************************************/
+typedef enum e_FmPcdDoneAction {
+ e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
+ e_FM_PCD_DROP_FRAME /**< Drop frame */
+} e_FmPcdDoneAction;
+
+/**************************************************************************//**
+ @Description A structure for selecting the policer counter
+*//***************************************************************************/
+typedef enum e_FmPcdPlcrProfileCounters {
+ e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
+ e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
+ e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
+ e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
+ e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
+} e_FmPcdPlcrProfileCounters;
+
+/**************************************************************************//**
+ @Description A structure for selecting action
+*//***************************************************************************/
+typedef enum e_FmPcdAction {
+ e_FM_PCD_ACTION_NONE, /**< NONE */
+ e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
+ e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
+} e_FmPcdAction;
+
+#if defined(FM_CAPWAP_SUPPORT)
+/**************************************************************************//**
+ @Description An enum for selecting type of insert manipulation
+*//***************************************************************************/
+typedef enum e_FmPcdManipInsrtType {
+ e_FM_PCD_MANIP_INSRT_NONE = 0, /**< No insertion */
+ e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_INT_FRAME_HDR, /**< Insert internal frame header to start of frame */
+ e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE /**< Insert template to start of frame*/
+} e_FmPcdManipInsrtType;
+
+/**************************************************************************//**
+ @Description An enum for selecting type of remove manipulation
+*//***************************************************************************/
+typedef enum e_FmPcdManipRmvParamsType {
+ e_FM_PCD_MANIP_RMV_NONE = 0, /**< No remove */
+ e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION, /**< Remove from start of frame till (excluding) specified indication */
+ e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION, /**< Remove from start of frame till (including) specified indication */
+ e_FM_PCD_MANIP_RMV_INT_FRAME_HDR /**< Remove internal frame header to start of frame */
+} e_FmPcdManipRmvParamsType;
+
+/**************************************************************************//**
+ @Description An enum for selecting type of location
+*//***************************************************************************/
+typedef enum e_FmPcdManipLocateType {
+ e_FM_PCD_MANIP_LOC_BY_HDR = 0, /**< Locate according to header */
+ e_FM_PCD_MANIP_LOC_NON_HDR /**< Locate from data that is not the header */
+} e_FmPcdManipLocateType;
+
+/**************************************************************************//**
+ @Description An enum for selecting type of Timeout mode
+*//***************************************************************************/
+typedef enum e_FmPcdManipReassemTimeOutMode {
+ e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< limits the time of the reassm process from the first frag to the last */
+ e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< limits the time of receiving the fragment */
+} e_FmPcdManipReassemTimeOutMode;
+
+/**************************************************************************//**
+ @Description An enum for selecting type of WaysNumber mode
+*//***************************************************************************/
+typedef enum e_FmPcdManipReassemWaysNumber {
+ e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< -------------- */
+ e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< -------------- */
+ e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< -------------- */
+ e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< four ways hash */
+ e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< -------------- */
+ e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< -------------- */
+ e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< -------------- */
+ e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< eight ways hash*/
+} e_FmPcdManipReassemWaysNumber;
+
+/**************************************************************************//**
+ @Description An enum for selecting type of statistics mode
+*//***************************************************************************/
+typedef enum e_FmPcdStatsType {
+ e_FM_PCD_STATS_PER_FLOWID = 0 /**< type where flowId used as index for getting statistics */
+} e_FmPcdStatsType;
+
+#endif /* FM_CAPWAP_SUPPORT */
+
+
+/**************************************************************************//**
+ @Description A Union of protocol dependent special options
+*//***************************************************************************/
+typedef union u_FmPcdHdrProtocolOpt {
+ ethProtocolOpt_t ethOpt; /**< Ethernet options */
+ vlanProtocolOpt_t vlanOpt; /**< Vlan options */
+ mplsProtocolOpt_t mplsOpt; /**< MPLS options */
+ ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
+ ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
+} u_FmPcdHdrProtocolOpt;
+
+/**************************************************************************//**
+ @Description A union holding all known protocol fields
+*//***************************************************************************/
+typedef union t_FmPcdFields {
+ headerFieldEth_t eth; /**< eth */
+ headerFieldVlan_t vlan; /**< vlan */
+ headerFieldLlcSnap_t llcSnap; /**< llcSnap */
+ headerFieldPppoe_t pppoe; /**< pppoe */
+ headerFieldMpls_t mpls; /**< mpls */
+ headerFieldIpv4_t ipv4; /**< ipv4 */
+ headerFieldIpv6_t ipv6; /**< ipv6 */
+ headerFieldUdp_t udp; /**< udp */
+ headerFieldTcp_t tcp; /**< tcp */
+ headerFieldSctp_t sctp; /**< sctp */
+ headerFieldDccp_t dccp; /**< dccp */
+ headerFieldGre_t gre; /**< gre */
+ headerFieldMinencap_t minencap; /**< minencap */
+ headerFieldIpsecAh_t ipsecAh; /**< ipsecAh */
+ headerFieldIpsecEsp_t ipsecEsp; /**< ipsecEsp */
+ headerFieldUdpEncapEsp_t udpEncapEsp; /**< udpEncapEsp */
+} t_FmPcdFields;
+
+/**************************************************************************//**
+ @Description structure for defining header extraction for key generation
+*//***************************************************************************/
+typedef struct t_FmPcdFromHdr {
+ uint8_t size; /**< Size in byte */
+ uint8_t offset; /**< Byte offset */
+} t_FmPcdFromHdr;
+
+/**************************************************************************//**
+ @Description structure for defining field extraction for key generation
+*//***************************************************************************/
+typedef struct t_FmPcdFromField {
+ t_FmPcdFields field; /**< Field selection */
+ uint8_t size; /**< Size in byte */
+ uint8_t offset; /**< Byte offset */
+} t_FmPcdFromField;
+
+/**************************************************************************//**
+ @Description A structure of parameters used to define a single network
+ environment unit.
+ A unit should be defined if it will later be used by one or
+ more PCD engines to distinguich between flows.
+*//***************************************************************************/
+typedef struct t_FmPcdDistinctionUnit {
+ struct {
+ e_NetHeaderType hdr; /**< One of the headers supported by the FM */
+ u_FmPcdHdrProtocolOpt opt; /**< only one option !! */
+ } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
+} t_FmPcdDistinctionUnit;
+
+/**************************************************************************//**
+ @Description A structure of parameters used to define the different
+ units supported by a specific PCD Network Environment
+ Characteristics module. Each unit represent
+ a protocol or a group of protocols that may be used later
+ by the different PCD engined to distinguich between flows.
+*//***************************************************************************/
+typedef struct t_FmPcdNetEnvParams {
+ uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
+ t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
+ different units to be identified */
+} t_FmPcdNetEnvParams;
+
+/**************************************************************************//**
+ @Description structure for defining a single extraction action
+ when creating a key
+*//***************************************************************************/
+typedef struct t_FmPcdExtractEntry {
+ e_FmPcdExtractType type; /**< Extraction type select */
+ union {
+ struct {
+ e_NetHeaderType hdr; /**< Header selection */
+ bool ignoreProtocolValidation;
+ /**< Ignore protocol validation */
+ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
+ IP. Otherwise should be cleared.*/
+ e_FmPcdExtractByHdrType type; /**< Header extraction type select */
+ union {
+ t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
+ t_FmPcdFromField fromField; /**< Extract bytes from field parameters*/
+ t_FmPcdFields fullField; /**< Extract full filed parameters*/
+ } extractByHdrType;
+ } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
+ struct {
+ e_FmPcdExtractFrom src; /**< Non-header extraction source */
+ e_FmPcdAction action; /**< Relevant for CC Only */
+ uint16_t icIndxMask; /**< Relevant only for CC where
+ action=e_FM_PCD_ACTION_INDEXED_LOOKUP */
+ uint8_t offset; /**< Byte offset */
+ uint8_t size; /**< Size in byte */
+ } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
+ };
+} t_FmPcdExtractEntry;
+
+/**************************************************************************//**
+ @Description A structure for defining masks for each extracted
+ field in the key.
+*//***************************************************************************/
+typedef struct t_FmPcdKgExtractMask {
+ uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
+ uint8_t offset; /**< Byte offset */
+ uint8_t mask; /**< A byte mask (selected bits will be used) */
+} t_FmPcdKgExtractMask;
+
+/**************************************************************************//**
+ @Description A structure for defining default selection per groups
+ of fields
+*//***************************************************************************/
+typedef struct t_FmPcdKgExtractDflt {
+ e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select*/
+ e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
+} t_FmPcdKgExtractDflt;
+
+/**************************************************************************//**
+ @Description A structure for defining all parameters needed for
+ generation a key and using a hash function
+*//***************************************************************************/
+typedef struct t_FmPcdKgKeyExtractAndHashParams {
+ uint32_t privateDflt0; /**< Scheme default register 0 */
+ uint32_t privateDflt1; /**< Scheme default register 1 */
+ uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
+ t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
+ uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
+ t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
+ /**< For each extraction used in this scheme, specify the required
+ default register to be used when header is not found.
+ types not specified in this array will get undefined value. */
+ uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
+ t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
+ uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
+ result. 0 means using the 24 LSB's, otherwise use the
+ 24 LSB's after shifting right.*/
+ uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
+ of queues for the key and hash functionality */
+ uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
+ bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
+ destination fields on all layers; If TRUE, driver will check that for
+ all layers, if SRC extraction is selected, DST extraction must also be
+ selected, and vice versa. */
+} t_FmPcdKgKeyExtractAndHashParams;
+
+/**************************************************************************//**
+ @Description A structure of parameters for defining a single
+ Fqid mask (extracted OR).
+*//***************************************************************************/
+typedef struct t_FmPcdKgExtractedOrParams {
+ e_FmPcdExtractType type; /**< Extraction type select */
+ union {
+ struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
+ e_NetHeaderType hdr;
+ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
+ IP. Otherwise should be cleared.*/
+ bool ignoreProtocolValidation;
+ /**< continue extraction even if protocol is not recognized */
+ } extractByHdr;
+ e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
+ };
+ uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
+ e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
+ field not found */
+ uint8_t mask; /**< Extraction mask (specified bits are used) */
+ uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
+ the extracted byte; Assume byte is placed as the 8 MSB's in
+ a 32 bit word where the lower bits
+ are the FQID; i.e if bitOffsetInFqid=1 than its LSB
+ will effect the FQID MSB, if bitOffsetInFqid=24 than the
+ extracted byte will effect the 8 LSB's of the FQID,
+ if bitOffsetInFqid=31 than the byte's MSB will effect
+ the FQID's LSB; 0 means - no effect on FQID;
+ Note that one, and only one of
+ bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
+ extracted byte must effect either FQID or Policer profile).*/
+ uint8_t bitOffsetInPlcrProfile;
+ /**< 0-15, Selects which bits of the 8 policer profile id bits to
+ effect using the extracted byte; Assume byte is placed
+ as the 8 MSB's in a 16 bit word where the lower bits
+ are the policer profile id; i.e if bitOffsetInPlcrProfile=1
+ than its LSB will effect the profile MSB, if bitOffsetInFqid=8
+ than the extracted byte will effect the whole policer profile id,
+ if bitOffsetInFqid=15 than the byte's MSB will effect
+ the Policer Profile id's LSB;
+ 0 means - no effect on policer profile; Note that one, and only one of
+ bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
+ extracted byte must effect either FQID or Policer profile).*/
+} t_FmPcdKgExtractedOrParams;
+
+/**************************************************************************//**
+ @Description A structure for configuring scheme counter
+*//***************************************************************************/
+typedef struct t_FmPcdKgSchemeCounter {
+ bool update; /**< FALSE to keep the current counter state
+ and continue from that point, TRUE to update/reset
+ the counter when the scheme is written. */
+ uint32_t value; /**< If update=TRUE, this value will be written into the
+ counter. clear this field to reset the counter. */
+} t_FmPcdKgSchemeCounter;
+
+/**************************************************************************//**
+ @Description A structure for defining policer profile
+ parameters as required by keygen (when policer
+ is the next engine after this scheme).
+*//***************************************************************************/
+typedef struct t_FmPcdKgPlcrProfile {
+ bool sharedProfile; /**< TRUE if this profile is shared between ports
+ (i.e. managed by master partition) May not be TRUE
+ if profile is after Coarse Classification*/
+ bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
+ id, if FALSE fqidOffsetRelativeProfileIdBase is used
+ together with fqidOffsetShift and numOfProfiles
+ parameters, to define a range of profiles from
+ which the keygen result will determine the
+ destination policer profile. */
+ union {
+ uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
+ This parameter should
+ indicate the policer profile offset within the port's
+ policer profiles or SHARED window. */
+ struct {
+ uint8_t fqidOffsetShift; /**< shift of KG results without the qid base */
+ uint8_t fqidOffsetRelativeProfileIdBase;
+ /**< OR of KG results without the qid base
+ This parameter should indicate the policer profile
+ offset within the port's policer profiles window or
+ SHARED window depends on sharedProfile */
+ uint8_t numOfProfiles; /**< Range of profiles starting at base */
+ } indirectProfile;
+ } profileSelect;
+} t_FmPcdKgPlcrProfile;
+
+/**************************************************************************//**
+ @Description A structure for CC parameters if CC is the next engine after KG
+*//***************************************************************************/
+typedef struct t_FmPcdKgCc {
+ t_Handle h_CcTree; /**< A handle to a CC Tree */
+ uint8_t grpId; /**< CC group id within the CC tree */
+ bool plcrNext; /**< TRUE if after CC, in case of data frame,
+ policing is required. */
+ bool bypassPlcrProfileGeneration;
+ /**< TRUE to bypass keygen policer profile
+ generation (profile selected is the one selected at
+ port initialization). */
+ t_FmPcdKgPlcrProfile plcrProfile; /**< only if plcrNext=TRUE and bypassPlcrProfileGeneration=FALSE */
+} t_FmPcdKgCc;
+
+/**************************************************************************//**
+ @Description A structure for initializing a keygen single scheme
+*//***************************************************************************/
+typedef struct t_FmPcdKgSchemeParams {
+ bool modify; /**< TRUE to change an existing scheme */
+ union
+ {
+ uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
+ t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
+ }id;
+ bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need for match vector. Keygen will ignore
+ it when matching */
+ struct { /**< HL Relevant only if alwaysDirect = FALSE */
+ t_Handle h_NetEnv; /**< A handle to the Network environment as returned
+ by FM_PCD_SetNetEnvCharacteristics() */
+ uint8_t numOfDistinctionUnits; /**< Number of netenv units listed in unitIds array */
+ uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
+ /**< Indexes as passed to SetNetEnvCharacteristics array*/
+ } netEnvParams;
+ bool useHash; /**< use the KG Hash functionality */
+ t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
+ /**< used only if useHash = TRUE */
+ bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
+ In such a case FQID after KG will be the default FQID
+ defined for the relevant port, or the FQID defined by CC
+ in cases where CC was the previous engine. */
+ uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
+ If hash is used and an even distribution is expected
+ according to hashDistributionNumOfFqids, baseFqid must be aligned to
+ hashDistributionNumOfFqids. */
+ uint8_t numOfUsedExtractedOrs; /**< Number of Fqid masks listed in extractedOrs array*/
+ t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
+ /**< IN: FM_PCD_KG_NUM_OF_GENERIC_REGS
+ registers are shared between qidMasks
+ functionality and some of the extraction
+ actions; Normally only some will be used
+ for qidMask. Driver will return error if
+ resource is full at initialization time. */
+ e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
+ union { /**< depends on nextEngine */
+ e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
+ t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
+ t_FmPcdKgCc cc; /**< Used when next engine is CC */
+ } kgNextEngineParams;
+ t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
+ the scheme counter */
+} t_FmPcdKgSchemeParams;
+
+/**************************************************************************//**
+ @Description A structure for defining CC params when CC is the
+ next engine after a CC node.
+*//***************************************************************************/
+typedef struct t_FmPcdCcNextCcParams {
+ t_Handle h_CcNode; /**< A handle of the next CC node */
+} t_FmPcdCcNextCcParams;
+
+/**************************************************************************//**
+ @Description A structure for defining PLCR params when PLCR is the
+ next engine after a CC node.
+*//***************************************************************************/
+typedef struct t_FmPcdCcNextPlcrParams {
+ bool overrideParams; /**< TRUE if CC override previously decided parameters*/
+ bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
+ TRUE if this profile is shared between ports */
+ uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
+ (otherwise profile id is taken from keygen);
+ This parameter should indicate the policer
+ profile offset within the port's
+ policer profiles or from SHARED window.*/
+ uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
+ FQID for enqueuing the frame;
+ In earlier chips if policer next engine is KEYGEN,
+ this parameter can be 0, because the KEYGEN
+ always decides the enqueue FQID.*/
+ bool statisticsEn; /**< In the case of TRUE Statistic counter is
+ incremented for each received frame passed through
+ this Coarse Classification entry.*/
+} t_FmPcdCcNextPlcrParams;
+
+/**************************************************************************//**
+ @Description A structure for defining enqueue params when BMI is the
+ next engine after a CC node.
+*//***************************************************************************/
+typedef struct t_FmPcdCcNextEnqueueParams {
+
+ e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
+ bool overrideFqid; /**< TRUE if CC override previously decided Fqid(by Keygen),
+ relevant if action = e_FM_PCD_ENQ_FRAME */
+ uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
+ (otherwise FQID is taken from keygen),
+ relevant if action = e_FM_PCD_ENQ_FRAME*/
+ bool statisticsEn; /**< In the case of TRUE Statistic counter is
+ incremented for each received frame passed through
+ this Coarse Classification entry.*/
+} t_FmPcdCcNextEnqueueParams;
+
+/**************************************************************************//**
+ @Description A structure for defining KG params when KG is the
+ next engine after a CC node.
+*//***************************************************************************/
+typedef struct t_FmPcdCcNextKgParams {
+ bool overrideFqid; /**< TRUE if CC override previously decided Fqid (by keygen),
+ Note - this parameters irrelevant for earlier chips*/
+ uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
+ (otherwise FQID is taken from keygen),
+ Note - this parameters irrelevant for earlier chips*/
+ t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
+ bool statisticsEn; /**< In the case of TRUE Statistic counter is
+ incremented for each received frame passed through
+ this Coarse Classification entry.*/
+} t_FmPcdCcNextKgParams;
+
+/**************************************************************************//**
+ @Description A structure for defining next engine params after a CC node.
+*//***************************************************************************/
+typedef struct t_FmPcdCcNextEngineParams {
+ e_FmPcdEngine nextEngine; /**< User has to initialize parameters
+ according to nextEngine definition */
+ union {
+ t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
+ t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
+ t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
+ t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
+ } params;
+#if defined(FM_CAPWAP_SUPPORT)
+ t_Handle h_Manip; /**< Handler to headerManip.
+ Relevant if next engine of the type result
+ (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
+#endif /* defined(FM_CAPWAP_SUPPORT) || ... */
+} t_FmPcdCcNextEngineParams;
+
+/**************************************************************************//**
+ @Description A structure for defining a single CC Key parameters
+*//***************************************************************************/
+typedef struct t_FmPcdCcKeyParams {
+ uint8_t *p_Key; /**< pointer to the key of the size defined in keySize*/
+ uint8_t *p_Mask; /**< pointer to the Mask per key of the size defined
+ in keySize. p_Key and p_Mask (if defined) has to be
+ of the same size defined in the keySize */
+ t_FmPcdCcNextEngineParams ccNextEngineParams;
+ /**< parameters for the next for the defined Key in
+ the p_Key */
+} t_FmPcdCcKeyParams;
+
+/**************************************************************************//**
+ @Description A structure for defining CC Keys parameters
+*//***************************************************************************/
+typedef struct t_KeysParams {
+ uint8_t numOfKeys; /**< Number Of relevant Keys */
+ uint8_t keySize; /**< size of the key - in the case of the extraction of
+ the type FULL_FIELD keySize has to be as standard size of the relevant
+ key. In the another type of extraction keySize has to be as size of extraction.
+ In the case of action = e_FM_PCD_ACTION_INDEXED_LOOKUP the size of keySize has to be 2*/
+ t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
+ /**< it's array with numOfKeys entries each entry in
+ the array of the type t_FmPcdCcKeyParams */
+ t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
+ /**< parameters for the next step of
+ unfound (or undefined) key . Not relevant in the case
+ of action = e_FM_PCD_ACTION_INDEXED_LOOKUP*/
+} t_KeysParams;
+
+/**************************************************************************//**
+ @Description A structure for defining the CC node params
+*//***************************************************************************/
+typedef struct t_FmPcdCcNodeParams {
+ t_FmPcdExtractEntry extractCcParams; /**< params which defines extraction parameters */
+ t_KeysParams keysParams; /**< params which defines Keys parameters of the
+ extraction defined in extractCcParams */
+} t_FmPcdCcNodeParams;
+
+/**************************************************************************//**
+ @Description A structure for defining each CC tree group in term of
+ NetEnv units and the action to be taken in each case.
+ the unitIds list must be in order from lower to higher indexes.
+
+ t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
+ structures where each defines the next action to be taken for
+ each units combination. for example:
+ numOfDistinctionUnits = 2
+ unitIds = {1,3}
+ p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
+ unit 1 - not found; unit 3 - not found;
+ p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
+ unit 1 - not found; unit 3 - found;
+ p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
+ unit 1 - found; unit 3 - not found;
+ p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
+ unit 1 - found; unit 3 - found;
+*//***************************************************************************/
+typedef struct t_FmPcdCcGrpParams {
+ uint8_t numOfDistinctionUnits; /**< up to 4 */
+ uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
+ /**< Indexes of the units as defined in
+ FM_PCD_SetNetEnvCharacteristics() */
+ t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
+ /**< Max size is 16 - if only one group used */
+} t_FmPcdCcGrpParams;
+
+/**************************************************************************//**
+ @Description A structure for defining the CC tree groups
+*//***************************************************************************/
+typedef struct t_FmPcdCcTreeParams {
+ t_Handle h_NetEnv; /**< A handle to the Network environment as returned
+ by FM_PCD_SetNetEnvCharacteristics() */
+ uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
+ t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS]; /**< Parameters for each group. */
+} t_FmPcdCcTreeParams;
+
+/**************************************************************************//**
+ @Description A structure for defining parameters for byte rate
+*//***************************************************************************/
+typedef struct t_FmPcdPlcrByteRateModeParams {
+ e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
+ e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
+ e_FM_PCD_PLCR_FULL_FRM_LEN */
+} t_FmPcdPlcrByteRateModeParams;
+
+/**************************************************************************//**
+ @Description A structure for selcting the policer profile RFC-2698 or
+ RFC-4115 parameters
+*//***************************************************************************/
+typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
+ e_FmPcdPlcrRateMode rateMode; /**< Byte / Packet */
+ t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
+ uint32_t comittedInfoRate; /**< KBits/Sec or Packets/Sec */
+ uint32_t comittedBurstSize; /**< Bytes/Packets */
+ uint32_t peakOrAccessiveInfoRate; /**< KBits/Sec or Packets/Sec */
+ uint32_t peakOrAccessiveBurstSize; /**< Bytes/Packets */
+} t_FmPcdPlcrNonPassthroughAlgParams;
+
+/**************************************************************************//**
+ @Description A union for defining Policer next engine parameters
+*//***************************************************************************/
+typedef union u_FmPcdPlcrNextEngineParams {
+ e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
+ t_Handle h_Profile; /**< Policer profile handle - used when next engine
+ is PLCR, must be a SHARED profile */
+ t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is Keygen */
+} u_FmPcdPlcrNextEngineParams;
+
+/**************************************************************************//**
+ @Description A structure for selecting the policer profile entry parameters
+*//***************************************************************************/
+typedef struct t_FmPcdPlcrProfileParams {
+ bool modify; /**< TRUE to change an existing profile */
+ union {
+ struct {
+ e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
+ t_Handle h_FmPort; /**< Relevant for per-port profiles only */
+ uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
+ } newParams; /**< use it when modify=FALSE */
+ t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
+ } id;
+ e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
+ e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
+
+ union {
+ e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode. the policer will re-color
+ any incoming packet with the default value. */
+ e_FmPcdPlcrColor override; /**< For Color-Aware modes. The profile response to a
+ pre-color value of 2'b11. */
+ } color;
+
+ t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 params */
+
+ e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
+ u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
+
+ e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
+ u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
+
+ e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
+ u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
+
+ bool trapProfileOnFlowA; /**< Trap on flow A */
+ bool trapProfileOnFlowB; /**< Trap on flow B */
+ bool trapProfileOnFlowC; /**< Trap on flow C */
+} t_FmPcdPlcrProfileParams;
+
+#if defined(FM_CAPWAP_SUPPORT)
+/**************************************************************************//**
+ @Description A structure for selecting the location of manipulation
+*//***************************************************************************/
+typedef struct t_FmPcdManipLocationParams {
+ e_FmPcdManipLocateType type; /**< location of manipulation type select */
+ struct { /**< used when type = e_FM_PCD_MANIP_BY_HDR */
+ e_NetHeaderType hdr; /**< Header selection */
+ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
+ IP. Otherwise should be cleared. */
+ bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
+ t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
+ } manipByHdr;
+} t_FmPcdManipLocationParams;
+
+/**************************************************************************//**
+ @Description structure for defining insert manipulation
+ of the type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
+*//***************************************************************************/
+typedef struct t_FmPcdManipInsrtByTemplateParams {
+ uint8_t size; /**< size of insert template to the start of the frame. */
+ uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
+ /**< array of the insertion template. */
+
+ bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
+ struct {
+ uint16_t ipOuterOffset; /**< offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
+ uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
+ in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
+ bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
+ uint8_t udpOffset; /**< offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
+ uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
+ bool recalculateLength; /**< TRUE if recalculate length has to be performed due to the engines in the path which can change the frame later, relevant if modifyOuterIp = TRUE.*/
+ struct {
+ uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP-total-len field.*/
+ uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP-total-len field and UDP length*/
+ uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP-total-len field and UDP length.*/
+ } recalculateLengthParams; /**< recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
+ } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
+
+ bool modifyOuterVlan; /**< TRUE if user wants to modify vpri field in the outer VLAN header*/
+ struct {
+ uint8_t vpri; /**< value of vpri, relevant if modifyOuterVlan = TRUE
+ vpri only 3 bits, it has to be adjusted to the right*/
+ } modifyOuterVlanParams;
+} t_FmPcdManipInsrtByTemplateParams;
+#endif /* defined(FM_CAPWAP_SUPPORT) || ... */
+
+
+#ifdef FM_CAPWAP_SUPPORT
+/**************************************************************************//**
+ @Description structure for defining CAPWAP fragmentation
+*//***************************************************************************/
+typedef struct t_CapwapFragmentationParams {
+ uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
+ bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
+ and all other fragments exclude the CAPWAP options field,
+ FALSE - all fragments include CAPWAP header options field. */
+} t_CapwapFragmentationParams;
+
+/**************************************************************************//**
+ @Description structure for defining CAPWAP Re-assembly
+*//***************************************************************************/
+typedef struct t_CapwapReassemblyParams {
+ uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time.
+ It has to be power of 2.
+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
+ maxNumFramesInProcess has to be in the range of 4 - 512,
+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
+ maxNumFramesInProcess has to be in the range of 8 - 2048 */
+ bool haltOnDuplicationFrag; /**< In the case of TRUE, Reassembly process halted due to duplicated fragment,
+ and all processed fragments passed for enqueue with error indication.
+ In the case of FALSE, only duplicated fragment passed for enqueue with error indication */
+
+ e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
+ uint32_t fqidForTimeOutFrames; /**< Fqid in which time out frames will enqueue during Time Out Process */
+ uint32_t timeoutRoutineRequestTime;
+ /**< Represents the time interval in microseconds between consecutive
+ timeout routine requests It has to be power of 2. */
+ uint32_t timeoutThresholdForReassmProcess;
+ /**< Represents the time interval in microseconds which defines
+ if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
+
+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry needed for reassembly process */
+} t_CapwapReassemblyParams;
+#endif /* FM_CAPWAP_SUPPORT */
+
+
+#if defined(FM_CAPWAP_SUPPORT)
+/**************************************************************************//**
+ @Description structure for defining fragmentation/reassembly
+*//***************************************************************************/
+typedef struct t_FmPcdManipFragOrReasmParams {
+ bool frag; /**< TRUE if using the structure for fragmentation,
+ otherwise this structure is used for reassembly */
+ uint8_t extBufPoolIndx; /**< Index of the buffer pool ID which was configured for port
+ and can be used for manipulation;
+ NOTE: This field is relevant only for CAPWAP fragmentation
+ and reassembly */
+ e_NetHeaderType hdr; /**< Header selection */
+ union {
+#ifdef FM_CAPWAP_SUPPORT
+ t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation, relevant if frag = TRUE, hdr = HEADER_TYPE_CAPWAP */
+ t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly, relevant if frag = FALSE, hdr = HEADER_TYPE_CAPWAP */
+#endif /* FM_CAPWAP_SUPPORT */
+ };
+} t_FmPcdManipFragOrReasmParams;
+
+/**************************************************************************//**
+ @Description structure for defining insert manipulation
+*//***************************************************************************/
+typedef struct t_FmPcdManipInsrtParams {
+ e_FmPcdManipInsrtType type; /**< Type of insert manipulation */
+ union {
+ t_FmPcdManipInsrtByTemplateParams insrtByTemplateParams;
+ /**< parameters for insert manipulation, relevant if
+ type = e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE */
+ };
+} t_FmPcdManipInsrtParams;
+
+/**************************************************************************//**
+ @Description structure for defining remove manipulation
+*//***************************************************************************/
+typedef struct t_FmPcdManipRmvParams {
+ e_FmPcdManipRmvParamsType type; /**< Type of remove manipulation */
+ t_FmPcdManipLocationParams rmvSpecificLocationParams;
+ /**< Specified location of remove manipulation;
+ This params should be initialized in cases:
+ - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_SPECIFIC_LOCATION
+ - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION */
+} t_FmPcdManipRmvParams;
+
+/**************************************************************************//**
+ @Description structure for defining manipulation
+*//***************************************************************************/
+typedef struct t_FmPcdManipParams {
+ bool rmv; /**< TRUE, if defined remove manipulation */
+ t_FmPcdManipRmvParams rmvParams; /**< Parameters for remove manipulation, relevant if rmv = TRUE */
+
+ bool insrt; /**< TRUE, if defined insert manipulation */
+ t_FmPcdManipInsrtParams insrtParams; /**< Parameters for insert manipulation, relevant if insrt = TRUE */
+
+ bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
+ t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation, relevant if fragOrReasm = TRUE */
+
+ /**< General parameters */
+ bool treatFdStatusFieldsAsErrors;
+ /**< Set to TRUE when the port that is using this manip is chained
+ to SEC (i.e. the traffic was forwarded from SEC) */
+} t_FmPcdManipParams;
+
+/**************************************************************************//**
+ @Description structure for defining statistics node
+*//***************************************************************************/
+typedef struct t_FmPcdStatsParams {
+ e_FmPcdStatsType type; /**< type of statistics node */
+} t_FmPcdStatsParams;
+#endif /* defined(FM_CAPWAP_SUPPORT) || ... */
+
+
+/**************************************************************************//**
+ @Function FM_PCD_SetNetEnvCharacteristics
+
+ @Description Define a set of Network Environment Characteristics.
+ When setting an environment it is important to understand its
+ application. It is not meant to describe the flows that will run
+ on the ports using this environment, but what the user means TO DO
+ with the PCD mechanisms in order to parse-classify-distribute those
+ frames.
+ By specifying a distinction unit, the user means it would use that option
+ for distinction between frames at either a keygen scheme keygen or a coarse
+ classification action descriptor. Using interchangeable headers to define a
+ unit means that the user is indifferent to which of the interchangeable
+ headers is present in the frame, and they want the distinction to be based
+ on the presence of either one of them.
+ Depending on context, there are limitations to the use of environments. A
+ port using the PCD functionality is bound to an environment. Some or even
+ all ports may share an environment but also an environment per port is
+ possible. When initializing a scheme, a classification plan group (see below),
+ or a coarse classification tree, one of the initialized environments must be
+ stated and related to. When a port is bound to a scheme, a classification
+ plan group, or a coarse classification tree, it MUST be bound to the same
+ environment.
+ The different PCD modules, may relate (for flows definition) ONLY on
+ distinction units as defined by their environment. When initializing a
+ scheme for example, it may not choose to select IPV4 as a match for
+ recognizing flows unless it was defined in the relating environment. In
+ fact, to guide the user through the configuration of the PCD, each module's
+ characterization in terms of flows is not done using protocol names, but using
+ environment indexes.
+ In terms of HW implementation, the list of distinction units sets the LCV vectors
+ and later used for match vector, classification plan vectors and coarse classification
+ indexing.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] p_NetEnvParams A structure of parameters for the initialization of
+ the network environment.
+
+ @Return A handle to the initialized object on success; NULL code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Handle FM_PCD_SetNetEnvCharacteristics(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_DeleteNetEnvCharacteristics
+
+ @Description Deletes a set of Network Environment Characteristics.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] h_NetEnv A handle to the Network environment.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PCD_DeleteNetEnvCharacteristics(t_Handle h_FmPcd, t_Handle h_NetEnv);
+
+/**************************************************************************//**
+ @Function FM_PCD_KgSetScheme
+
+ @Description Initializing or modifying and enabling a scheme for the keygen.
+ This routine should be called for adding or modifying a scheme.
+ When a scheme needs modifying, the API requires that it will be
+ rewritten. In such a case 'modify' should be TRUE. If the
+ routine is called for a valid scheme and 'modify' is FALSE,
+ it will return error.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in,out] p_Scheme A structure of parameters for defining the scheme
+
+ @Return A handle to the initialized scheme on success; NULL code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Handle FM_PCD_KgSetScheme (t_Handle h_FmPcd,
+ t_FmPcdKgSchemeParams *p_Scheme);
+
+/**************************************************************************//**
+ @Function FM_PCD_KgDeleteScheme
+
+ @Description Deleting an initialized scheme.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSetScheme
+
+ @Return E_OK on success; Error code otherwise.
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_KgDeleteScheme(t_Handle h_FmPcd, t_Handle h_Scheme);
+
+/**************************************************************************//**
+ @Function FM_PCD_KgGetSchemeCounter
+
+ @Description Reads scheme packet counter.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSetScheme.
+
+ @Return Counter's current value.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+uint32_t FM_PCD_KgGetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme);
+
+/**************************************************************************//**
+ @Function FM_PCD_KgSetSchemeCounter
+
+ @Description Writes scheme packet counter.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSetScheme.
+ @Param[in] value New scheme counter value - typically '0' for
+ resetting the counter.
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_KgSetSchemeCounter(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t value);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcBuildTree
+
+ @Description This routine must be called to define a complete coarse
+ classification tree. This is the way to define coarse
+ classification to a certain flow - the keygen schemes
+ may point only to trees defined in this way.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] p_FmPcdCcTreeParams A structure of parameters to define the tree.
+
+ @Return A handle to the initialized object on success; NULL code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Handle FM_PCD_CcBuildTree (t_Handle h_FmPcd,
+ t_FmPcdCcTreeParams *p_FmPcdCcTreeParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcDeleteTree
+
+ @Description Deleting an built tree.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcTree A handle to a CC tree.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_CcDeleteTree(t_Handle h_FmPcd, t_Handle h_CcTree);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcSetNode
+
+ @Description This routine should be called for each CC (coarse classification)
+ node. The whole CC tree should be built bottom up so that each
+ node points to already defined nodes.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] p_CcNodeParam A structure of parameters defining the CC node
+
+ @Return A handle to the initialized object on success; NULL code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Handle FM_PCD_CcSetNode(t_Handle h_FmPcd,
+ t_FmPcdCcNodeParams *p_CcNodeParam);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcDeleteNode
+
+ @Description Deleting an built node.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to a CC node.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_CcDeleteNode(t_Handle h_FmPcd, t_Handle h_CcNode);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcTreeModifyNextEngine
+
+ @Description Modify the Next Engine Parameters in the entry of the tree.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcTree A handle to the tree
+ @Param[in] grpId A Group index in the tree
+ @Param[in] index Entry index in the group defined by grpId
+ @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine params
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_CcBuildTree().
+*//***************************************************************************/
+t_Error FM_PCD_CcTreeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcNodeModifyNextEngine
+
+ @Description Modify the Next Engine Parameters in the relevant key entry of the node.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to the node
+ @Param[in] keyIndex Key index for Next Engine Params modifications
+ @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine params
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_CcSetNode().
+*//***************************************************************************/
+t_Error FM_PCD_CcNodeModifyNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcNodeModifyMissNextEngine
+
+ @Description Modify the Next Engine Parameters of the Miss key case of the node.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to the node
+ @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine params
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_CcSetNode().
+*//***************************************************************************/
+t_Error FM_PCD_CcNodeModifyMissNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcNodeRemoveKey
+
+ @Description Remove the key (include Next Engine Parameters of this key) defined by the index of the relevant node .
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to the node
+ @Param[in] keyIndex Key index for removing
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also
+ the node that points to this node
+*//***************************************************************************/
+t_Error FM_PCD_CcNodeRemoveKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcNodeAddKey
+
+ @Description Add the key(include Next Engine Parameters of this key)in the index defined by the keyIndex .
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to the node
+ @Param[in] keyIndex Key index for adding
+ @Param[in] keySize Key size of added key
+ @Param[in] p_KeyParams A pointer to the parameters includes new key with Next Engine Parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also
+ the node that points to this node
+*//***************************************************************************/
+t_Error FM_PCD_CcNodeAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcNodeModifyKeyAndNextEngine
+
+ @Description Modify the key and Next Engine Parameters of this key in the index defined by the keyIndex .
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to the node
+ @Param[in] keyIndex Key index for adding
+ @Param[in] keySize Key size of added key
+ @Param[in] p_KeyParams A pointer to the parameters includes modified key and modified Next Engine Parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also
+ the node that points to this node
+*//***************************************************************************/
+t_Error FM_PCD_CcNodeModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_KeyParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcNodeModifyKey
+
+ @Description Modify the key in the index defined by the keyIndex .
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to the node
+ @Param[in] keyIndex Key index for adding
+ @Param[in] keySize Key size of added key
+ @Param[in] p_Key A pointer to the new key
+ @Param[in] p_Mask A pointer to the new mask if relevant, otherwise pointer to NULL
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also
+ the node that points to this node
+*//***************************************************************************/
+t_Error FM_PCD_CcNodeModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask);
+
+/**************************************************************************//**
+ @Function FM_PCD_CcNodeGetKeyCounter
+
+ @Description This routine may be used to get a counter of specific key in a CC
+ Node; This counter reflects how many frames passed that were matched
+ this key.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_CcNode A handle to the node
+ @Param[in] keyIndex Key index for adding
+
+ @Return The specific key counter.
+
+ @Cautions Allowed only following FM_PCD_CcSetNode() not only of the relevant node but also
+ the node that points to this node
+*//***************************************************************************/
+uint32_t FM_PCD_CcNodeGetKeyCounter(t_Handle h_FmPcd, t_Handle h_CcNode, uint8_t keyIndex);
+
+/**************************************************************************//**
+ @Function FM_PCD_PlcrSetProfile
+
+ @Description Sets a profile entry in the policer profile table.
+ The routine overrides any existing value.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] p_Profile A structure of parameters for defining a
+ policer profile entry.
+
+ @Return A handle to the initialized object on success; NULL code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Handle FM_PCD_PlcrSetProfile(t_Handle h_FmPcd,
+ t_FmPcdPlcrProfileParams *p_Profile);
+
+/**************************************************************************//**
+ @Function FM_PCD_PlcrDeleteProfile
+
+ @Description Delete a profile entry in the policer profile table.
+ The routine set entry to invalid.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_Profile A handle to the profile.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_PlcrDeleteProfile(t_Handle h_FmPcd, t_Handle h_Profile);
+
+/**************************************************************************//**
+ @Function FM_PCD_PlcrGetProfileCounter
+
+ @Description Sets an entry in the classification plan.
+ The routine overrides any existing value.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_Profile A handle to the profile.
+ @Param[in] counter Counter selector.
+
+ @Return specific counter value.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+uint32_t FM_PCD_PlcrGetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
+
+/**************************************************************************//**
+ @Function FM_PCD_PlcrSetProfileCounter
+
+ @Description Sets an entry in the classification plan.
+ The routine overrides any existing value.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_Profile A handle to the profile.
+ @Param[in] counter Counter selector.
+ @Param[in] value value to set counter with.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_PlcrSetProfileCounter(t_Handle h_FmPcd, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
+
+#if defined(FM_CAPWAP_SUPPORT)
+/**************************************************************************//**
+ @Function FM_PCD_ManipSetNode
+
+ @Description This routine should be called for defining a manipulation
+ node. A manipulation node must be defined before the CC node
+ that precedes it.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
+
+ @Return A handle to the initialized object on success; NULL code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Handle FM_PCD_ManipSetNode(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
+
+/**************************************************************************//**
+ @Function FM_PCD_ManipDeleteNode
+
+ @Description Delete an existing manip node.
+
+ @Param[in] h_FmPcd A handle to an FM PCD Module.
+ @Param[in] h_HdrManipNode A handle to a Manip node.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Error FM_PCD_ManipDeleteNode(t_Handle h_FmPcd, t_Handle h_HdrManipNode);
+#endif /* defined(FM_CAPWAP_SUPPORT) || ... */
+
+
+#ifdef FM_CAPWAP_SUPPORT
+/**************************************************************************//**
+ @Function FM_PCD_StatisticsSetNode
+
+ @Description This routine should be called for defining a statistics
+ node.
+
+ @Param[in] h_FmPcd FM PCD module descriptor.
+ @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
+
+ @Return A handle to the initialized object on success; NULL code otherwise.
+
+ @Cautions Allowed only following FM_PCD_Init().
+*//***************************************************************************/
+t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
+#endif /* FM_CAPWAP_SUPPORT */
+
+/** @} */ /* end of FM_PCD_Runtime_tree_buildgrp group */
+/** @} */ /* end of FM_PCD_Runtime_grp group */
+/** @} */ /* end of FM_PCD_grp group */
+/** @} */ /* end of FM_grp group */
+
+
+
+#endif /* __FM_PCD_EXT */
diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h
new file mode 100644
index 0000000..d1df4ea
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/fm_port_ext.h
@@ -0,0 +1,2196 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_port_ext.h
+
+ @Description FM-Port Application Programming Interface.
+*//***************************************************************************/
+#ifndef __FM_PORT_EXT
+#define __FM_PORT_EXT
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "fm_pcd_ext.h"
+#include "fm_ext.h"
+#include "net_ext.h"
+
+
+/**************************************************************************//**
+
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group FM_PORT_grp FM Port
+
+ @Description FM Port API
+
+ The FM uses a general module called "port" to represent a Tx port
+ (MAC), an Rx port (MAC), offline parsing flow or host command
+ flow. There may be up to 17 (may change) ports in an FM - 5 Tx
+ ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
+ Host command/Offline parsing ports. The SW driver manages these
+ ports as sub-modules of the FM, i.e. after an FM is initialized,
+ its ports may be initialized and operated upon.
+
+ The port is initialized aware of its type, but other functions on
+ a port may be indifferent to its type. When necessary, the driver
+ verifies coherency and returns error if applicable.
+
+ On initialization, user specifies the port type and it's index
+ (relative to the port's type). Host command and Offline parsing
+ ports share the same id range, I.e user may not initialized host
+ command port 0 and offline parsing port 0.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description An enum for defining port PCD modes.
+ This enum defines the superset of PCD engines support - i.e. not
+ all engines have to be used, but all have to be enabled. The real
+ flow of a specific frame depends on the PCD configuration and the
+ frame headers and payload.
+*//***************************************************************************/
+typedef enum e_FmPortPcdSupport {
+ e_FM_PORT_PCD_SUPPORT_NONE = 0, /**< BMI to BMI, PCD is not used */
+ e_FM_PORT_PCD_SUPPORT_PRS_ONLY, /**< Use only Parser */
+ e_FM_PORT_PCD_SUPPORT_PLCR_ONLY, /**< Use only Policer */
+ e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR, /**< Use Parser and Policer */
+ e_FM_PORT_PCD_SUPPORT_PRS_AND_KG, /**< Use Parser and Keygen */
+ e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC, /**< Use Parser, Keygen and Coarse Classification */
+ e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR,
+ /**< Use all PCD engines */
+ e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
+#ifdef FM_CAPWAP_SUPPORT
+ ,
+ e_FM_PORT_PCD_SUPPORT_CC_ONLY, /**< Use only Coarse Classification */
+ e_FM_PORT_PCD_SUPPORT_CC_AND_KG, /**< Use Coarse Classification,and Keygen */
+ e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
+#endif /* FM_CAPWAP_SUPPORT */
+} e_FmPortPcdSupport;
+
+/**************************************************************************//**
+ @Description Port interrupts
+*//***************************************************************************/
+typedef enum e_FmPortExceptions {
+ e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
+} e_FmPortExceptions;
+
+
+/**************************************************************************//**
+ @Collection General FM Port defines
+*//***************************************************************************/
+#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
+/* @} */
+
+/**************************************************************************//**
+ @Collection FM Frame error
+*//***************************************************************************/
+typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
+
+#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Offline parsing only! Unsupported Format */
+#define FM_PORT_FRM_ERR_LENGTH 0x02000000 /**< Offline parsing only! Length Error */
+#define FM_PORT_FRM_ERR_DMA 0x01000000 /**< DMA Data error */
+#ifdef FM_CAPWAP_SUPPORT
+#define FM_PORT_FRM_ERR_NON_FM 0x00400000 /**< non Frame-Manager error; probably come from SEC that
+ was chained to FM */
+#endif /* FM_CAPWAP_SUPPORT */
+#define FM_PORT_FRM_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
+ error (SGMII and TBI modes), FIFO parity error. PHY
+ Sequence error, PHY error control character detected. */
+#define FM_PORT_FRM_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
+#define FM_PORT_FRM_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
+#define FM_PORT_FRM_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
+#define FM_PORT_FRM_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
+#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
+#define FM_PORT_FRM_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
+#define FM_PORT_FRM_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
+#define FM_PORT_FRM_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
+#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
+#define FM_PORT_FRM_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
+#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
+#define FM_PORT_FRM_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
+#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
+#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
+/* @} */
+
+
+
+/**************************************************************************//**
+ @Group FM_PORT_init_grp FM Port Initialization Unit
+
+ @Description FM Port Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Exceptions user callback routine, will be called upon an
+ exception passing the exception identification.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] exception - The exception.
+ *//***************************************************************************/
+typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
+
+/**************************************************************************//**
+ @Description User callback function called by driver with received data.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App Application's handle originally specified to
+ the API Config function
+ @Param[in] p_Data A pointer to data received
+ @Param[in] length length of received data
+ @Param[in] status receive status and errors
+ @Param[in] position position of buffer in frame
+ @Param[in] h_BufContext A handle of the user acossiated with this buffer
+
+ @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
+ operation for all ready data.
+ @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
+*//***************************************************************************/
+typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
+ uint8_t *p_Data,
+ uint16_t length,
+ uint16_t status,
+ uint8_t position,
+ t_Handle h_BufContext);
+
+/**************************************************************************//**
+ @Description User callback function called by driver when transmit completed.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App Application's handle originally specified to
+ the API Config function
+ @Param[in] p_Data A pointer to data received
+ @Param[in] status transmit status and errors
+ @Param[in] lastBuffer is last buffer in frame
+ @Param[in] h_BufContext A handle of the user acossiated with this buffer
+ *//***************************************************************************/
+typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
+ uint8_t *p_Data,
+ uint16_t status,
+ t_Handle h_BufContext);
+
+/**************************************************************************//**
+ @Description A structure of information about each of the external
+ buffer pools used by the port,
+*//***************************************************************************/
+typedef struct t_FmPortExtPoolParams {
+ uint8_t id; /**< External buffer pool id */
+ uint16_t size; /**< External buffer pool buffer size */
+} t_FmPortExtPoolParams;
+
+/**************************************************************************//**
+ @Description A structure for informing the driver about the external
+ buffer pools allocated in the BM and used by this port.
+*//***************************************************************************/
+typedef struct t_FmPortExtPools {
+ uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
+ t_FmPortExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
+ /**< Parameters for each port */
+} t_FmPortExtPools;
+
+/**************************************************************************//**
+ @Description structure for additional Rx port parameters
+*//***************************************************************************/
+typedef struct t_FmPortRxParams {
+ uint32_t errFqid; /**< Error Queue Id. */
+ uint32_t dfltFqid; /**< Default Queue Id. */
+ uint16_t liodnOffset; /**< Port's LIODN offset. */
+ t_FmPortExtPools extBufPools; /**< Which external buffer pools are used
+ (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
+} t_FmPortRxParams;
+
+/**************************************************************************//**
+ @Description structure for additional non-Rx port parameters
+*//***************************************************************************/
+typedef struct t_FmPortNonRxParams {
+ uint32_t errFqid; /**< Error Queue Id. */
+ uint32_t dfltFqid; /**< For Tx and HC - Default Confirmation queue,
+ 0 means no Tx confirmation for processed
+ frames. For OP - default Rx queue. */
+ uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
+ by the FM for dequeue. */
+#ifdef FM_OP_PARTITION_ERRATA_FMANx8
+ uint16_t opLiodnOffset; /**< For Offline Parsing ports only. Port's LIODN offset. */
+#endif /* FM_OP_PARTITION_ERRATA_FMANx8 */
+} t_FmPortNonRxParams;
+
+/**************************************************************************//**
+ @Description structure for additional Rx port parameters
+*//***************************************************************************/
+typedef struct t_FmPortImRxTxParams {
+ t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
+ uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
+ uint8_t dataMemId; /**< Memory partition ID for data buffers */
+ uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
+ t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
+ t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
+ t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
+} t_FmPortImRxTxParams;
+
+/**************************************************************************//**
+ @Description Union for additional parameters depending on port type
+*//***************************************************************************/
+typedef union u_FmPortSpecificParams {
+ t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
+ t_FmPortRxParams rxParams; /**< Rx port parameters structure */
+ t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
+} u_FmPortSpecificParams;
+
+/**************************************************************************//**
+ @Description structure representing FM initialization parameters
+*//***************************************************************************/
+typedef struct t_FmPortParams {
+ uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
+ t_Handle h_Fm; /**< A handle to the FM object this port related to */
+ e_FmPortType portType; /**< Port type */
+ uint8_t portId; /**< Port Id - relative to type */
+ bool independentModeEnable;
+ /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
+ uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
+ used together with LIODN offset. */
+ u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
+ type. */
+
+ t_FmPortExceptionCallback *f_Exception; /**< Callback routine to be called of PCD exception */
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+} t_FmPortParams;
+
+
+/**************************************************************************//**
+ @Function FM_PORT_Config
+
+ @Description Creates descriptor for the FM PORT module.
+
+ The routine returns a handle (descriptor) to the FM PORT object.
+ This descriptor must be passed as first parameter to all other
+ FM PORT function calls.
+
+ No actual initialization or configuration of FM hardware is
+ done by this routine.
+
+ @Param[in] p_FmPortParams - Pointer to data structure of parameters
+
+ @Retval Handle to FM object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
+
+/**************************************************************************//**
+ @Function FM_PORT_Init
+
+ @Description Initializes the FM PORT module
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PORT_Init(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_Free
+
+ @Description Frees all resources that were assigned to FM PORT module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PORT_Free(t_Handle h_FmPort);
+
+
+/**************************************************************************//**
+ @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for defining QM frame dequeue
+*//***************************************************************************/
+typedef enum e_FmPortDeqType {
+ e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
+ and Intra-Class Scheduling respected. */
+ e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
+ and Intra-Class Scheduling respected. */
+ e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
+ and override Intra-Class Scheduling */
+} e_FmPortDeqType;
+
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+/**************************************************************************//**
+ @Description enum for defining QM frame dequeue
+*//***************************************************************************/
+typedef enum e_FmPortDeqPrefetchOption {
+ e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
+ only when a dedicated portID Tnum is waiting. */
+ e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
+ one dedicated portId tnum is waiting. */
+ e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
+ no dedicated portId tnums are waiting. */
+
+} e_FmPortDeqPrefetchOption;
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+/**************************************************************************//**
+ @Description enum for defining port DMA swap mode
+*//***************************************************************************/
+typedef enum e_FmPortDmaSwap {
+ e_FM_PORT_DMA_NO_SWP, /**< No swap, transfer data as is.*/
+ e_FM_PORT_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
+ in PowerPc Little Endian mode. */
+ e_FM_PORT_DMA_SWP_BE /**< The transferred data should be swapped
+ in Big Endian mode */
+} e_FmPortDmaSwap;
+
+/**************************************************************************//**
+ @Description enum for defining port DMA cache attributes
+*//***************************************************************************/
+typedef enum e_FmPortDmaCache {
+ e_FM_PORT_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
+ e_FM_PORT_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
+} e_FmPortDmaCache;
+
+/**************************************************************************//**
+ @Description enum for defining port default color
+*//***************************************************************************/
+typedef enum e_FmPortColor {
+ e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
+ e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
+ e_FM_PORT_COLOR_RED, /**< Default port color is red */
+ e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
+} e_FmPortColor;
+
+/**************************************************************************//**
+ @Description struct for defining Dual Tx rate limiting scale
+*//***************************************************************************/
+typedef enum e_FmPortDualRateLimiterScaleDown {
+ e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
+ e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
+ e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
+ e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
+} e_FmPortDualRateLimiterScaleDown;
+
+
+/**************************************************************************//**
+ @Description struct for defining FM port resources
+*//***************************************************************************/
+typedef struct t_FmPortRsrc {
+ uint32_t num; /**< Committed required resource */
+ uint32_t extra; /**< Extra (not committed) required resource */
+} t_FmPortRsrc;
+
+/**************************************************************************//**
+ @Description struct for defining pool depletion criteria
+*//***************************************************************************/
+typedef struct t_FmPortBufPoolDepletion {
+ bool numberOfPoolsModeEnable; /**< select mode in which pause frames will be sent after
+ a number of pools are depleted */
+ uint8_t numOfPools; /**< the minimum number of depleted pools that will
+ invoke pause frames transmission. */
+ bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
+ /**< For each pool, TRUE if it should be considered for
+ depletion (Note - this pool must be used by this port!) */
+ bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
+ a single of pools are depleted */
+ bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
+ /**< For each pool, TRUE if it should be considered for
+ depletion (Note - this pool must be used by this port!) */
+} t_FmPortBufPoolDepletion;
+
+/**************************************************************************//**
+ @Description struct for defining observed pool depletion
+*//***************************************************************************/
+typedef struct t_FmPortObservedBufPoolDepletion {
+ t_FmPortBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
+ t_FmPortExtPools poolsParams; /**< Which external buffer pools are observed
+ (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
+ and their sizes. */
+} t_FmPortObservedBufPoolDepletion;
+
+/**************************************************************************//**
+ @Description struct for defining Tx rate limiting
+*//***************************************************************************/
+typedef struct t_FmPortRateLimit {
+ uint16_t maxBurstSize; /**< in kBytes for Tx ports, in frames
+ for offline parsing ports. (note that
+ for early chips burst size is
+ rounded up to a multiply of 1000 frames).*/
+ uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
+ offline parsing ports. Rate limit refers to
+ data rate (rather than line rate). */
+ e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For offline parsing ports only. Not-valid
+ for some earlier chip revisions */
+} t_FmPortRateLimit;
+
+/**************************************************************************//**
+ @Description struct for defining define the parameters of
+ the Rx port performance counters
+*//***************************************************************************/
+typedef struct t_FmPortPerformanceCnt {
+ uint8_t taskCompVal; /**< Task compare value */
+ uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
+ value (unused for H/O) */
+ uint8_t dmaCompVal; /**< Dma compare value */
+ uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
+} t_FmPortPerformanceCnt;
+
+/**************************************************************************//**
+ @Description struct for defining buffer content.
+*//***************************************************************************/
+typedef struct t_FmPortBufferPrefixContent {
+ uint16_t privDataSize; /**< Number of bytes to be left at the beginning
+ of the external buffer */
+ bool passPrsResult; /**< TRUE to pass the parse result to/from the FM */
+ bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM */
+ bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM */
+ bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
+ AD, hash-result, key, etc. */
+ uint16_t dataAlign; /**< 0 to use driver's default alignment, other value
+ for selecting a data alignment (must be a
+ power of 2) */
+#ifdef DEBUG
+ bool passDebugInfo; /**< Debug-information */
+#endif /* DEBUG */
+#ifdef FM_CAPWAP_SUPPORT
+ uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size) */
+#endif /* FM_CAPWAP_SUPPORT */
+} t_FmPortBufferPrefixContent;
+
+/**************************************************************************//**
+ @Description struct for defining backup Bm Pools.
+*//***************************************************************************/
+typedef struct t_FmPortBackupBmPools {
+ uint8_t numOfBackupPools; /**< Number of BM backup pools -
+ must be smaller than the total number of
+ pools defined for the specified port.*/
+ uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
+ /**< numOfBackupPools pool id's, specifying which
+ pools should be used only as backup. Pool
+ id's specified here must be a subset of the
+ pools used by the specified port.*/
+} t_FmPortBackupBmPools;
+
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDeqHighPriority
+
+ @Description Calling this routine changes the dequeue priority in the
+ internal driver data base from its default configuration
+ [TRUE]
+
+ May be used for Non-Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDeqType
+
+ @Description Calling this routine changes the dequeue type parameter in the
+ internal driver data base from its default configuration
+ [e_FM_PORT_DEQ_TYPE1].
+
+ May be used for Non-Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] deqType According to QM definition.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
+
+#ifdef FM_QMI_DEQ_OPTIONS_SUPPORT
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDeqPrefetchOption
+
+ @Description Calling this routine changes the dequeue prefetch option parameter in the
+ internal driver data base from its default configuration
+ [e_FM_PORT_DEQ_FULL_PREFETCH]
+ Note: Available for some chips only
+
+ May be used for Non-Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] deqPrefetchOption New option
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
+#endif /* FM_QMI_DEQ_OPTIONS_SUPPORT */
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDeqByteCnt
+
+ @Description Calling this routine changes the dequeue byte count parameter in
+ the internal driver data base from its default configuration [2000].
+
+ May be used for Non-Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] deqByteCnt New byte count
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigTxFifoMinFillLevel
+
+ @Description Calling this routine changes the fifo minimum
+ fill level parameter in the internal driver data base
+ from its default configuration [0]
+
+ May be used for Tx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] minFillLevel New value
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigTxFifoDeqPipelineDepth
+
+ @Description Calling this routine changes the fifo dequeue
+ pipeline depth parameter in the internal driver data base
+
+ from its default configuration: 1G ports: [2],
+ 10G port: [8]
+
+ May be used for Tx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] deqPipelineDepth New value
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigTxFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigTxFifoLowComfLevel
+
+ @Description Calling this routine changes the fifo low comfort level
+ parameter in internal driver data base
+ from its default configuration [5]
+
+ May be used for Tx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] fifoLowComfLevel New value
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigRxFifoThreshold
+
+ @Description Calling this routine changes the threshold of the FIFO
+ fill level parameter in the internal driver data base
+ from its default configuration [BMI_MAX_FIFO_SIZE]
+
+ If the total number of buffers which are
+ currently in use and associated with the
+ specific RX port exceed this threshold, the
+ BMI will signal the MAC to send a pause frame
+ over the link.
+
+ May be used for Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] fifoThreshold New value
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigRxFifoPriElevationLevel
+
+ @Description Calling this routine changes the priority elevation level
+ parameter in the internal driver data base from its default
+ configuration [BMI_MAX_FIFO_SIZE]
+
+ If the total number of buffers which are currently in use and
+ associated with the specific RX port exceed the amount specified
+ in priElevationLevel, BMI will signal the main FM's DMA to
+ elevate the FM priority on the system bus.
+
+ May be used for Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] priElevationLevel New value
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigBufferPrefixContent
+
+ @Description Defines the structure, size and content of the application buffer.
+ The prefix will
+ In Tx ports, if 'passPrsResult', the application
+ should set a value to their offsets in the prefix of
+ the FM will save the first 'privDataSize', than,
+ depending on 'passPrsResult' and 'passTimeStamp', copy parse result
+ and timeStamp, and the packet itself (in this order), to the
+ application buffer, and to offset.
+ Calling this routine changes the buffer margins definitions
+ in the internal driver data base from its default
+ configuration: Data size: [0]
+ Pass Parser result: [FALSE].
+ Pass timestamp: [FALSE].
+
+ May be used for all ports
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in,out] p_FmPortBufferPrefixContent A structure of parameters describing the
+ structure of the buffer.
+ Out parameter: Start margin - offset
+ of data from start of external buffer.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort, t_FmPortBufferPrefixContent *p_FmPortBufferPrefixContent);
+
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigCheksumLastBytesIgnore
+
+ @Description Calling this routine changes the number of checksum bytes to ignore
+ parameter in the internal driver data base from its default configuration
+ [0]
+
+ May be used by Tx & Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] cheksumLastBytesIgnore New value
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigCutBytesFromEnd
+
+ @Description Calling this routine changes the number of bytes to cut from a
+ frame's end parameter in the internal driver data base
+ from its default configuration [4]
+ Note that if the result of (frame length before chop - cutBytesFromEnd) is
+ less than 14 bytes, the chop operation is not executed.
+
+ May be used for Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] cutBytesFromEnd New value
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigPoolDepletion
+
+ @Description Calling this routine enables pause frame generation depending on the
+ depletion status of BM pools. It also defines the conditions to activate
+ this functionality. By default, this functionality is disabled.
+
+ May be used for Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmPortBufPoolDepletion *p_BufPoolDepletion);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigObservedPoolDepletion
+
+ @Description Calling this routine enables a mechanism to stop port enqueue
+ depending on the depletion status of selected BM pools.
+ It also defines the conditions to activate
+ this functionality. By default, this functionality is disabled.
+
+ Note: Available for some chips only
+
+ May be used for Offline Parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
+
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort, t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigExtBufPools
+
+ @Description This routine should be called for offline parsing ports
+ that internally use BM buffer pools. In such cases, e.g. for fragmentation and
+ re-assembly, the FM needs new BM buffers. By calling this routine the user
+ specifies the BM buffer pools that should be used.
+
+ Note: Available for some chips only
+
+ May be used for Offline Parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_FmPortExtPools A structure of parameters for the external pools.
+
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmPortExtPools *p_FmPortExtPools);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigBackupPools
+
+ @Description Calling this routine allows the configuration of some of the BM pools
+ defined for this port as backup pools.
+ A pool configured to be a backup pool will be used only if all other
+ enabled non-backup pools are depleted.
+
+ May be used for Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
+ be defined as backup pools.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmPortBackupBmPools *p_FmPortBackupBmPools);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigFrmDiscardOverride
+
+ @Description Calling this routine changes the error frames destination parameter
+ in the internal driver data base from its default configuration:
+ override = [FALSE]
+
+ May be used for Rx and offline parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] override TRUE to override dicarding of error frames and
+ enqueueing them to error queue.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigErrorsToDiscard
+
+ @Description Calling this routine changes the behaviour on error parameter
+ in the internal driver data base from its default configuration:
+ [FM_PORT_FRM_ERR_CLS_DISCARD].
+ If a requested error was previously defined as "ErrorsToEnqueue" it's
+ definition will change and the frame will be discarded.
+ Errors that were not defined either as "ErrorsToEnqueue" nor as
+ "ErrorsToDiscard", will be forwarded to CPU.
+
+
+ May be used for Rx and offline parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] errs A list of errors to discard
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDmaSwapData
+
+ @Description Calling this routine changes the DMA swap data aparameter
+ in the internal driver data base from its default
+ configuration [e_FM_PORT_DMA_NO_SWP]
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] swapData New selection
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmPortDmaSwap swapData);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDmaIcCacheAttr
+
+ @Description Calling this routine changes the internal context cache
+ attribute parameter in the internal driver data base
+ from its default configuration [e_FM_PORT_DMA_NO_STASH]
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] intContextCacheAttr New selection
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmPortDmaCache intContextCacheAttr);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDmaHdrAttr
+
+ @Description Calling this routine changes the header cache
+ attribute parameter in the internal driver data base
+ from its default configuration [e_FM_PORT_DMA_NO_STASH]
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] headerCacheAttr New selection
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmPortDmaCache headerCacheAttr);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDmaScatterGatherAttr
+
+ @Description Calling this routine changes the scatter gather cache
+ attribute parameter in the internal driver data base
+ from its default configuration [e_FM_PORT_DMA_NO_STASH]
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] scatterGatherCacheAttr New selection
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmPortDmaCache scatterGatherCacheAttr);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDmaWriteOptimize
+
+ @Description Calling this routine changes the write optimization
+ parameter in the internal driver data base
+ from its default configuration: optimize = [TRUE]
+
+ May be used for non-Tx port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDfltColor
+
+ @Description Calling this routine changes the internal default color parameter
+ in the internal driver data base
+ from its default configuration [e_FM_PORT_COLOR_GREEN]
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] color New selection
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigSyncReq
+
+ @Description Calling this routine changes the synchronization attribute parameter
+ in the internal driver data base from its default configuration:
+ syncReq = [TRUE]
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigForwardReuseIntContext
+
+ @Description This routine is relevant for Rx ports that are routed to offline
+ parsing. It changes the internal context reuse option
+ in the internal driver data base from its default configuration:
+ reuse = [FALSE]
+
+ May be used for Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] reuse TRUE to reuse internal context on frames
+ forwarded to offline parsing.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigDontReleaseTxBufToBM
+
+ @Description This routine should be called if no Tx confirmation
+ is done, and yet buffers should not be released to the BM.
+ Normally, buffers are returned using the Tx confirmation
+ process. When Tx confirmation is not used (defFqid=0),
+ buffers are typically released to the BM. This routine
+ may be called to avoid this behavior and not release the
+ buffers.
+
+ May be used for Tx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigIMMaxRxBufLength
+
+ @Description Changes the maximum receive buffer length from its default
+ configuration: Closest rounded down power of 2 value of the
+ data buffer size.
+
+ The maximum receive buffer length directly affects the structure
+ of received frames (single- or multi-buffered) and the performance
+ of both the FM and the driver.
+
+ The selection between single- or multi-buffered frames should be
+ done according to the characteristics of the specific application.
+ The recommended mode is to use a single data buffer per packet,
+ as this mode provides the best performance. However, the user can
+ select to use multiple data buffers per packet.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] newVal Maximum receive buffer length (in bytes).
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+ This routine is to be used only if Independent-Mode is enabled.
+*//***************************************************************************/
+t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigIMRxBdRingLength
+
+ @Description Changes the receive BD ring length from its default
+ configuration:[128]
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] newVal The desired BD ring length.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+ This routine is to be used only if Independent-Mode is enabled.
+*//***************************************************************************/
+t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigIMTxBdRingLength
+
+ @Description Changes the transmit BD ring length from its default
+ configuration:[16]
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] newVal The desired BD ring length.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+ This routine is to be used only if Independent-Mode is enabled.
+*//***************************************************************************/
+t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
+
+ @Description Configures memory partition and attributes for FMan-Controller
+ data structures (e.g. BD rings).
+ Calling this routine changes the internal driver data base
+ from its default configuration
+ [0 , MEMORY_ATTR_CACHEABLE].
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] memId Memory partition ID.
+ @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
+ uint8_t memId,
+ uint32_t memAttributes);
+
+/**************************************************************************//**
+ @Function FM_PORT_ConfigIMPolling
+
+ @Description Changes the Rx flow from interrupt driven (default) to polling.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+ This routine is to be used only if Independent-Mode is enabled.
+*//***************************************************************************/
+t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
+
+/** @} */ /* end of FM_PORT_advanced_init_grp group */
+/** @} */ /* end of FM_PORT_init_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
+
+ @Description FM Port Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for defining FM Port counters
+*//***************************************************************************/
+typedef enum e_FmPortCounters {
+ e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
+ e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
+ e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
+ e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
+ e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
+ e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
+ e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
+ e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
+ e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
+ e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
+ e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
+ e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx only statistics counter */
+ e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
+ e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
+ e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
+ e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
+ e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
+ e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI counter */
+ e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI counter */
+ e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
+ e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
+} e_FmPortCounters;
+
+/**************************************************************************//**
+ @Description Structure for Port id parameters.
+ Fields commented 'IN' are passed by the port module to be used
+ by the FM module.
+ Fields commented 'OUT' will be filled by FM before returning to port.
+*//***************************************************************************/
+typedef struct t_FmPortCongestionGrps {
+ uint16_t numOfCongestionGrpsToConsider; /**< The number of required congestion groups
+ to define the size of the following array */
+ uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
+ /**< An array of 'numOfCongestionGrpsToConsider'
+ describing the groups */
+} t_FmPortCongestionGrps;
+
+
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function FM_PORT_DumpRegs
+
+ @Description Dump all regs.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+/**************************************************************************//**
+ @Function FM_PORT_GetBufferDataOffset
+
+ @Description Relevant for Rx ports.
+ Returns the data offset from the beginning of the data buffer
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+
+ @Return data offset.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_GetBufferICInfo
+
+ @Description Returns the Internal Context offset from the beginning of the data buffer
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+ @Param[in] p_Data - A pointer to the data buffer.
+
+ @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
+ configured for this port.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
+
+#ifdef DEBUG
+/**************************************************************************//**
+ @Function FM_PORT_GetBufferDebugInfo
+
+ @Description Returns the debug info offset from the beginning of the data buffer
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+ @Param[in] p_Data - A pointer to the data buffer.
+
+ @Return Debug info pointer on success, NULL if 'passDebugInfo' was not
+ configured for this port.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+uint8_t * FM_PORT_GetBufferDebugInfo(t_Handle h_FmPort, char *p_Data);
+#endif /* DEBUG */
+
+/**************************************************************************//**
+ @Function FM_PORT_GetBufferPrsResult
+
+ @Description Returns the pointer to the parse result in the data buffer.
+ In Rx ports this is relevant after reception, if parse
+ result is configured to be part of the data passed to the
+ application. For non Rx ports it may be used to get the pointer
+ of the area in the buffer where parse result should be
+ initialized - if so configured.
+ See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
+ configuration.
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+ @Param[in] p_Data - A pointer to the data buffer.
+
+ @Return Parse result pointer on success, NULL if parse result was not
+ configured for this port.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
+
+/**************************************************************************//**
+ @Function FM_PORT_GetBufferTimeStamp
+
+ @Description Returns the time stamp in the data buffer.
+ Relevant for Rx ports for getting the buffer time stamp.
+ See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
+ configuration.
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+ @Param[in] p_Data - A pointer to the data buffer.
+
+ @Return A pointer to the hash result on success, NULL otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
+
+/**************************************************************************//**
+ @Function FM_PORT_GetBufferHashResult
+
+ @Description Given a data buffer, on the condition that hash result was defined
+ as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
+ this routine will return the pointer to the hash result location in the
+ buffer prefix.
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+ @Param[in] p_Data - A pointer to the data buffer.
+
+ @Return A pointer to the hash result on success, NULL otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
+
+/**************************************************************************//**
+ @Function FM_PORT_Disable
+
+ @Description Gracefully disable an FM port. The port will not start new tasks after all
+ tasks associated with the port are terminated.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+ This is a blocking routine, it returns after port is
+ gracefully stopped, i.e. the port will not except new frames,
+ but it will finish all frames or tasks which were already began
+*//***************************************************************************/
+t_Error FM_PORT_Disable(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_Enable
+
+ @Description A runtime routine provided to allow disable/enable of port.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_Enable(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetRateLimit
+
+ @Description Calling this routine enables rate limit algorithm.
+ By default, this functionality is disabled.
+ Note that rate-limit mechanism uses the FM time stamp.
+ The selected rate limit specified here would be
+ rounded DOWN to the nearest 16M.
+
+ May be used for Tx and offline parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_RateLimit A structure of rate limit parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
+
+/**************************************************************************//**
+ @Function FM_PORT_DeleteRateLimit
+
+ @Description Calling this routine disables and clears rate limit
+ initialization.
+
+ May be used for Tx and offline parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetStatisticsCounters
+
+ @Description Calling this routine enables/disables port's statistics counters.
+ By default, counters are enabled.
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] enable TRUE to enable, FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetFrameQueueCounters
+
+ @Description Calling this routine enables/disables port's enqueue/dequeue counters.
+ By default, counters are enabled.
+
+ May be used for all ports
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] enable TRUE to enable, FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetPerformanceCounters
+
+ @Description Calling this routine enables/disables port's performance counters.
+ By default, counters are enabled.
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] enable TRUE to enable, FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetPerformanceCounters
+
+ @Description Calling this routine defines port's performance
+ counters parameters.
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
+ counters parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
+
+/**************************************************************************//**
+ @Function FM_PORT_AnalyzePerformanceParams
+
+ @Description User may call this routine to so the driver will analyze if the
+ basic performance parameters are correct and also the driver may
+ suggest of improvments; The basic parameters are FIFO sizes, number
+ of DMAs and number of TNUMs for the port.
+
+ May be used for all port types
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetNumOfOpenDmas
+
+ @Description Calling this routine updates the number of open DMA requested for
+ this port.
+
+
+ May be used for all port types.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_NumOfOpenDmas A structure of resource requested parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetNumOfTasks
+
+ @Description Calling this routine updates the number of tasks requested for
+ this port.
+
+ May be used for all port types.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_NumOfTasks A structure of resource requested parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetSizeOfFifo
+
+ @Description Calling this routine updates the Fifo size resource requested for
+ this port.
+
+ May be used for all port types - note that only Rx has 'extra'
+ fifo size. For other ports 'extra' field must be disabled.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_SizeOfFifo A structure of resource requested parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetAllocBufCounter
+
+ @Description Calling this routine enables/disables BM pool allocate
+ buffer counters.
+ By default, counters are enabled.
+
+ May be used for Rx ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] poolId BM pool id.
+ @Param[in] enable TRUE to enable, FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
+
+/**************************************************************************//**
+ @Function FM_PORT_GetCounter
+
+ @Description Reads one of the FM PORT counters.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] fmPortCounter The requested counter.
+
+ @Return Counter's current value.
+
+ @Cautions Allowed only following FM_PORT_Init().
+ Note that it is user's responsibility to call this routine only
+ for enabled counters, and there will be no indication if a
+ disabled counter is accessed.
+*//***************************************************************************/
+uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
+
+/**************************************************************************//**
+ @Function FM_PORT_ModifyCounter
+
+ @Description Sets a value to an enabled counter. Use "0" to reset the counter.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] fmPortCounter The requested counter.
+ @Param[in] value The requested value to be written into the counter.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
+
+/**************************************************************************//**
+ @Function FM_PORT_GetAllocBufCounter
+
+ @Description Reads one of the FM PORT buffer counters.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] poolId The requested pool.
+
+ @Return Counter's current value.
+
+ @Cautions Allowed only following FM_PORT_Init().
+ Note that it is user's responsibility to call this routine only
+ for enabled counters, and there will be no indication if a
+ disabled counter is accessed.
+*//***************************************************************************/
+uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
+
+/**************************************************************************//**
+ @Function FM_PORT_ModifyAllocBufCounter
+
+ @Description Sets a value to an enabled counter. Use "0" to reset the counter.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] poolId The requested pool.
+ @Param[in] value The requested value to be written into the counter.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
+
+/**************************************************************************//**
+ @Function FM_PORT_AddCongestionGrps
+
+ @Description This routine effects the corresponding Tx port.
+ It should be called in order to enable pause
+ frame transmission in case of congestion in one or more
+ of the congestion groups relevant to this port.
+ Each call to this routine may add one or more congestion
+ groups to be considered relevant to this port.
+
+ May be used for Rx, or RX+OP ports only (depending on chip)
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_CongestionGrps A pointer to an array of congestion groups
+ id's to consider.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
+
+/**************************************************************************//**
+ @Function FM_PORT_RemoveCongestionGrps
+
+ @Description This routine effects the corresponding Tx port. It should be
+ called when congestion groups were
+ defined for this port and are no longer relevant, or pause
+ frames transmitting is not required on their behalf.
+ Each call to this routine may remove one or more congestion
+ groups to be considered relevant to this port.
+
+ May be used for Rx, or RX+OP ports only (depending on chip)
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_CongestionGrps A pointer to an array of congestion groups
+ id's to consider.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
+
+/**************************************************************************//**
+ @Function FM_PORT_IsStalled
+
+ @Description A routine for checking whether the specified port is stalled.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return TRUE if port is stalled, FALSE otherwize
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+bool FM_PORT_IsStalled(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_ReleaseStalled
+
+ @Description This routine may be called in case the port was stalled and may
+ now be released.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetRxL4ChecksumVerify
+
+ @Description This routine is relevant for Rx ports (1G and 10G). The routine
+ set/clear the L3/L4 checksum verification (on RX side).
+ Note that this takes affect only if hw-parser is enabled!
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
+ on frames or not.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetErrorsRoute
+
+ @Description Errors selected for this routine will cause a frame with that error
+ to be enqueued to error queue.
+ Errors not selected for this routine will cause a frame with that error
+ to be enqueued to the one of the other port queues.
+ By default all errors are defined to be enqueued to error queue.
+ Errors that were configured to be discarded (at initialization)
+ may not be selected here.
+
+ May be used for Rx and offline parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] errs A list of errors to enqueue to error queue
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
+
+/**************************************************************************//**
+ @Function FM_PORT_SetIMExceptions
+
+ @Description Calling this routine enables/disables FM PORT interrupts.
+ Note: Not available for guest partition.
+
+ @Param[in] h_FmPort FM PORT module descriptor.
+ @Param[in] exception The exception to be selected.
+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
+
+
+
+/**************************************************************************//**
+ @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
+
+ @Description FM Port PCD Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description A structure defining the KG scheme after the parser.
+ This is relevant only to change scheme selection mode - from
+ direct to indirect and vice versa, or when the scheme is selected directly,
+ to select the scheme id.
+
+*//***************************************************************************/
+typedef struct t_FmPcdKgSchemeSelect {
+ bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV.*/
+ t_Handle h_DirectScheme; /**< Relevant for 'direct'=TRUE only.
+ 'h_DirectScheme' selects the scheme after parser. */
+} t_FmPcdKgSchemeSelect;
+
+/**************************************************************************//**
+ @Description A structure of scheme parameters
+*//***************************************************************************/
+typedef struct t_FmPcdPortSchemesParams {
+ uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
+ t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
+ port to be bound to */
+} t_FmPcdPortSchemesParams;
+
+/**************************************************************************//**
+ @Description Union for defining port protocol parameters for parser
+*//***************************************************************************/
+typedef union u_FmPcdHdrPrsOpts {
+ /* MPLS */
+ struct {
+ bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
+ interpreted as described in HW spec table. When the bit
+ is cleared, the parser will advance to MPLS next parse */
+ e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
+ } mplsPrsOptions;
+ /* VLAN */
+ struct {
+ uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
+ on VLAN TAG on top of 0x8100 and 0x88A8 */
+ uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
+ on VLAN TAG on top of 0x8100 and 0x88A8 */
+ } vlanPrsOptions;
+ /* PPP */
+ struct{
+ bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
+ } pppoePrsOptions;
+
+ /* IPV6 */
+ struct{
+ bool routingHdrDisable; /**< Disable routing header */
+ } ipv6PrsOptions;
+
+ /* UDP */
+ struct{
+ bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
+ } udpPrsOptions;
+
+ /* TCP */
+ struct {
+ bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
+ } tcpPrsOptions;
+} u_FmPcdHdrPrsOpts;
+
+/**************************************************************************//**
+ @Description A structure for defining each header for the parser
+*//***************************************************************************/
+typedef struct t_FmPcdPrsAdditionalHdrParams {
+ e_NetHeaderType hdr; /**< Selected header */
+ bool errDisable; /**< TRUE to disable error indication */
+ bool swPrsEnable; /**< Enable jump to SW parser when this
+ header is recognized by the HW parser. */
+ uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
+ attachments exists for the same header,
+ (in the main sw parser code) use this
+ index to distinguish between them. */
+ bool usePrsOpts; /**< TRUE to use parser options. */
+ u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
+ defining the parser options selected.*/
+} t_FmPcdPrsAdditionalHdrParams;
+
+/**************************************************************************//**
+ @Description struct for defining port PCD parameters
+*//***************************************************************************/
+typedef struct t_FmPortPcdPrsParams {
+ uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
+ port information into the parser result. This information
+ may be extracted by Keygen and be used for frames
+ distribution when a per-port distinction is required,
+ it may also be used as a port logical id for analyzing
+ incoming frames. */
+ uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
+ e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
+ bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
+ NOTE: this field is not valid when the FN is in "guest" mode. */
+ uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
+ special parameters */
+ t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
+ /**< 'numOfHdrsWithAdditionalParams' structures
+ of additional parameters
+ for each header that requires them */
+ bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
+ indicate a VLAN tag (in addition to the TPID values
+ 0x8100 and 0x88A8). */
+ uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
+ bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
+ indicate a VLAN tag (in addition to the TPID values
+ 0x8100 and 0x88A8). */
+ uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
+} t_FmPortPcdPrsParams;
+
+/**************************************************************************//**
+ @Description struct for defining coarse alassification parameters
+*//***************************************************************************/
+typedef struct t_FmPortPcdCcParams {
+ t_Handle h_CcTree; /**< A handle to a CC tree */
+} t_FmPortPcdCcParams;
+
+/**************************************************************************//**
+ @Description struct for defining keygen parameters
+*//***************************************************************************/
+typedef struct t_FmPortPcdKgParams {
+ uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
+ t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
+ /**< Array of 'numOfSchemes' schemes handles for the
+ port to be bound to */
+ bool directScheme; /**< TRUE for going from parser to a specific scheme,
+ regardless of parser result */
+ t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
+ as returned by FM_PCD_KgSetScheme */
+} t_FmPortPcdKgParams;
+
+/**************************************************************************//**
+ @Description struct for defining policer parameters
+*//***************************************************************************/
+typedef struct t_FmPortPcdPlcrParams {
+ t_Handle h_Profile; /**< Selected profile handle; Relevant for one of
+ following cases:
+ e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
+ e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
+ or if any flow uses a KG scheme were policer
+ profile is not generated
+ (bypassPlcrProfileGeneration selected) */
+} t_FmPortPcdPlcrParams;
+
+/**************************************************************************//**
+ @Description struct for defining port PCD parameters
+*//***************************************************************************/
+typedef struct t_FmPortPcdParams {
+ e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
+ Describes the active PCD engines for this port. */
+ t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
+ t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
+ t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
+ t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
+ t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port */
+} t_FmPortPcdParams;
+
+/**************************************************************************//**
+ @Description A structure for defining the Parser starting point
+*//***************************************************************************/
+typedef struct t_FmPcdPrsStart {
+ uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
+ start parsing */
+ e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
+ 'parsingOffset' */
+} t_FmPcdPrsStart;
+
+
+/**************************************************************************//**
+ @Function FM_PORT_SetPCD
+
+ @Description Calling this routine defines the port's PCD configuration.
+ It changes it from its default configuration which is PCD
+ disabled (BMI to BMI) and configures it according to the passed
+ parameters.
+
+ May be used for Rx and offline parsing ports only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
+ configuration.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
+
+/**************************************************************************//**
+ @Function FM_PORT_DeletePCD
+
+ @Description Calling this routine releases the port's PCD configuration.
+ The port returns to its default configuration which is PCD
+ disabled (BMI to BMI) and all PCD configuration is removed.
+
+ May be used for Rx and offline parsing ports which are
+ in PCD mode only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_AttachPCD
+
+ @Description This routine may be called after FM_PORT_DetachPCD was called,
+ to return to the originally configured PCD support flow.
+ The couple of routines are used to allow PCD configuration changes
+ that demand that PCD will not be used while changes take place.
+
+ May be used for Rx and offline parsing ports which are
+ in PCD mode only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_DetachPCD
+
+ @Description Calling this routine detaches the port from its PCD functionality.
+ The port returns to its default flow which is BMI to BMI.
+
+ May be used for Rx and offline parsing ports which are
+ in PCD mode only
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_AttachPCD().
+*//***************************************************************************/
+t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdPlcrAllocProfiles
+
+ @Description This routine may be called only for ports that use the Policer in
+ order to allocate private policer profiles.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] numOfProfiles The number of required policer profiles
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), and before FM_PORT_SetPCD().
+*//***************************************************************************/
+t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdPlcrFreeProfiles
+
+ @Description This routine should be called for freeing private policer profiles.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), and before FM_PORT_SetPCD().
+*//***************************************************************************/
+t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdKgModifyInitialScheme
+
+ @Description This routine may be called only for ports that use the keygen in
+ order to change the initial scheme frame should be routed to.
+ The change may be of a scheme id (in case of direct mode),
+ from direct to indirect, or from indirect to direct - specifying the scheme id.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
+ a scheme is direct/indirect, and if direct - scheme id.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
+*//***************************************************************************/
+t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdPlcrModifyInitialProfile
+
+ @Description This routine may be called for ports with flows
+ e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
+ only, to change the initial Policer profile frame should be
+ routed to. The change may be of a profile and/or absolute/direct
+ mode selection.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] h_Profile Policer profile handle
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
+*//***************************************************************************/
+t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdCcModifyTree
+
+ @Description This routine may be called for ports that use coarse classification tree
+ if the user wishes to replace the tree. The routine may not be called while port
+ receives packets using the PCD functionalities, therefor port must be first detached
+ from the PCD, only than the routine may be called, and than port be attached to PCD again.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
+ the BuildTree routine.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
+*//***************************************************************************/
+t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdKgBindSchemes
+
+ @Description These routines may be called for adding more schemes for the
+ port to be bound to. The selected schemes are not added,
+ just this specific port starts using them.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_PortScheme A structure defining the list of schemes to be added.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
+*//***************************************************************************/
+t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdKgUnbindSchemes
+
+ @Description These routines may be called for adding more schemes for the
+ port to be bound to. The selected schemes are not removed or invalidated,
+ just this specific port stops using them.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_PortScheme A structure defining the list of schemes to be added.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
+*//***************************************************************************/
+t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
+
+/**************************************************************************//**
+ @Function FM_PORT_PcdPrsModifyStartOffset
+
+ @Description Runtime change of the parser start offset within the header.
+ The routine may not be called while port
+ receives packets using the PCD functionalities, therefore port must be first detached
+ from the PCD, only than the routine may be called, and than port be attached to PCD again.
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_FmPcdPrsStart A structure of parameters for defining the
+ start point for the parser.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetatchPCD().
+*//***************************************************************************/
+t_Error FM_PORT_PcdPrsModifyStartOffset (t_Handle h_FmPort, t_FmPcdPrsStart *p_FmPcdPrsStart);
+
+/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
+/** @} */ /* end of FM_PORT_runtime_control_grp group */
+
+
+/**************************************************************************//**
+ @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
+
+ @Description FM Port Runtime data unit API functions, definitions and enums.
+ This API is valid only if working in Independent-Mode.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_PORT_ImTx
+
+ @Description Tx function, called to transmit a data buffer on the port.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] p_Data A pointer to an LCP data buffer.
+ @Param[in] length Size of data for transmission.
+ @Param[in] lastBuffer Buffer position - TRUE for the last buffer
+ of a frame, including a single buffer frame
+ @Param[in] h_BufContext A handle of the user acossiated with this buffer
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+ NOTE - This routine can be used only when working in
+ Independent-Mode mode.
+*//***************************************************************************/
+t_Error FM_PORT_ImTx( t_Handle h_FmPort,
+ uint8_t *p_Data,
+ uint16_t length,
+ bool lastBuffer,
+ t_Handle h_BufContext);
+
+/**************************************************************************//**
+ @Function FM_PORT_ImTxConf
+
+ @Description Tx port confirmation routine, optional, may be called to verify
+ transmission of all frames. The procedure performed by this
+ routine will be performed automatically on next buffer transmission,
+ but if desired, calling this routine will invoke this action on
+ demand.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Cautions Allowed only following FM_PORT_Init().
+ NOTE - This routine can be used only when working in
+ Independent-Mode mode.
+*//***************************************************************************/
+void FM_PORT_ImTxConf(t_Handle h_FmPort);
+
+/**************************************************************************//**
+ @Function FM_PORT_ImRx
+
+ @Description Rx function, may be called to poll for received buffers.
+ Normally, Rx process is invoked by the driver on Rx interrupt.
+ Alternatively, this routine may be called on demand.
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+ NOTE - This routine can be used only when working in
+ Independent-Mode mode.
+*//***************************************************************************/
+t_Error FM_PORT_ImRx(t_Handle h_FmPort);
+
+/** @} */ /* end of FM_PORT_runtime_data_grp group */
+/** @} */ /* end of FM_PORT_grp group */
+/** @} */ /* end of FM_grp group */
+
+
+
+
+#endif /* __FM_PORT_EXT */
diff --git a/sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h b/sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h
new file mode 100644
index 0000000..8827d2a
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/fm_rtc_ext.h
@@ -0,0 +1,592 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_rtc_ext.h
+
+ @Description External definitions and API for FM RTC IEEE1588 Timer Module.
+
+ @Cautions None.
+*//***************************************************************************/
+
+#ifndef __FM_RTC_EXT_H__
+#define __FM_RTC_EXT_H__
+
+
+#include "error_ext.h"
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+
+ @Group FM_grp Frame Manager API
+
+ @Description FM API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group fm_rtc_grp FM RTC
+
+ @Description FM RTC functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group fm_rtc_init_grp FM RTC Initialization Unit
+
+ @Description FM RTC initialization API.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description FM RTC Alarm Polarity Options.
+*//***************************************************************************/
+typedef enum e_FmRtcAlarmPolarity
+{
+ e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
+ e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
+} e_FmRtcAlarmPolarity;
+
+/**************************************************************************//**
+ @Description FM RTC Trigger Polarity Options.
+*//***************************************************************************/
+typedef enum e_FmRtcTriggerPolarity
+{
+ e_FM_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
+ e_FM_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
+} e_FmRtcTriggerPolarity;
+
+/**************************************************************************//**
+ @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
+*//***************************************************************************/
+typedef enum e_FmSrcClock
+{
+ e_FM_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
+ e_FM_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
+ e_FM_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
+}e_FmSrcClk;
+
+/**************************************************************************//**
+ @Description FM RTC configuration parameters structure.
+
+ This structure should be passed to FM_RTC_Config().
+*//***************************************************************************/
+typedef struct t_FmRtcParams
+{
+ t_Handle h_Fm; /**< FM Handle*/
+ uintptr_t baseAddress; /**< Base address of FM RTC registers */
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+} t_FmRtcParams;
+
+
+/**************************************************************************//**
+ @Function FM_RTC_Config
+
+ @Description Configures the FM RTC module according to user's parameters.
+
+ The driver assigns default values to some FM RTC parameters.
+ These parameters can be overwritten using the advanced
+ configuration routines.
+
+ @Param[in] p_FmRtcParam - FM RTC configuration parameters.
+
+ @Return Handle to the new FM RTC object; NULL pointer on failure.
+
+ @Cautions None
+*//***************************************************************************/
+t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
+
+/**************************************************************************//**
+ @Function FM_RTC_Init
+
+ @Description Initializes the FM RTC driver and hardware.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_Init(t_Handle h_FmRtc);
+
+/**************************************************************************//**
+ @Function FM_RTC_Free
+
+ @Description Frees the FM RTC object and all allocated resources.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_Free(t_Handle h_FmRtc);
+
+
+/**************************************************************************//**
+ @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
+
+ @Description FM RTC advanced configuration functions.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigPeriod
+
+ @Description Configures the period of the timestamp if different than
+ default [1000].
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] period - Period in nano-seconds.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigSourceClock
+
+ @Description Configures the source clock of the RTC.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] srcClk - Source clock selection.
+ @Param[in] freqInMhz - the source-clock frequency (in MHz).
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
+ e_FmSrcClk srcClk,
+ uint32_t freqInMhz);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigPulseRealignment
+
+ @Description Configures the RTC to automatic FIPER pulse realignment in
+ response to timer adjustments [FALSE]
+
+ In this mode, the RTC clock is identical to the source clock.
+ This feature can be useful when the system contains an external
+ RTC with inherent frequency compensation.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] enable - TRUE to enable automatic realignment.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigFrequencyBypass
+
+ @Description Configures the RTC to bypass the frequency compensation
+ mechanism. [FALSE]
+
+ In this mode, the RTC clock is identical to the source clock.
+ This feature can be useful when the system contains an external
+ RTC with inherent frequency compensation.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] enabled - TRUE to bypass frequency compensation;
+ FALSE otherwise.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigInvertedInputClockPhase
+
+ @Description Configures the RTC to invert the source clock phase on input.
+ [FALSE]
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] inverted - TRUE to invert the source clock phase on input.
+ FALSE otherwise.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigInvertedOutputClockPhase
+
+ @Description Configures the RTC to invert the output clock phase.
+ [FALSE]
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] inverted - TRUE to invert the output clock phase.
+ FALSE otherwise.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigOutputClockDivisor
+
+ @Description Configures the divisor for generating the output clock from
+ the RTC clock. [0x00000002]
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] divisor - Divisor for generation of the output clock.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigAlarmPolarity
+
+ @Description Configures the polarity (active-high/active-low) of a specific
+ alarm signal. [e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH]
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] alarmId - Alarm ID.
+ @Param[in] alarmPolarity - Alarm polarity.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
+ uint8_t alarmId,
+ e_FmRtcAlarmPolarity alarmPolarity);
+
+/**************************************************************************//**
+ @Function FM_RTC_ConfigExternalTriggerPolarity
+
+ @Description Configures the polarity (rising/falling edge) of a specific
+ external trigger signal. [e_FM_RTC_TRIGGER_ON_FALLING_EDGE]
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] triggerId - Trigger ID.
+ @Param[in] triggerPolarity - Trigger polarity.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
+*//***************************************************************************/
+t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
+ uint8_t triggerId,
+ e_FmRtcTriggerPolarity triggerPolarity);
+
+/** @} */ /* end of fm_rtc_adv_config_grp */
+/** @} */ /* end of fm_rtc_init_grp */
+
+
+/**************************************************************************//**
+ @Group fm_rtc_control_grp FM RTC Control Unit
+
+ @Description FM RTC runtime control API.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function t_FmRtcExceptionsCallback
+
+ @Description Exceptions user callback routine, used for RTC different mechanisms.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] id - source id.
+*//***************************************************************************/
+typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
+
+/**************************************************************************//**
+ @Description FM RTC alarm parameters.
+*//***************************************************************************/
+typedef struct t_FmRtcAlarmParams {
+ uint8_t alarmId; /**< 0 or 1 */
+ uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
+ should go off - must be a multiple of
+ the RTC period */
+ t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
+ reaches alarmTime */
+ bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
+} t_FmRtcAlarmParams;
+
+/**************************************************************************//**
+ @Description FM RTC Periodic Pulse parameters.
+*//***************************************************************************/
+typedef struct t_FmRtcPeriodicPulseParams {
+ uint8_t periodicPulseId; /**< 0 or 1 */
+ uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
+ a multiple of the RTC period */
+ t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
+ periodicPulsePeriod. */
+} t_FmRtcPeriodicPulseParams;
+
+/**************************************************************************//**
+ @Description FM RTC Periodic Pulse parameters.
+*//***************************************************************************/
+typedef struct t_FmRtcExternalTriggerParams {
+ uint8_t externalTriggerId; /**< 0 or 1 */
+ bool usePulseAsInput; /**< Use the pulse interrupt instead of
+ an external signal */
+ t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
+ periodicPulsePeriod. */
+} t_FmRtcExternalTriggerParams;
+
+
+/**************************************************************************//**
+ @Function FM_RTC_Enable
+
+ @Description Enable the RTC (time count is started).
+
+ The user can select to resume the time count from previous
+ point, or to restart the time count.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] resetClock - Restart the time count from zero.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
+
+/**************************************************************************//**
+ @Function FM_RTC_Disable
+
+ @Description Disables the RTC (time count is stopped).
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_Disable(t_Handle h_FmRtc);
+
+/**************************************************************************//**
+ @Function FM_RTC_SetClockOffset
+
+ @Description Sets the clock offset (usually relative to another clock).
+
+ The user can pass a negative offset value.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] offset - New clock offset (in nanoseconds).
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
+
+/**************************************************************************//**
+ @Function FM_RTC_SetAlarm
+
+ @Description Schedules an alarm event to a given RTC time.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] p_FmRtcAlarmParams - Alarm parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+ Must be called only prior to FM_RTC_Enable().
+*//***************************************************************************/
+t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
+
+/**************************************************************************//**
+ @Function FM_RTC_SetPeriodicPulse
+
+ @Description Sets a periodic pulse.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+ Must be called only prior to FM_RTC_Enable().
+*//***************************************************************************/
+t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
+
+/**************************************************************************//**
+ @Function FM_RTC_ClearPeriodicPulse
+
+ @Description Clears a periodic pulse.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] periodicPulseId - Periodic pulse id.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
+
+/**************************************************************************//**
+ @Function FM_RTC_SetExternalTrigger
+
+ @Description Sets an external trigger indication and define a callback
+ routine to be called on such event.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
+
+/**************************************************************************//**
+ @Function FM_RTC_ClearExternalTrigger
+
+ @Description Clears external trigger indication.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] id - External Trigger id.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
+
+/**************************************************************************//**
+ @Function FM_RTC_GetExternalTriggerTimeStamp
+
+ @Description Reads the External Trigger TimeStamp.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] triggerId - External Trigger id.
+ @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
+ uint8_t triggerId,
+ uint64_t *p_TimeStamp);
+
+/**************************************************************************//**
+ @Function FM_RTC_GetCurrentTime
+
+ @Description Returns the current RTC time.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[out] p_Ts - returned time stamp (in nanoseconds).
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
+
+/**************************************************************************//**
+ @Function FM_RTC_SetCurrentTime
+
+ @Description Sets the current RTC time.
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] ts - The new time stamp (in nanoseconds).
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
+
+/**************************************************************************//**
+ @Function FM_RTC_GetFreqCompensation
+
+ @Description TODO
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[out] p_Compensation - A pointer to the returned value of compensation.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
+
+/**************************************************************************//**
+ @Function FM_RTC_SetFreqCompensation
+
+ @Description TODO
+
+ @Param[in] h_FmRtc - Handle to FM RTC object.
+ @Param[in] freqCompensation - the new desired compensation value to be set.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
+*//***************************************************************************/
+t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function FM_RTC_DumpRegs
+
+ @Description Dumps all FM registers
+
+ @Param[in] h_FmRtc A handle to an FM RTC Module.
+
+ @Return E_OK on success;
+
+ @Cautions Allowed only FM_Init().
+*//***************************************************************************/
+t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+/** @} */ /* end of fm_rtc_control_grp */
+/** @} */ /* end of fm_rtc_grp */
+/** @} */ /* end of FM_grp group */
+
+
+#endif /* __FM_RTC_EXT_H__ */
diff --git a/sys/contrib/ncsw/inc/Peripherals/qm_ext.h b/sys/contrib/ncsw/inc/Peripherals/qm_ext.h
new file mode 100644
index 0000000..e5674f4
--- /dev/null
+++ b/sys/contrib/ncsw/inc/Peripherals/qm_ext.h
@@ -0,0 +1,1270 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File qm_ext.h
+
+ @Description QM & Portal API
+*//***************************************************************************/
+#ifndef __QM_EXT_H
+#define __QM_EXT_H
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "dpaa_ext.h"
+#include "part_ext.h"
+
+
+/**************************************************************************//**
+ @Group QM_grp Queue Manager API
+
+ @Description QM API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description This callback type is used when receiving frame.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App A user argument to the callback
+ @Param[in] h_QmFqr A handle to an QM-FQR Module.
+ @Param[in] fqidOffset fqid offset from the FQR's fqid base.
+ @Param[in] p_Frame The Received Frame
+
+ @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
+ operation for all ready data.
+ @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
+
+ @Cautions p_Frame is local parameter; i.e. users must NOT access or use
+ this parameter in any means outside this callback context.
+*//***************************************************************************/
+typedef e_RxStoreResponse (t_QmReceivedFrameCallback)(t_Handle h_App,
+ t_Handle h_QmFqr,
+ t_Handle h_QmPortal,
+ uint32_t fqidOffset,
+ t_DpaaFD *p_Frame);
+
+/**************************************************************************//**
+ @Description This callback type is used when the FQR is completely was drained.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App A user argument to the callback
+ @Param[in] h_QmFqr A handle to an QM-FQR Module.
+
+ @Retval E_OK on success; Error code otherwise.
+*//***************************************************************************/
+typedef t_Error (t_QmFqrDrainedCompletionCB)(t_Handle h_App,
+ t_Handle h_QmFqr);
+
+/**************************************************************************//**
+ @Description QM Rejection code enum
+*//***************************************************************************/
+typedef enum e_QmRejectionCode
+{
+ e_QM_RC_NONE,
+
+ e_QM_RC_CG_TAILDROP, /**< This frames was rejected due to congestion
+ group taildrop situation */
+ e_QM_RC_CG_WRED, /**< This frames was rejected due to congestion
+ group WRED situation */
+ e_QM_RC_FQ_TAILDROP /**< This frames was rejected due to FQID TD
+ situation */
+/* e_QM_RC_ERROR
+ e_QM_RC_ORPWINDOW_EARLY
+ e_QM_RC_ORPWINDOW_LATE
+ e_QM_RC_ORPWINDOW_RETIRED */
+} e_QmRejectionCode;
+
+/**************************************************************************//**
+ @Description QM Rejected frame information
+*//***************************************************************************/
+typedef struct t_QmRejectedFrameInfo
+{
+ e_QmRejectionCode rejectionCode; /**< Rejection code */
+ union
+ {
+ struct
+ {
+ uint8_t cgId; /**< congestion group id*/
+ } cg; /**< rejection parameters when rejectionCode =
+ e_QM_RC_CG_TAILDROP or e_QM_RC_CG_WRED. */
+ };
+} t_QmRejectedFrameInfo;
+
+/**************************************************************************//**
+ @Description This callback type is used when receiving rejected frames.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App A user argument to the callback
+ @Param[in] h_QmFqr A handle to an QM-FQR Module.
+ @Param[in] fqidOffset fqid offset from the FQR's fqid base.
+ @Param[in] p_Frame The Rejected Frame
+ @Param[in] p_QmRejectedFrameInfo Rejected Frame information
+
+ @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
+ operation for all ready data.
+ @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
+
+ @Cautions p_Frame is local parameter; i.e. users must NOT access or use
+ this parameter in any means outside this callback context.
+*//***************************************************************************/
+typedef e_RxStoreResponse (t_QmRejectedFrameCallback)(t_Handle h_App,
+ t_Handle h_QmFqr,
+ t_Handle h_QmPortal,
+ uint32_t fqidOffset,
+ t_DpaaFD *p_Frame,
+ t_QmRejectedFrameInfo *p_QmRejectedFrameInfo);
+
+
+
+/**************************************************************************//**
+ @Group QM_lib_grp QM common API
+
+ @Description QM common API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description QM Exceptions
+*//***************************************************************************/
+typedef enum e_QmExceptions {
+ e_QM_EX_CORENET_INITIATOR_DATA = 0, /**< Initiator Data Error */
+ e_QM_EX_CORENET_TARGET_DATA, /**< CoreNet Target Data Error */
+ e_QM_EX_CORENET_INVALID_TARGET_TRANSACTION, /**< Invalid Target Transaction */
+ e_QM_EX_PFDR_THRESHOLD, /**< PFDR Low Watermark Interrupt */
+ e_QM_EX_PFDR_ENQUEUE_BLOCKED, /**< PFDR Enqueues Blocked Interrupt */
+ e_QM_EX_SINGLE_ECC, /**< Single Bit ECC Error Interrupt */
+ e_QM_EX_MULTI_ECC, /**< Multi Bit ECC Error Interrupt */
+ e_QM_EX_INVALID_COMMAND, /**< Invalid Command Verb Interrupt */
+ e_QM_EX_DEQUEUE_DCP, /**< Invalid Dequeue Direct Connect Portal Interrupt */
+ e_QM_EX_DEQUEUE_FQ, /**< Invalid Dequeue FQ Interrupt */
+ e_QM_EX_DEQUEUE_SOURCE, /**< Invalid Dequeue Source Interrupt */
+ e_QM_EX_DEQUEUE_QUEUE, /**< Invalid Dequeue Queue Interrupt */
+ e_QM_EX_ENQUEUE_OVERFLOW, /**< Invalid Enqueue Overflow Interrupt */
+ e_QM_EX_ENQUEUE_STATE, /**< Invalid Enqueue State Interrupt */
+ e_QM_EX_ENQUEUE_CHANNEL, /**< Invalid Enqueue Channel Interrupt */
+ e_QM_EX_ENQUEUE_QUEUE, /**< Invalid Enqueue Queue Interrupt */
+ e_QM_EX_CG_STATE_CHANGE /**< CG change state notification */
+} e_QmExceptions;
+
+/**************************************************************************//**
+ @Group QM_init_grp QM (common) Initialization Unit
+
+ @Description QM (common) Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function t_QmExceptionsCallback
+
+ @Description Exceptions user callback routine, will be called upon an
+ exception passing the exception identification.
+
+ @Param[in] h_App - User's application descriptor.
+ @Param[in] exception - The exception.
+*//***************************************************************************/
+typedef void (t_QmExceptionsCallback) ( t_Handle h_App,
+ e_QmExceptions exception);
+
+/**************************************************************************//**
+ @Description Frame's Type to poll
+*//***************************************************************************/
+typedef enum e_QmPortalPollSource {
+ e_QM_PORTAL_POLL_SOURCE_DATA_FRAMES = 0, /**< Poll only data frames */
+ e_QM_PORTAL_POLL_SOURCE_CONTROL_FRAMES, /**< Poll only control frames */
+ e_QM_PORTAL_POLL_SOURCE_BOTH /**< Poll both */
+} e_QmPortalPollSource;
+
+/**************************************************************************//**
+ @Description structure representing QM contextA of FQ initialization parameters
+ Note that this is only "space-holder" for the Context-A. The "real"
+ Context-A is described in each specific driver (E.g. FM driver
+ has its own Context-A API).
+*//***************************************************************************/
+typedef struct {
+ uint32_t res[2]; /**< reserved size for context-a */
+} t_QmContextA;
+
+/**************************************************************************//**
+ @Description structure representing QM contextB of FQ initialization parameters
+ Note that this is only "space-holder" for the Context-B. The "real"
+ Context-B is described in each specific driver (E.g. FM driver
+ has its own Context-B API).
+*//***************************************************************************/
+typedef uint32_t t_QmContextB;
+
+/**************************************************************************//**
+ @Description structure representing QM initialization parameters
+*//***************************************************************************/
+typedef struct {
+ uint8_t guestId; /**< QM Partition Id */
+
+ uintptr_t baseAddress; /**< Qm base address (virtual)
+ NOTE: this parameter relevant only for BM in master mode ('guestId'=NCSW_MASTER_ID). */
+ uintptr_t swPortalsBaseAddress; /**< QM Software Portals Base Address (virtual) */
+ uint16_t liodn; /**< This value is attached to every transaction initiated by QMan when accessing its private data structures */
+ uint32_t totalNumOfFqids; /**< Total number of frame-queue-ids in the system */
+ uint32_t fqdMemPartitionId; /**< FQD's mem partition id;
+ NOTE: The memory partition must be non-cacheable and no-coherent area. */
+ uint32_t pfdrMemPartitionId; /**< PFDR's mem partition id;
+ NOTE: The memory partition must be non-cacheable and no-coherent area. */
+ t_QmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions.*/
+ t_Handle h_App; /**< A handle to an application layer object; This handle will
+ be passed by the driver upon calling the above callbacks */
+ int errIrq; /**< error interrupt line; NO_IRQ if interrupts not used */
+ uint32_t partFqidBase; /**< The first frame-queue-id dedicated to this partition.
+ NOTE: this parameter relevant only when working with multiple partitions. */
+ uint32_t partNumOfFqids; /**< Number of frame-queue-ids dedicated to this partition.
+ NOTE: this parameter relevant only when working with multiple partitions. */
+ uint16_t partCgsBase; /**< The first cgr dedicated to this partition.
+ NOTE: this parameter relevant only when working with multiple partitions. */
+ uint16_t partNumOfCgs; /**< Number of cgr's dedicated to this partition.
+ NOTE: this parameter relevant only when working with multiple partitions. */
+} t_QmParam;
+
+
+/**************************************************************************//**
+ @Function QM_Config
+
+ @Description Creates descriptor for the QM module.
+
+ The routine returns a handle (descriptor) to the QM object.
+ This descriptor must be passed as first parameter to all other
+ QM function calls.
+
+ No actual initialization or configuration of QM hardware is
+ done by this routine.
+
+ @Param[in] p_QmParam - Pointer to data structure of parameters
+
+ @Retval Handle to the QM object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle QM_Config(t_QmParam *p_QmParam);
+
+/**************************************************************************//**
+ @Function QM_Init
+
+ @Description Initializes the QM module
+
+ @Param[in] h_Qm - A handle to the QM module
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error QM_Init(t_Handle h_Qm);
+
+/**************************************************************************//**
+ @Function QM_Free
+
+ @Description Frees all resources that were assigned to the QM module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_Qm - A handle to the QM module
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error QM_Free(t_Handle h_Qm);
+
+
+/**************************************************************************//**
+ @Group QM_advanced_init_grp QM (common) Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description structure for defining DC portal ERN destination
+*//***************************************************************************/
+typedef struct t_QmDcPortalParams {
+ bool sendToSw;
+ e_DpaaSwPortal swPortalId;
+} t_QmDcPortalParams;
+
+
+/**************************************************************************//**
+ @Function QM_ConfigRTFramesDepth
+
+ @Description Change the run-time frames depth (i.e. the maximum total number
+ of frames that may be inside QM at a certain time) from its default
+ configuration [30000].
+
+ @Param[in] h_Qm - A handle to the QM module
+ @Param[in] rtFramesDepth - run-time max num of frames.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Config() and before QM_Init().
+*//***************************************************************************/
+t_Error QM_ConfigRTFramesDepth(t_Handle h_Qm, uint32_t rtFramesDepth);
+
+/**************************************************************************//**
+ @Function QM_ConfigPfdrThreshold
+
+ @Description Change the pfdr threshold from its default
+ configuration [0].
+ An interrupt if enables is asserted when the number of PFDRs is below this threshold.
+
+ @Param[in] h_Qm - A handle to the QM module
+ @Param[in] threshold - threshold value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Config() and before QM_Init().
+*//***************************************************************************/
+t_Error QM_ConfigPfdrThreshold(t_Handle h_Qm, uint32_t threshold);
+
+/**************************************************************************//**
+ @Function QM_ConfigSfdrReservationThreshold
+
+ @Description Change the sfdr threshold from its default
+ configuration [0].
+
+ @Param[in] h_Qm - A handle to the QM module
+ @Param[in] threshold - threshold value.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Config() and before QM_Init().
+*//***************************************************************************/
+t_Error QM_ConfigSfdrReservationThreshold(t_Handle h_Qm, uint32_t threshold);
+
+/**************************************************************************//**
+ @Function QM_ConfigErrorRejectionNotificationDest
+
+ @Description Change the destination of rejected frames for DC portals.
+ By default, depending on chip, some DC portals are set to reject
+ frames to HW and some to SW.
+
+ @Param[in] h_Qm - A handle to the QM module
+ @Param[in] id - DC Portal id.
+ @Param[in] p_Params - Destination parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Config() and before QM_Init().
+*//***************************************************************************/
+t_Error QM_ConfigErrorRejectionNotificationDest(t_Handle h_Qm, e_DpaaDcPortal id, t_QmDcPortalParams *p_Params);
+
+/** @} */ /* end of QM_advanced_init_grp group */
+/** @} */ /* end of QM_init_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_runtime_control_grp QM (common) Runtime Control Unit
+
+ @Description QM (common) Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for defining QM counters
+*//***************************************************************************/
+typedef enum e_QmCounters {
+ e_QM_COUNTERS_SFDR_IN_USE = 0, /**< Total Single Frame Descriptor Record (SFDR) currently in use */
+ e_QM_COUNTERS_PFDR_IN_USE, /**< Total Packed Frame Descriptor Record (PFDR) currently in use */
+ e_QM_COUNTERS_PFDR_FREE_POOL /**< Total Packed Frame Descriptor Record (PFDR) Free Pool Count in external memory */
+} e_QmCounters;
+
+/**************************************************************************//**
+ @Description structure for returning revision information
+*//***************************************************************************/
+typedef struct t_QmRevisionInfo {
+ uint8_t majorRev; /**< Major revision */
+ uint8_t minorRev; /**< Minor revision */
+} t_QmRevisionInfo;
+
+/**************************************************************************//**
+ @Description structure representing QM FQ-Range reservation parameters
+*//***************************************************************************/
+typedef struct t_QmRsrvFqrParams {
+ bool useForce; /**< TRUE - force reservation of specific fqids;
+ FALSE - reserve several fqids */
+ uint32_t numOfFqids; /**< number of fqids to be reserved. */
+ union{
+ struct {
+ uint32_t align; /**< alignment. will be used if useForce=FALSE */
+ } nonFrcQs;
+ struct {
+ uint32_t fqid; /**< the fqid base of the forced fqids. will be used if useForce=TRUE */
+ } frcQ;
+ } qs;
+} t_QmRsrvFqrParams;
+
+/**************************************************************************//**
+ @Description structure representing QM Error information
+*//***************************************************************************/
+typedef struct t_QmErrorInfo {
+ bool portalValid;
+ bool hwPortal;
+ e_DpaaSwPortal swPortalId; /**< Sw Portal id */
+ e_DpaaDcPortal dcpId; /**< Dcp (hw Portal) id */
+ bool fqidValid;
+ uint32_t fqid;
+} t_QmErrorInfo;
+
+
+/**************************************************************************//**
+ @Function QM_ReserveQueues
+
+ @Description Request to Reserved queues for future use.
+
+ @Param[in] h_Qm - A handle to the QM Module.
+ @Param[in] p_QmFqrParams - A structure of parameters for defining the
+ desired queues parameters.
+ @Param[out] p_BaseFqid - base-fqid on success; '0' code otherwise.
+
+ @Return E_OK on success;
+
+ @Cautions Allowed only after QM_Init().
+*//***************************************************************************/
+t_Error QM_ReserveQueues(t_Handle h_Qm, t_QmRsrvFqrParams *p_QmFqrParams, uint32_t *p_BaseFqid);
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+/**************************************************************************//**
+ @Function QM_DumpRegs
+
+ @Description Dumps all QM registers
+
+ @Param[in] h_Qm - A handle to the QM Module.
+
+ @Return E_OK on success;
+
+ @Cautions Allowed only after QM_Init().
+*//***************************************************************************/
+t_Error QM_DumpRegs(t_Handle h_Qm);
+#endif /* (defined(DEBUG_ERRORS) && ... */
+
+/**************************************************************************//**
+ @Function QM_SetException
+
+ @Description Calling this routine enables/disables the specified exception.
+
+ @Param[in] h_Qm - A handle to the QM Module.
+ @Param[in] exception - The exception to be selected.
+ @Param[in] enable - TRUE to enable interrupt, FALSE to mask it.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init().
+ This routine should NOT be called from guest-partition
+ (i.e. guestId != NCSW_MASTER_ID)
+*//***************************************************************************/
+t_Error QM_SetException(t_Handle h_Qm, e_QmExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function QM_ErrorIsr
+
+ @Description QM interrupt-service-routine for errors.
+
+ @Param[in] h_Qm - A handle to the QM module
+
+ @Cautions Allowed only following QM_Init().
+ This routine should NOT be called from guest-partition
+ (i.e. guestId != NCSW_MASTER_ID)
+*//***************************************************************************/
+void QM_ErrorIsr(t_Handle h_Qm);
+
+/**************************************************************************//**
+ @Function QM_GetErrorInformation
+
+ @Description Reads the last error information.
+
+ @Param[in] h_Qm - A handle to the QM Module.
+ @Param[out] p_errInfo - the information will be loaded to this struct.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init().
+ This routine should NOT be called from guest-partition
+ (i.e. guestId != NCSW_MASTER_ID)
+*//***************************************************************************/
+t_Error QM_GetErrorInformation(t_Handle h_Qm, t_QmErrorInfo *p_errInfo);
+
+/**************************************************************************//**
+ @Function QM_GetCounter
+
+ @Description Reads one of the QM counters.
+
+ @Param[in] h_Qm - A handle to the QM Module.
+ @Param[in] counter - The requested counter.
+
+ @Return Counter's current value.
+
+ @Cautions Allowed only following QM_Init().
+*//***************************************************************************/
+uint32_t QM_GetCounter(t_Handle h_Qm, e_QmCounters counter);
+
+/**************************************************************************//**
+ @Function QM_GetRevision
+
+ @Description Returns the QM revision
+
+ @Param[in] h_Qm A handle to a QM Module.
+ @Param[out] p_QmRevisionInfo A structure of revision information parameters.
+
+ @Return None.
+
+ @Cautions Allowed only following QM_Init().
+*//***************************************************************************/
+t_Error QM_GetRevision(t_Handle h_Qm, t_QmRevisionInfo *p_QmRevisionInfo);
+
+/** @} */ /* end of QM_runtime_control_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_runtime_data_grp QM (common) Runtime Data Unit
+
+ @Description QM (common) Runtime data unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function QM_Poll
+
+ @Description Poll frames from QM.
+
+ @Param[in] h_Qm - A handle to the QM module
+ @Param[in] source - The selected frames type to poll
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init().
+*//***************************************************************************/
+t_Error QM_Poll(t_Handle h_Qm, e_QmPortalPollSource source);
+
+/** @} */ /* end of QM_runtime_data_grp group */
+/** @} */ /* end of QM_lib_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_portal_grp QM-Portal API
+
+ @Description QM common API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group QM_portal_init_grp QM-Portal Initialization Unit
+
+ @Description QM-Portal Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description structure representing QM-Portal Stash parameters
+*//***************************************************************************/
+typedef struct {
+ uint8_t stashDestQueue; /**< This value is used to direct all stashing transactions initiated on behalf of this software portal
+ to the specific Stashing Request Queues (SRQ) */
+ uint8_t eqcr; /**< If 0, disabled. If 1, for every EQCR entry consumed by QMan a new stash transaction is performed.
+ If 2-7, after 2-7 EQCR entries being consumed by QMAN a new stash transaction is performed. */
+ bool eqcrHighPri; /**< EQCR entry stash transactions for this software portal will be signaled with higher priority. */
+ bool dqrr; /**< DQRR entry stash enable/disable */
+ uint16_t dqrrLiodn; /**< This value is attached to every transaction initiated by QMan when performing DQRR entry or EQCR_CI stashing
+ on behalf of this software portal */
+ bool dqrrHighPri; /**< DQRR entry stash transactions for this software portal will be signaled with higher priority. */
+ bool fdFq; /**< Dequeued Frame Data, Annotation, and FQ Context Stashing enable/disable */
+ uint16_t fdFqLiodn; /**< This value is attached to every transaction initiated by QMan when performing dequeued frame data and
+ annotation stashing, or FQ context stashing on behalf of this software portal */
+ bool fdFqHighPri; /**< Dequeued frame data, annotation, and FQ context stash transactions for this software portal will be signaled
+ with higher priority. */
+ bool fdFqDrop; /**< If True, Dequeued frame data, annotation, and FQ context stash transactions for this software portal will be dropped
+ by QMan if the target SRQ is almost full, to prevent QMan sequencer stalling. Stash transactions that are
+ dropped will result in a fetch from main memory when a core reads the addressed coherency granule.
+ If FALSE, Dequeued frame data, annotation, and FQ context stash transactions for this software portal will never be
+ dropped by QMan. If the target SRQ is full a sequencer will stall until each stash transaction can be completed. */
+} t_QmPortalStashParam;
+
+/**************************************************************************//**
+ @Description structure representing QM-Portal initialization parameters
+*//***************************************************************************/
+typedef struct {
+ uintptr_t ceBaseAddress; /**< Cache-enabled base address (virtual) */
+ uintptr_t ciBaseAddress; /**< Cache-inhibited base address (virtual) */
+ t_Handle h_Qm; /**< Qm Handle */
+ e_DpaaSwPortal swPortalId; /**< Portal id */
+ int irq; /**< portal interrupt line; used only if useIrq set to TRUE */
+ uint16_t fdLiodnOffset; /**< liodn to be used for all frames enqueued via this software portal */
+ t_QmReceivedFrameCallback *f_DfltFrame; /**< this callback will be called unless specific callback assigned to the FQ*/
+ t_QmRejectedFrameCallback *f_RejectedFrame; /**< this callback will be called for rejected frames. */
+ t_Handle h_App; /**< a handle to the upper layer; It will be passed by the driver upon calling the CB */
+} t_QmPortalParam;
+
+
+/**************************************************************************//**
+ @Function QM_PORTAL_Config
+
+ @Description Creates descriptor for a QM-Portal module.
+
+ The routine returns a handle (descriptor) to a QM-Portal object.
+ This descriptor must be passed as first parameter to all other
+ QM-Portal function calls.
+
+ No actual initialization or configuration of QM-Portal hardware is
+ done by this routine.
+
+ @Param[in] p_QmPortalParam - Pointer to data structure of parameters
+
+ @Retval Handle to a QM-Portal object, or NULL for Failure.
+*//***************************************************************************/
+t_Handle QM_PORTAL_Config(t_QmPortalParam *p_QmPortalParam);
+
+/**************************************************************************//**
+ @Function QM_PORTAL_Init
+
+ @Description Initializes a QM-Portal module
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error QM_PORTAL_Init(t_Handle h_QmPortal);
+
+/**************************************************************************//**
+ @Function QM_PORTAL_Free
+
+ @Description Frees all resources that were assigned to a QM-Portal module.
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error QM_PORTAL_Free(t_Handle h_QmPortal);
+
+/**************************************************************************//**
+ @Group QM_portal_advanced_init_grp QM-Portal Advanced Configuration Unit
+
+ @Description Configuration functions used to change default values.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function QM_PORTAL_ConfigDcaMode
+
+ @Description Change the Discrate Consumption Acknowledge mode
+ from its default configuration [FALSE].
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+ @Param[in] enable - Enable/Disable DCA mode
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_PORTAL_Config() and before QM_PORTAL_Init().
+*//***************************************************************************/
+t_Error QM_PORTAL_ConfigDcaMode(t_Handle h_QmPortal, bool enable);
+
+/**************************************************************************//**
+ @Function QM_PORTAL_ConfigStash
+
+ @Description Config the portal to active stash mode.
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+ @Param[in] p_StashParams - Pointer to data structure of parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_PORTAL_Config() and before QM_PORTAL_Init().
+*//***************************************************************************/
+t_Error QM_PORTAL_ConfigStash(t_Handle h_QmPortal, t_QmPortalStashParam *p_StashParams);
+
+
+/**************************************************************************//**
+ @Function QM_PORTAL_ConfigPullMode
+
+ @Description Change the Pull Mode from its default configuration [FALSE].
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+ @Param[in] pullMode - When TRUE, the Portal will work in pull mode.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_PORTAL_Config() and before QM_PORTAL_Init().
+*//***************************************************************************/
+t_Error QM_PORTAL_ConfigPullMode(t_Handle h_QmPortal, bool pullMode);
+
+/** @} */ /* end of QM_portal_advanced_init_grp group */
+/** @} */ /* end of QM_portal_init_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_portal_runtime_control_grp QM-Portal Runtime Control Unit
+
+ @Description QM-Portal Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function QM_PORTAL_AddPoolChannel
+
+ @Description Adding the pool channel to the SW-Portal's scheduler.
+ the sw-portal will get frames that came from the pool channel.
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+ @Param[in] poolChannelId - Pool channel id. must between '0' to QM_MAX_NUM_OF_POOL_CHANNELS
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_PORTAL_Init().
+*//***************************************************************************/
+t_Error QM_PORTAL_AddPoolChannel(t_Handle h_QmPortal, uint8_t poolChannelId);
+
+/** @} */ /* end of QM_portal_runtime_control_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_portal_runtime_data_grp QM-Portal Runtime Data Unit
+
+ @Description QM-Portal Runtime data unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description structure representing QM Portal Frame Info
+*//***************************************************************************/
+typedef struct t_QmPortalFrameInfo {
+ t_Handle h_App;
+ t_Handle h_QmFqr;
+ uint32_t fqidOffset;
+ t_DpaaFD frame;
+} t_QmPortalFrameInfo;
+
+/**************************************************************************//**
+ @Function QM_PORTAL_Poll
+
+ @Description Poll frames from the specified sw-portal.
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+ @Param[in] source - The selected frames type to poll
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_PORTAL_Init().
+*//***************************************************************************/
+t_Error QM_PORTAL_Poll(t_Handle h_QmPortal, e_QmPortalPollSource source);
+
+/**************************************************************************//**
+ @Function QM_PORTAL_PollFrame
+
+ @Description Poll frames from the specified sw-portal. will poll only data frames
+
+ @Param[in] h_QmPortal - A handle to a QM-Portal module
+ @Param[out] p_frameInfo - A structure to hold the dequeued frame information
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_PORTAL_Init().
+*//***************************************************************************/
+t_Error QM_PORTAL_PollFrame(t_Handle h_QmPortal, t_QmPortalFrameInfo *p_frameInfo);
+
+
+/** @} */ /* end of QM_portal_runtime_data_grp group */
+/** @} */ /* end of QM_portal_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_fqr_grp QM Frame-Queue-Range API
+
+ @Description QM-FQR API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group QM_fqr_init_grp QM-FQR Initialization Unit
+
+ @Description QM-FQR Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+
+/**************************************************************************//**
+ @Description structure representing QM FQ-Range congestion group parameters
+*//***************************************************************************/
+typedef struct {
+ t_Handle h_QmCg; /**< A handle to the congestion group. */
+ int8_t overheadAccountingLength; /**< For each frame add this number for CG calculation
+ (may be negative), if 0 - disable feature */
+ uint32_t fqTailDropThreshold; /**< if not "0" - enable tail drop on this FQR */
+} t_QmFqrCongestionAvoidanceParams;
+
+/**************************************************************************//**
+ @Description structure representing QM FQ-Range initialization parameters
+*//***************************************************************************/
+typedef struct {
+ t_Handle h_Qm; /**< A handle to a QM module */
+ t_Handle h_QmPortal; /**< A handle to a QM Portal Module;
+ will be used only for Init and Free routines;
+ NOTE : if NULL, assuming affinity */
+ bool initParked; /**< This FQ-Range will be initialize in park state (un-schedule) */
+ bool holdActive; /**< This FQ-Range can be parked (un-schedule);
+ This affects only on queues destined to software portals*/
+ bool preferInCache; /**< Prefer this FQ-Range to be in QMAN's internal cache for all states */
+ bool useContextAForStash;/**< This FQ-Range will use context A for stash */
+ union {
+ struct {
+ uint8_t frameAnnotationSize;/**< Size of Frame Annotation to be stashed */
+ uint8_t frameDataSize; /**< Size of Frame Data to be stashed. */
+ uint8_t fqContextSize; /**< Size of FQ context to be stashed. */
+ uint64_t fqContextAddr; /**< 40 bit memory address containing the FQ context information to be stashed;
+ Must be cacheline-aligned */
+ } stashingParams;
+ t_QmContextA *p_ContextA; /**< context-A field to be written in the FQ structure */
+ };
+ t_QmContextB *p_ContextB; /**< context-B field to be written in the FQ structure;
+ Note that this field may be used for Tx queues only! */
+ e_QmFQChannel channel; /**< Qm Channel */
+ uint8_t wq; /**< Work queue within the channel */
+ bool shadowMode; /**< If TRUE, useForce MUST set to TRUE and numOfFqids MUST set to '1' */
+ uint32_t numOfFqids; /**< number of fqids to be allocated*/
+ bool useForce; /**< TRUE - force allocation of specific fqids;
+ FALSE - allocate several fqids */
+ union{
+ struct {
+ uint32_t align; /**< alignment. will be used if useForce=FALSE */
+ } nonFrcQs;
+ struct {
+ uint32_t fqid; /**< the fqid base of the forced fqids. will be used if useForce=TRUE */
+ } frcQ;
+ } qs;
+ bool congestionAvoidanceEnable;
+ /**< TRUE to enable congestion avoidance mechanism */
+ t_QmFqrCongestionAvoidanceParams congestionAvoidanceParams;
+ /**< Parameters for congestion avoidance */
+} t_QmFqrParams;
+
+
+/**************************************************************************//**
+ @Function QM_FQR_Create
+
+ @Description Initializing and enabling a Frame-Queue-Range.
+ This routine should be called for adding an FQR.
+
+ @Param[in] p_QmFqrParams - A structure of parameters for defining the
+ desired queues parameters.
+
+ @Return A handle to the initialized FQR on success; NULL code otherwise.
+
+ @Cautions Allowed only following QM_Init().
+*//***************************************************************************/
+t_Handle QM_FQR_Create(t_QmFqrParams *p_QmFqrParams);
+
+/**************************************************************************//**
+ @Function QM_FQR_Free
+
+ @Description Deleting and free all resources of an initialized FQR.
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init() and QM_FQR_Create() for this FQR.
+*//***************************************************************************/
+t_Error QM_FQR_Free(t_Handle h_QmFqr);
+
+/**************************************************************************//**
+ @Function QM_FQR_FreeWDrain
+
+ @Description Deleting and free all resources of an initialized FQR
+ with the option of draining.
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+ @Param[in] f_CompletionCB - Pointer to a completion callback to be used in non-blocking mode.
+ @Param[in] deliverFrame - TRUE for deliver the drained frames to the user;
+ FALSE for not deliver the frames.
+ @Param[in] f_CallBack - Pointer to a callback to handle the delivered frames.
+ @Param[in] h_App - User's application descriptor.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init() and QM_FQR_Create() for this FQR.
+*//***************************************************************************/
+t_Error QM_FQR_FreeWDrain(t_Handle h_QmFqr,
+ t_QmFqrDrainedCompletionCB *f_CompletionCB,
+ bool deliverFrame,
+ t_QmReceivedFrameCallback *f_CallBack,
+ t_Handle h_App);
+
+/** @} */ /* end of QM_fqr_init_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_fqr_runtime_control_grp QM-FQR Runtime Control Unit
+
+ @Description QM-FQR Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description enum for defining QM-FQR counters
+*//***************************************************************************/
+typedef enum e_QmFqrCounters {
+ e_QM_FQR_COUNTERS_FRAME = 0, /**< Total number of frames on this frame queue */
+ e_QM_FQR_COUNTERS_BYTE /**< Total number of bytes in all frames on this frame queue */
+} e_QmFqrCounters;
+
+/**************************************************************************//**
+ @Function QM_FQR_RegisterCB
+
+ @Description Register a callback routine to be called when a frame comes from this FQ-Range
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+ @Param[in] f_CallBack - An application callback
+ @Param[in] h_App - User's application descriptor
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_FQR_Create().
+*//***************************************************************************/
+t_Error QM_FQR_RegisterCB(t_Handle h_QmFqr, t_QmReceivedFrameCallback *f_CallBack, t_Handle h_App);
+
+/**************************************************************************//**
+ @Function QM_FQR_Resume
+
+ @Description Request to Re-Schedule this Fqid.
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+ @Param[in] h_QmPortal - A handle to a QM Portal Module;
+ NOTE : if NULL, assuming affinity.
+ @Param[in] fqidOffset - Fqid offset within the FQ-Range.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_FQR_Create().
+*//***************************************************************************/
+t_Error QM_FQR_Resume(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset);
+
+/**************************************************************************//**
+ @Function QM_FQR_Suspend
+
+ @Description Request to Un-Schedule this Fqid.
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+ @Param[in] h_QmPortal - A handle to a QM Portal Module;
+ NOTE : if NULL, assuming affinity.
+ @Param[in] fqidOffset - Fqid offset within the FQ-Range.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_FQR_Create().
+*//***************************************************************************/
+t_Error QM_FQR_Suspend(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset);
+
+/**************************************************************************//**
+ @Function QM_FQR_GetFqid
+
+ @Description Returned the Fqid base of the FQ-Range
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+
+ @Return Fqid base.
+
+ @Cautions Allowed only following QM_FQR_Create().
+*//***************************************************************************/
+uint32_t QM_FQR_GetFqid(t_Handle h_QmFqr);
+
+/**************************************************************************//**
+ @Function QM_FQR_GetCounter
+
+ @Description Reads one of the QM-FQR counters.
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+ @Param[in] h_QmPortal - A handle to a QM Portal Module;
+ NOTE : if NULL, assuming affinity.
+ @Param[in] fqidOffset - Fqid offset within the FQ-Range.
+ @Param[in] counter - The requested counter.
+
+ @Return Counter's current value.
+
+ @Cautions Allowed only following QM_FQR_Create().
+*//***************************************************************************/
+uint32_t QM_FQR_GetCounter(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, e_QmFqrCounters counter);
+
+/** @} */ /* end of QM_fqr_runtime_control_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_fqr_runtime_data_grp QM-FQR Runtime Data Unit
+
+ @Description QM-FQR Runtime data unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function QM_FQR_Enqueue
+
+ @Description Enqueue the frame into the FQ to be transmitted.
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+ @Param[in] h_QmPortal - A handle to a QM Portal Module;
+ NOTE : if NULL, assuming affinity.
+ @Param[in] fqidOffset - Fqid offset within the FQ-Range.
+ @Param[in] p_Frame - Pointer to the frame to be enqueued.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_FQR_Create().
+*//***************************************************************************/
+t_Error QM_FQR_Enqueue(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, t_DpaaFD *p_Frame);
+
+/**************************************************************************//**
+ @Function QM_FQR_PullFrame
+
+ @Description Perform a Pull command.
+
+ @Param[in] h_QmFqr - A handle to a QM-FQR Module.
+ @Param[in] h_QmPortal - A handle to a QM Portal Module;
+ NOTE : if NULL, assuming affinity.
+ @Param[in] fqidOffset - Fqid offset within the FQ-Range.
+ @Param[out] p_Frame - The Received Frame
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_PORTAL_Init().
+*//***************************************************************************/
+t_Error QM_FQR_PullFrame(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, t_DpaaFD *p_Frame);
+
+
+/** @} */ /* end of QM_fqr_runtime_data_grp group */
+/** @} */ /* end of QM_fqr_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_cg_grp QM Congestion Group API
+
+ @Description QM-CG API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group QM_cg_init_grp QM-Congestion Group Initialization Unit
+
+ @Description QM-CG Initialization Unit
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description structure representing QM CG WRED curve
+*//***************************************************************************/
+typedef struct t_QmCgWredCurve {
+ uint32_t maxTh; /**< minimum threshold - below this level
+ all packets are rejected (approximated
+ to be expressed as x*2^y due to HW
+ implementation)*/
+ uint32_t minTh; /**< minimum threshold - below this level
+ all packets are accepted (approximated
+ due to HW implementation)*/
+ uint8_t probabilityDenominator; /**< 1-64, the fraction of packets dropped
+ when the average queue depth is at the
+ maximum threshold.(approximated due to HW
+ implementation). */
+} t_QmCgWredCurve;
+
+/**************************************************************************//**
+ @Description structure representing QM CG WRED parameters
+*//***************************************************************************/
+typedef struct t_QmCgWredParams {
+ bool enableGreen;
+ t_QmCgWredCurve greenCurve;
+ bool enableYellow;
+ t_QmCgWredCurve yellowCurve;
+ bool enableRed;
+ t_QmCgWredCurve redCurve;
+} t_QmCgWredParams;
+
+/**************************************************************************//**
+ @Description structure representing QM CG configuration parameters
+*//***************************************************************************/
+typedef struct t_QmCgParams {
+ t_Handle h_Qm; /**< A handle to a QM module */
+ t_Handle h_QmPortal; /**< A handle to a QM Portal Module;
+ will be used for Init, Free and as
+ an interrupt destination for cg state
+ change (if CgStateChangeEnable = TRUE) */
+ bool frameCount; /**< TRUE for frame count, FALSE - byte count */
+ bool wredEnable; /**< if TRUE - WRED enabled. Each color is enabled independently
+ so that some colors may use WRED, but others may use
+ Tail drop - if enabled, or none. */
+ t_QmCgWredParams wredParams; /**< WRED parameters, relevant if wredEnable = TRUE*/
+ bool tailDropEnable; /**< if TRUE - Tail drop enabled */
+ uint32_t threshold; /**< If Tail drop - used as Tail drop threshold, otherwise
+ 'threshold' may still be used to receive notifications
+ when threshold is passed. If threshold and f_Exception
+ are set, interrupts are set defaultly by driver. */
+ bool notifyDcPortal; /**< Relevant if this CG receives enqueues from a direct portal
+ e_DPAA_DCPORTAL0 or e_DPAA_DCPORTAL1. TRUE to notify
+ the DC portal, FALSE to notify this SW portal. */
+ e_DpaaDcPortal dcPortalId; /**< relevant if notifyDcPortal=TRUE - DC Portal id */
+ t_QmExceptionsCallback *f_Exception; /**< relevant and mandatory if threshold is configured and
+ notifyDcPortal = FALSE. If threshold and f_Exception
+ are set, interrupts are set defaultly by driver */
+ t_Handle h_App; /**< A handle to the application layer, will be passed as
+ argument to f_Exception */
+} t_QmCgParams;
+
+
+/**************************************************************************//**
+ @Function QM_CG_Create
+
+ @Description Create and configure a congestion Group.
+
+ @Param[in] p_CgParams - CG parameters
+
+ @Return A handle to the CG module
+
+ @Cautions Allowed only following QM_Init().
+*//***************************************************************************/
+t_Handle QM_CG_Create(t_QmCgParams *p_CgParams);
+
+/**************************************************************************//**
+ @Function QM_CG_Free
+
+ @Description Deleting and free all resources of an initialized CG.
+
+ @Param[in] h_QmCg - A handle to a QM-CG Module.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init() and QM_CR_Create() for this CG.
+*//***************************************************************************/
+t_Error QM_CG_Free(t_Handle h_QmCg);
+
+/** @} */ /* end of QM_cg_init_grp group */
+
+
+/**************************************************************************//**
+ @Group QM_cg_runtime_control_grp QM-CG Runtime Control Unit
+
+ @Description QM-CG Runtime control unit API functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description structure representing QM CG WRED colors
+*//***************************************************************************/
+typedef enum e_QmCgColor {
+ e_QM_CG_COLOR_GREEN,
+ e_QM_CG_COLOR_YELLOW,
+ e_QM_CG_COLOR_RED
+} e_QmCgColor;
+
+/**************************************************************************//**
+ @Description structure representing QM CG modification parameters
+*//***************************************************************************/
+typedef struct t_QmCgModifyWredParams {
+ e_QmCgColor color;
+ bool enable;
+ t_QmCgWredCurve wredParams;
+} t_QmCgModifyWredParams;
+
+
+/**************************************************************************//**
+ @Function QM_CG_SetException
+
+ @Description Set CG exception.
+
+ @Param[in] h_QmCg - A handle to a QM-CG Module.
+ @Param[in] exception - exception enum
+ @Param[in] enable - TRUE to enable, FALSE to disable.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init() and QM_CG_Create() for this CG.
+*//***************************************************************************/
+t_Error QM_CG_SetException(t_Handle h_QmCg, e_QmExceptions exception, bool enable);
+
+/**************************************************************************//**
+ @Function QM_CG_ModifyWredCurve
+
+ @Description Change WRED curve parameters for a selected color.
+ Note that this routine may be called only for valid CG's that
+ already have been configured for WRED, and only need a change
+ in the WRED parameters.
+
+ @Param[in] h_QmCg - A handle to a QM-CG Module.
+ @Param[in] p_QmCgModifyParams - A structure of new WRED parameters.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init() and QM_CG_Create() for this CG.
+*//***************************************************************************/
+t_Error QM_CG_ModifyWredCurve(t_Handle h_QmCg, t_QmCgModifyWredParams *p_QmCgModifyParams);
+
+/**************************************************************************//**
+ @Function QM_CG_ModifyTailDropThreshold
+
+ @Description Change WRED curve parameters for a selected color.
+ Note that this routine may be called only for valid CG's that
+ already have been configured for tail drop, and only need a change
+ in the threshold value.
+
+ @Param[in] h_QmCg - A handle to a QM-CG Module.
+ @Param[in] threshold - New threshold.
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following QM_Init() and QM_CG_Create() for this CG.
+*//***************************************************************************/
+t_Error QM_CG_ModifyTailDropThreshold(t_Handle h_QmCg, uint32_t threshold);
+
+
+/** @} */ /* end of QM_cg_runtime_control_grp group */
+/** @} */ /* end of QM_cg_grp group */
+/** @} */ /* end of QM_grp group */
+
+
+#endif /* __QM_EXT_H */
diff --git a/sys/contrib/ncsw/inc/core_ext.h b/sys/contrib/ncsw/inc/core_ext.h
new file mode 100644
index 0000000..022de2b3
--- /dev/null
+++ b/sys/contrib/ncsw/inc/core_ext.h
@@ -0,0 +1,81 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File core_ext.h
+
+ @Description Generic interface to basic core operations.
+
+ The system integrator must ensure that this interface is
+ mapped to a specific core implementation, by including the
+ appropriate header file.
+*//***************************************************************************/
+#ifndef __CORE_EXT_H
+#define __CORE_EXT_H
+
+
+#ifdef NCSW_PPC_CORE
+#include "ppc_ext.h"
+#elif defined(NCSW_VXWORKS)
+#include "core_vxw_ext.h"
+#else
+#error "Core is not defined!"
+#endif /* NCSW_CORE */
+
+#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
+#error "Must define core as little-endian or big-endian!"
+#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
+
+
+/**************************************************************************//**
+ @Function CORE_GetId
+
+ @Description Returns the core ID in the system.
+
+ @Return Core ID.
+*//***************************************************************************/
+uint32_t CORE_GetId(void);
+
+/**************************************************************************//**
+ @Function CORE_MemoryBarrier
+
+ @Description This routine will cause the core to stop executing any commands
+ until all previous memory read/write commands are completely out
+ of the core's pipeline.
+
+ @Return None.
+*//***************************************************************************/
+void CORE_MemoryBarrier(void);
+
+
+#endif /* __CORE_EXT_H */
+
diff --git a/sys/contrib/ncsw/inc/cores/e500v2_ext.h b/sys/contrib/ncsw/inc/cores/e500v2_ext.h
new file mode 100644
index 0000000..df545ff
--- /dev/null
+++ b/sys/contrib/ncsw/inc/cores/e500v2_ext.h
@@ -0,0 +1,413 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File e500v2_ext.h
+
+ @Description E500 external definitions prototypes
+ This file is not included by the E500
+ source file as it is an assembly file. It is used
+ only for prototypes exposure, for inclusion
+ by user and other modules.
+*//***************************************************************************/
+
+#ifndef __E500V2_EXT_H
+#define __E500V2_EXT_H
+
+#include "std_ext.h"
+
+
+/* Layer 1 Cache Manipulations
+ *==============================
+ * Should not be called directly by the user.
+ */
+void L1DCache_Invalidate (void);
+void L1ICache_Invalidate(void);
+void L1DCache_Enable(void);
+void L1ICache_Enable(void);
+void L1DCache_Disable(void);
+void L1ICache_Disable(void);
+void L1DCache_Flush(void);
+void L1ICache_Flush(void);
+/*
+ *
+ */
+uint32_t L1DCache_LineLock(uint32_t addr);
+uint32_t L1ICache_LineLock(uint32_t addr);
+void L1Cache_BroadCastEnable(void);
+void L1Cache_BroadCastDisable(void);
+
+
+#define CORE_DCacheEnable E500_DCacheEnable
+#define CORE_ICacheEnable E500_ICacheEnable
+#define CORE_DCacheDisable E500_DCacheDisable
+#define CORE_ICacheDisable E500_ICacheDisable
+#define CORE_GetId E500_GetId
+#define CORE_TestAndSet E500_TestAndSet
+#define CORE_MemoryBarrier E500_MemoryBarrier
+#define CORE_InstructionSync E500_InstructionSync
+
+#define CORE_SetDozeMode E500_SetDozeMode
+#define CORE_SetNapMode E500_SetNapMode
+#define CORE_SetSleepMode E500_SetSleepMode
+#define CORE_SetJogMode E500_SetJogMode
+#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
+
+#define CORE_RecoverDozeMode E500_RecoverDozeMode
+#define CORE_RecoverNapMode E500_RecoverNapMode
+#define CORE_RecoverSleepMode E500_RecoverSleepMode
+#define CORE_RecoverJogMode E500_RecoverJogMode
+
+void E500_SetDozeMode(void);
+void E500_SetNapMode(void);
+void E500_SetSleepMode(void);
+void E500_SetJogMode(void);
+t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
+
+void E500_RecoverDozeMode(void);
+void E500_RecoverNapMode(void);
+void E500_RecoverSleepMode(void);
+void E500_RecoverJogMode(void);
+
+
+/**************************************************************************//**
+ @Group E500_id E500 Application Programming Interface
+
+ @Description E500 API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group E500_init_grp E500 Initialization Unit
+
+ @Description E500 initialization unit API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+
+/**************************************************************************//**
+ @Function E500_DCacheEnable
+
+ @Description Enables the data cache for memory pages that are
+ not cache inhibited.
+
+ @Return None.
+*//***************************************************************************/
+void E500_DCacheEnable(void);
+
+/**************************************************************************//**
+ @Function E500_ICacheEnable
+
+ @Description Enables the instruction cache for memory pages that are
+ not cache inhibited.
+
+ @Return None.
+*//***************************************************************************/
+void E500_ICacheEnable(void);
+
+/**************************************************************************//**
+ @Function E500_DCacheDisable
+
+ @Description Disables the data cache.
+
+ @Return None.
+*//***************************************************************************/
+void E500_DCacheDisable(void);
+
+/**************************************************************************//**
+ @Function E500_ICacheDisable
+
+ @Description Disables the instruction cache.
+
+ @Return None.
+*//***************************************************************************/
+void E500_ICacheDisable(void);
+
+/**************************************************************************//**
+ @Function E500_DCacheFlush
+
+ @Description Flushes the data cache
+
+ @Return None.
+*//***************************************************************************/
+void E500_DCacheFlush(void);
+
+/**************************************************************************//**
+ @Function E500_ICacheFlush
+
+ @Description Flushes the instruction cache.
+
+ @Return None.
+*//***************************************************************************/
+void E500_ICacheFlush(void);
+
+/**************************************************************************//**
+ @Function E500_DCacheSetStashId
+
+ @Description Set Stash Id for data cache
+
+ @Param[in] stashId the stash id to be set.
+
+ @Return None.
+*//***************************************************************************/
+void E500_DCacheSetStashId(uint8_t stashId);
+
+/**************************************************************************//**
+ @Description E500mc L2 Cache Operation Mode
+*//***************************************************************************/
+typedef enum e_E500mcL2CacheMode
+{
+ e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
+ e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
+ e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
+} e_E500mcL2CacheMode;
+
+/**************************************************************************//**
+ @Function E500_L2CacheEnable
+
+ @Description Enables the cache for memory pages that are not cache inhibited.
+
+ @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
+
+ @Return None.
+
+ @Cautions This routine must be call only ONCE for both caches. I.e. it is
+ not possible to call this routine for i-cache and than to call
+ again for d-cache; The second call will override the first one.
+*//***************************************************************************/
+void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
+
+/**************************************************************************//**
+ @Function E500_L2CacheDisable
+
+ @Description Disables the cache (data instruction or both).
+
+ @Return None.
+
+*//***************************************************************************/
+void E500_L2CacheDisable(void);
+
+/**************************************************************************//**
+ @Function E500_L2CacheFlush
+
+ @Description Flushes the cache.
+
+ @Return None.
+*//***************************************************************************/
+void E500_L2CacheFlush(void);
+
+/**************************************************************************//**
+ @Function E500_L2SetStashId
+
+ @Description Set Stash Id
+
+ @Param[in] stashId the stash id to be set.
+
+ @Return None.
+*//***************************************************************************/
+void E500_L2SetStashId(uint8_t stashId);
+
+/**************************************************************************//**
+ @Function E500_AddressBusStreamingEnable
+
+ @Description Enables address bus streaming on the CCB.
+
+ This setting, along with the ECM streaming configuration
+ parameters, enables address bus streaming on the CCB.
+
+ @Return None.
+*//***************************************************************************/
+void E500_AddressBusStreamingEnable(void);
+
+/**************************************************************************//**
+ @Function E500_AddressBusStreamingDisable
+
+ @Description Disables address bus streaming on the CCB.
+
+ @Return None.
+*//***************************************************************************/
+void E500_AddressBusStreamingDisable(void);
+
+/**************************************************************************//**
+ @Function E500_AddressBroadcastEnable
+
+ @Description Enables address broadcast.
+
+ The e500 broadcasts cache management instructions (dcbst, dcblc
+ (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
+ based on ABE. ABE must be set to allow management of external
+ L2 caches.
+
+ @Return None.
+*//***************************************************************************/
+void E500_AddressBroadcastEnable(void);
+
+/**************************************************************************//**
+ @Function E500_AddressBroadcastDisable
+
+ @Description Disables address broadcast.
+
+ The e500 broadcasts cache management instructions (dcbst, dcblc
+ (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
+ based on ABE. ABE must be set to allow management of external
+ L2 caches.
+
+ @Return None.
+*//***************************************************************************/
+void E500_AddressBroadcastDisable(void);
+
+/**************************************************************************//**
+ @Function E500_IsTaskletSupported
+
+ @Description Checks if tasklets are supported by the e500 interrupt handler.
+
+ @Retval TRUE - Tasklets are supported.
+ @Retval FALSE - Tasklets are not supported.
+*//***************************************************************************/
+bool E500_IsTaskletSupported(void);
+
+void E500_EnableTimeBase(void);
+void E500_DisableTimeBase(void);
+
+uint64_t E500_GetTimeBaseTime(void);
+
+void E500_GenericIntrInit(void);
+
+t_Error E500_SetIntr(int ppcIntrSrc,
+ void (* Isr)(t_Handle handle),
+ t_Handle handle);
+
+t_Error E500_ClearIntr(int ppcIntrSrc);
+
+/**************************************************************************//**
+ @Function E500_GenericIntrHandler
+
+ @Description This is the general e500 interrupt handler.
+
+ It is called by the main assembly interrupt handler
+ when an exception occurs and no other function has been
+ assigned to this exception.
+
+ @Param intrEntry - (In) The exception interrupt vector entry.
+*//***************************************************************************/
+void E500_GenericIntrHandler(uint32_t intrEntry);
+
+/**************************************************************************//**
+ @Function CriticalIntr
+
+ @Description This is the specific critical e500 interrupt handler.
+
+ It is called by the main assembly interrupt handler
+ when an critical interrupt.
+
+ @Param intrEntry - (In) The exception interrupt vector entry.
+*//***************************************************************************/
+void CriticalIntr(uint32_t intrEntry);
+
+
+/**************************************************************************//**
+ @Function E500_GetId
+
+ @Description Returns the core ID in the system.
+
+ @Return Core ID.
+*//***************************************************************************/
+uint32_t E500_GetId(void);
+
+/**************************************************************************//**
+ @Function E500_TestAndSet
+
+ @Description This routine tries to atomically test-and-set an integer
+ in memory to a non-zero value.
+
+ The memory will be set only if it is tested as zero, in which
+ case the routine returns the new non-zero value; otherwise the
+ routine returns zero.
+
+ @Param[in] p - pointer to a volatile int in memory, on which test-and-set
+ operation should be made.
+
+ @Retval Zero - Operation failed - memory was already set.
+ @Retval Non-zero - Operation succeeded - memory has been set.
+*//***************************************************************************/
+int E500_TestAndSet(volatile int *p);
+
+/**************************************************************************//**
+ @Function E500_MemoryBarrier
+
+ @Description This routine will cause the core to stop executing any commands
+ until all previous memory read/write commands are completely out
+ of the core's pipeline.
+
+ @Return None.
+*//***************************************************************************/
+static __inline__ void E500_MemoryBarrier(void)
+{
+#ifdef CORE_E500MC
+ __asm__ ("mbar 1");
+#else
+ /**** ERRATA WORK AROUND START ****/
+ /* ERRATA num: CPU1 */
+ /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
+ guarded loads and stores. */
+
+ /* "msync" instruction is used instead */
+
+ __asm__ ("msync");
+
+ /**** ERRATA WORK AROUND END ****/
+#endif
+}
+
+/**************************************************************************//**
+ @Function E500_InstructionSync
+
+ @Description This routine will cause the core to wait for previous instructions
+ (including any interrupts they generate) to complete before the
+ synchronization command executes, which purges all instructions
+ from the processor's pipeline and refetches the next instruction.
+
+ @Return None.
+*//***************************************************************************/
+static __inline__ void E500_InstructionSync(void)
+{
+ __asm__ ("isync");
+}
+
+
+/** @} */ /* end of E500_init_grp group */
+/** @} */ /* end of E500_grp group */
+
+
+#endif /* __E500V2_EXT_H */
diff --git a/sys/contrib/ncsw/inc/cores/ppc_ext.h b/sys/contrib/ncsw/inc/cores/ppc_ext.h
new file mode 100644
index 0000000..e045c31
--- /dev/null
+++ b/sys/contrib/ncsw/inc/cores/ppc_ext.h
@@ -0,0 +1,130 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File ppc_ext.h
+
+ @Description Core API for PowerPC cores
+
+ These routines must be implemented by each specific PowerPC
+ core driver.
+*//***************************************************************************/
+#ifndef __PPC_EXT_H
+#define __PPC_EXT_H
+
+#include "part_ext.h"
+
+
+#define CORE_IS_BIG_ENDIAN
+
+
+/**************************************************************************//**
+ @Function CORE_TestAndSet
+
+ @Description This routine tries to atomically test-and-set an integer
+ in memory to a non-zero value.
+
+ The memory will be set only if it is tested as zero, in which
+ case the routine returns the new non-zero value; otherwise the
+ routine returns zero.
+
+ @Param[in] p - pointer to a volatile int in memory, on which test-and-set
+ operation should be made.
+
+ @Retval Zero - Operation failed - memory was already set.
+ @Retval Non-zero - Operation succeeded - memory has been set.
+*//***************************************************************************/
+int CORE_TestAndSet(volatile int *p);
+
+/**************************************************************************//**
+ @Function CORE_InstructionSync
+
+ @Description This routine will cause the core to wait for previous instructions
+ (including any interrupts they generate) to complete before the
+ synchronization command executes, which purges all instructions
+ from the processor's pipeline and refetches the next instruction.
+
+ @Return None.
+*//***************************************************************************/
+void CORE_InstructionSync(void);
+
+/**************************************************************************//**
+ @Function CORE_DCacheEnable
+
+ @Description Enables the data cache for memory pages that are
+ not cache inhibited.
+
+ @Return None.
+*//***************************************************************************/
+void CORE_DCacheEnable(void);
+
+/**************************************************************************//**
+ @Function CORE_ICacheEnable
+
+ @Description Enables the instruction cache for memory pages that are
+ not cache inhibited.
+
+ @Return None.
+*//***************************************************************************/
+void CORE_ICacheEnable(void);
+
+/**************************************************************************//**
+ @Function CORE_DCacheDisable
+
+ @Description Disables the data cache.
+
+ @Return None.
+*//***************************************************************************/
+void CORE_DCacheDisable(void);
+
+/**************************************************************************//**
+ @Function CORE_ICacheDisable
+
+ @Description Disables the instruction cache.
+
+ @Return None.
+*//***************************************************************************/
+void CORE_ICacheDisable(void);
+
+
+
+
+#if defined(CORE_E300)
+#include "e300_ext.h"
+#elif defined(CORE_E500V2) || defined(CORE_E500MC)
+#include "e500v2_ext.h"
+#else
+#error "Core not defined!"
+#endif
+
+
+#endif /* __PPC_EXT_H */
diff --git a/sys/contrib/ncsw/inc/ctype_ext.h b/sys/contrib/ncsw/inc/ctype_ext.h
new file mode 100644
index 0000000..e882fb1
--- /dev/null
+++ b/sys/contrib/ncsw/inc/ctype_ext.h
@@ -0,0 +1,93 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CTYPE_EXT_H
+#define __CTYPE_EXT_H
+
+
+#if defined(NCSW_LINUX) && defined(__KERNEL__) || defined(NCSW_FREEBSD)
+/*
+ * NOTE! This ctype does not handle EOF like the standard C
+ * library is required to.
+ */
+
+#define _U 0x01 /* upper */
+#define _L 0x02 /* lower */
+#define _D 0x04 /* digit */
+#define _C 0x08 /* cntrl */
+#define _P 0x10 /* punct */
+#define _S 0x20 /* white space (space/lf/tab) */
+#define _X 0x40 /* hex digit */
+#define _SP 0x80 /* hard space (0x20) */
+
+extern unsigned char _ctype[];
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
+#define isdigit(c) ((__ismask(c)&(_D)) != 0)
+#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c) ((__ismask(c)&(_L)) != 0)
+#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c) ((__ismask(c)&(_P)) != 0)
+#define isspace(c) ((__ismask(c)&(_S)) != 0)
+#define isupper(c) ((__ismask(c)&(_U)) != 0)
+#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define toascii(c) (((unsigned char)(c))&0x7f)
+
+static __inline__ unsigned char __tolower(unsigned char c)
+{
+ if (isupper(c))
+ c -= 'A'-'a';
+ return c;
+}
+
+static __inline__ unsigned char __toupper(unsigned char c)
+{
+ if (islower(c))
+ c -= 'a'-'A';
+ return c;
+}
+
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
+
+#else
+#include <ctype.h>
+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) || defined(NCSW_FREEBSD) */
+
+
+#endif /* __CTYPE_EXT_H */
diff --git a/sys/contrib/ncsw/inc/ddr_std_ext.h b/sys/contrib/ncsw/inc/ddr_std_ext.h
new file mode 100644
index 0000000..c4d9ed6
--- /dev/null
+++ b/sys/contrib/ncsw/inc/ddr_std_ext.h
@@ -0,0 +1,80 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+
+#ifndef __DDR_SDT_EXT_H
+#define __DDR_SDT_EXT_H
+
+
+/**************************************************************************//**
+ @Group ddr_Generic_Resources
+
+ @Description ddr generic functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+
+/**************************************************************************//**
+ @Description SPD maximum size
+*//***************************************************************************/
+#define SPD_MAX_SIZE 256
+
+/**************************************************************************//**
+ @Description DDR types select
+*//***************************************************************************/
+typedef enum e_DdrType
+{
+ e_DDR_DDR1,
+ e_DDR_DDR2,
+ e_DDR_DDR3,
+ e_DDR_DDR3L
+} e_DdrType;
+
+/**************************************************************************//**
+ @Description DDR Mode.
+*//***************************************************************************/
+typedef enum e_DdrMode
+{
+ e_DDR_BUS_WIDTH_32BIT,
+ e_DDR_BUS_WIDTH_64BIT
+} e_DdrMode;
+
+/** @} */ /* end of ddr_Generic_Resources group */
+
+
+
+#endif /* __DDR_SDT_EXT_H */
+
diff --git a/sys/contrib/ncsw/inc/debug_ext.h b/sys/contrib/ncsw/inc/debug_ext.h
new file mode 100644
index 0000000..37f5b83
--- /dev/null
+++ b/sys/contrib/ncsw/inc/debug_ext.h
@@ -0,0 +1,259 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File debug_ext.h
+
+ @Description Debug mode definitions.
+*//***************************************************************************/
+
+#ifndef __DEBUG_EXT_H
+#define __DEBUG_EXT_H
+
+#include "std_ext.h"
+#include "xx_ext.h"
+#include "memcpy_ext.h"
+#if (DEBUG_ERRORS > 0)
+#include "sprint_ext.h"
+#include "string_ext.h"
+#endif /* DEBUG_ERRORS > 0 */
+
+
+#if (DEBUG_ERRORS > 0)
+
+/* Internally used macros */
+
+#define DUMP_Print XX_Print
+#define DUMP_MAX_LEVELS 6
+#define DUMP_MAX_STR 64
+
+
+#define _CREATE_DUMP_SUBSTR(phrase) \
+ dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
+ sprintf(dumpTmpStr, "%s", #phrase); \
+ p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
+ while (p_DumpToken != NULL) \
+ { \
+ strcat(dumpSubStr, p_DumpToken); \
+ if (dumpIsArr[dumpTmpLevel]) \
+ { \
+ strcat(dumpSubStr, dumpIdxStr[dumpTmpLevel]); \
+ p_DumpToken = strtok(NULL, "."); \
+ } \
+ if ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != 0) \
+ strcat(dumpSubStr, "."); \
+ }\
+
+
+/**************************************************************************//**
+ @Group gen_id General Drivers Utilities
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group dump_id Memory and Registers Dump Mechanism
+
+ @Description Macros for dumping memory mapped structures.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Declaration of dump mechanism variables.
+
+ This macro must be declared at the beginning of each routine
+ which uses the dump mechanism macros, before the routine's code
+ starts.
+*//***************************************************************************/
+#define DECLARE_DUMP \
+ char dumpIdxStr[DUMP_MAX_LEVELS + 1][6] = { "", }; \
+ char dumpSubStr[DUMP_MAX_STR] = ""; \
+ char dumpTmpStr[DUMP_MAX_STR] = ""; \
+ char *p_DumpToken = NULL; \
+ int dumpArrIdx = 0, dumpArrSize = 0, dumpVarSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
+ uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
+ /* Prevent warnings if not all used */ \
+ UNUSED(dumpIdxStr[0][0]); \
+ UNUSED(dumpSubStr[0]); \
+ UNUSED(dumpTmpStr[0]); \
+ UNUSED(p_DumpToken); \
+ UNUSED(dumpArrIdx); \
+ UNUSED(dumpArrSize); \
+ UNUSED(dumpVarSize); \
+ UNUSED(dumpLevel); \
+ UNUSED(dumpTmpLevel); \
+ UNUSED(dumpIsArr[0]);
+
+
+/**************************************************************************//**
+ @Description Prints a title for a subsequent dumped structure or memory.
+
+ The inputs for this macro are the structure/memory title and
+ its base addresses.
+*//***************************************************************************/
+#define DUMP_TITLE(addr, msg) \
+ DUMP_Print("\r\n"); DUMP_Print msg; \
+ DUMP_Print(" (0x%p)\r\n" \
+ "---------------------------------------------------------\r\n", \
+ (addr))
+
+/**************************************************************************//**
+ @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
+
+ The inputs for this macro are the sub-structure subtitle.
+ A separating line with this subtitle will be printed.
+*//***************************************************************************/
+#define DUMP_SUBTITLE(subtitle) \
+ DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
+
+
+/**************************************************************************//**
+ @Description Dumps a memory region in 4-bytes aligned format.
+
+ The inputs for this macro are the base addresses and size
+ (in bytes) of the memory region.
+*//***************************************************************************/
+#define DUMP_MEMORY(addr, size) \
+ MemDisp((uint8_t *)(addr), (int)(size))
+
+
+/**************************************************************************//**
+ @Description Declares a dump loop, for dumping a sub-structure array.
+
+ The inputs for this macro are:
+ - idx: an index variable, for indexing the sub-structure items
+ inside the loop. This variable must be declared separately
+ in the beginning of the routine.
+ - cnt: the number of times to repeat the loop. This number should
+ equal the number of items in the sub-structures array.
+
+ Note, that the body of the loop must be written inside brackets.
+*//***************************************************************************/
+#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
+ for (idx=0, dumpIsArr[dumpLevel++] = 1; \
+ (idx < cnt) && sprintf(dumpIdxStr[dumpLevel-1], "[%d]", idx); \
+ idx++, ((idx < cnt) || ((dumpIsArr[--dumpLevel] = 0) == 0)))
+
+
+/**************************************************************************//**
+ @Description Dumps a structure's member variable.
+
+ The input for this macro is the full reference for the member
+ variable, where the structure is referenced using a pointer.
+
+ Note, that a members array must be dumped using DUMP_ARR macro,
+ rather than using this macro.
+
+ If the member variable is part of a sub-structure hierarchy,
+ the full hierarchy (including array indexing) must be specified.
+
+ Examples: p_Struct->member
+ p_Struct->sub.member
+ p_Struct->sub[i].member
+*//***************************************************************************/
+#define DUMP_VAR(st, phrase) \
+ do { \
+ void *addr = (void *)&((st)->phrase); \
+ _CREATE_DUMP_SUBSTR(phrase); \
+ dumpVarSize = sizeof((st)->phrase); \
+ switch (dumpVarSize) \
+ { \
+ case 1: DUMP_Print("0x%08X: 0x%02x%14s\t%s\r\n", \
+ addr, GET_UINT8(*(uint8_t*)addr), "", dumpSubStr); break; \
+ case 2: DUMP_Print("0x%08X: 0x%04x%12s\t%s\r\n", \
+ addr, GET_UINT16(*(uint16_t*)addr), "", dumpSubStr); break; \
+ case 4: DUMP_Print("0x%08X: 0x%08x%8s\t%s\r\n", \
+ addr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); break; \
+ case 8: DUMP_Print("0x%08X: 0x%016llx\t%s\r\n", \
+ addr, GET_UINT64(*(uint64_t*)addr), dumpSubStr); break; \
+ default: DUMP_Print("Bad size %d (" #st "->" #phrase ")\r\n", dumpVarSize); \
+ } \
+ } while (0)
+
+
+/**************************************************************************//**
+ @Description Dumps a structure's members array.
+
+ The input for this macro is the full reference for the members
+ array, where the structure is referenced using a pointer.
+
+ If the members array is part of a sub-structure hierarchy,
+ the full hierarchy (including array indexing) must be specified.
+
+ Examples: p_Struct->array
+ p_Struct->sub.array
+ p_Struct->sub[i].array
+*//***************************************************************************/
+#define DUMP_ARR(st, phrase) \
+ do { \
+ _CREATE_DUMP_SUBSTR(phrase); \
+ dumpArrSize = ARRAY_SIZE((st)->phrase); \
+ dumpVarSize = sizeof((st)->phrase[0]); \
+ switch (dumpVarSize) \
+ { \
+ case 1: \
+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
+ DUMP_Print("0x%08X: 0x%02x%14s\t%s[%d]\r\n", \
+ &((st)->phrase[dumpArrIdx]), GET_UINT8((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
+ } break; \
+ case 2: \
+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
+ DUMP_Print("0x%08X: 0x%04x%12s\t%s[%d]\r\n", \
+ &((st)->phrase[dumpArrIdx]), GET_UINT16((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
+ } break; \
+ case 4: \
+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
+ DUMP_Print("0x%08X: 0x%08x%8s\t%s[%d]\r\n", \
+ &((st)->phrase[dumpArrIdx]), GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
+ } break; \
+ case 8: \
+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
+ DUMP_Print("0x%08X: 0x%016llx\t%s[%d]\r\n", \
+ &((st)->phrase[dumpArrIdx]), GET_UINT64((st)->phrase[dumpArrIdx]), dumpSubStr, dumpArrIdx); \
+ } break; \
+ default: DUMP_Print("Bad size %d (" #st "->" #phrase "[0])\r\n", dumpVarSize); \
+ } \
+ } while (0)
+
+
+#endif /* DEBUG_ERRORS > 0 */
+
+
+/** @} */ /* end of dump_id group */
+/** @} */ /* end of gen_id group */
+
+
+#endif /* __DEBUG_EXT_H */
+
diff --git a/sys/contrib/ncsw/inc/endian_ext.h b/sys/contrib/ncsw/inc/endian_ext.h
new file mode 100644
index 0000000..7084e82
--- /dev/null
+++ b/sys/contrib/ncsw/inc/endian_ext.h
@@ -0,0 +1,446 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+
+ @File endian_ext.h
+
+ @Description Big/little endian swapping routines.
+*//***************************************************************************/
+
+#ifndef __ENDIAN_EXT_H
+#define __ENDIAN_EXT_H
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group gen_id General Drivers Utilities
+
+ @Description General usage API. This API is intended for usage by both the
+ internal modules and the user's application.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group endian_id Big/Little-Endian Conversion
+
+ @Description Routines and macros for Big/Little-Endian conversion and
+ general byte swapping.
+
+ All routines and macros are expecting unsigned values as
+ parameters, but will generate the correct result also for
+ signed values. Therefore, signed/unsigned casting is allowed.
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Collection Byte-Swap Macros
+
+ Macros for swapping byte order.
+
+ @Cautions The parameters of these macros are evaluated multiple times.
+ For calculated expressions or expressions that contain function
+ calls it is recommended to use the byte-swap routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Swaps the byte order of a given 16-bit value.
+
+ @Param[in] val - The 16-bit value to swap.
+
+ @Return The byte-swapped value..
+
+ @Cautions The given value is evaluated multiple times by this macro.
+ For calculated expressions or expressions that contain function
+ calls it is recommended to use the SwapUint16() routine.
+
+ @hideinitializer
+*//***************************************************************************/
+#define SWAP_UINT16(val) \
+ ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
+
+/**************************************************************************//**
+ @Description Swaps the byte order of a given 32-bit value.
+
+ @Param[in] val - The 32-bit value to swap.
+
+ @Return The byte-swapped value..
+
+ @Cautions The given value is evaluated multiple times by this macro.
+ For calculated expressions or expressions that contain function
+ calls it is recommended to use the SwapUint32() routine.
+
+ @hideinitializer
+*//***************************************************************************/
+#define SWAP_UINT32(val) \
+ ((uint32_t)((((val) & 0x000000FF) << 24) | \
+ (((val) & 0x0000FF00) << 8) | \
+ (((val) & 0x00FF0000) >> 8) | \
+ (((val) & 0xFF000000) >> 24)))
+
+/**************************************************************************//**
+ @Description Swaps the byte order of a given 64-bit value.
+
+ @Param[in] val - The 64-bit value to swap.
+
+ @Return The byte-swapped value..
+
+ @Cautions The given value is evaluated multiple times by this macro.
+ For calculated expressions or expressions that contain function
+ calls it is recommended to use the SwapUint64() routine.
+
+ @hideinitializer
+*//***************************************************************************/
+#define SWAP_UINT64(val) \
+ ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
+ (((val) & 0x000000000000FF00ULL) << 40) | \
+ (((val) & 0x0000000000FF0000ULL) << 24) | \
+ (((val) & 0x00000000FF000000ULL) << 8) | \
+ (((val) & 0x000000FF00000000ULL) >> 8) | \
+ (((val) & 0x0000FF0000000000ULL) >> 24) | \
+ (((val) & 0x00FF000000000000ULL) >> 40) | \
+ (((val) & 0xFF00000000000000ULL) >> 56)))
+
+/* @} */
+
+/**************************************************************************//**
+ @Collection Byte-Swap Routines
+
+ Routines for swapping the byte order of a given parameter and
+ returning the swapped value.
+
+ These inline routines are safer than the byte-swap macros,
+ because they evaluate the parameter expression only once.
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function SwapUint16
+
+ @Description Returns the byte-swapped value of a given 16-bit value.
+
+ @Param[in] val - The 16-bit value.
+
+ @Return The byte-swapped value of the parameter.
+*//***************************************************************************/
+static __inline__ uint16_t SwapUint16(uint16_t val)
+{
+ return (uint16_t)(((val & 0x00FF) << 8) |
+ ((val & 0xFF00) >> 8));
+}
+
+/**************************************************************************//**
+ @Function SwapUint32
+
+ @Description Returns the byte-swapped value of a given 32-bit value.
+
+ @Param[in] val - The 32-bit value.
+
+ @Return The byte-swapped value of the parameter.
+*//***************************************************************************/
+static __inline__ uint32_t SwapUint32(uint32_t val)
+{
+ return (uint32_t)(((val & 0x000000FF) << 24) |
+ ((val & 0x0000FF00) << 8) |
+ ((val & 0x00FF0000) >> 8) |
+ ((val & 0xFF000000) >> 24));
+}
+
+/**************************************************************************//**
+ @Function SwapUint64
+
+ @Description Returns the byte-swapped value of a given 64-bit value.
+
+ @Param[in] val - The 64-bit value.
+
+ @Return The byte-swapped value of the parameter.
+*//***************************************************************************/
+static __inline__ uint64_t SwapUint64(uint64_t val)
+{
+ return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
+ ((val & 0x000000000000FF00ULL) << 40) |
+ ((val & 0x0000000000FF0000ULL) << 24) |
+ ((val & 0x00000000FF000000ULL) << 8) |
+ ((val & 0x000000FF00000000ULL) >> 8) |
+ ((val & 0x0000FF0000000000ULL) >> 24) |
+ ((val & 0x00FF000000000000ULL) >> 40) |
+ ((val & 0xFF00000000000000ULL) >> 56));
+}
+
+/* @} */
+
+/**************************************************************************//**
+ @Collection In-place Byte-Swap-And-Set Routines
+
+ Routines for swapping the byte order of a given variable and
+ setting the swapped value back to the same variable.
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function SwapUint16P
+
+ @Description Swaps the byte order of a given 16-bit variable.
+
+ @Param[in] p_Val - Pointer to the 16-bit variable.
+
+ @Return None.
+*//***************************************************************************/
+static __inline__ void SwapUint16P(uint16_t *p_Val)
+{
+ *p_Val = SwapUint16(*p_Val);
+}
+
+/**************************************************************************//**
+ @Function SwapUint32P
+
+ @Description Swaps the byte order of a given 32-bit variable.
+
+ @Param[in] p_Val - Pointer to the 32-bit variable.
+
+ @Return None.
+*//***************************************************************************/
+static __inline__ void SwapUint32P(uint32_t *p_Val)
+{
+ *p_Val = SwapUint32(*p_Val);
+}
+
+/**************************************************************************//**
+ @Function SwapUint64P
+
+ @Description Swaps the byte order of a given 64-bit variable.
+
+ @Param[in] p_Val - Pointer to the 64-bit variable.
+
+ @Return None.
+*//***************************************************************************/
+static __inline__ void SwapUint64P(uint64_t *p_Val)
+{
+ *p_Val = SwapUint64(*p_Val);
+}
+
+/* @} */
+
+
+/**************************************************************************//**
+ @Collection Little-Endian Conversion Macros
+
+ These macros convert given parameters to or from Little-Endian
+ format. Use these macros when you want to read or write a specific
+ Little-Endian value in memory, without a-priori knowing the CPU
+ byte order.
+
+ These macros use the byte-swap routines. For conversion of
+ constants in initialization structures, you may use the CONST
+ versions of these macros (see below), which are using the
+ byte-swap macros instead.
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Converts a given 16-bit value from CPU byte order to
+ Little-Endian byte order.
+
+ @Param[in] val - The 16-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CPU_TO_LE16(val) SwapUint16(val)
+
+/**************************************************************************//**
+ @Description Converts a given 32-bit value from CPU byte order to
+ Little-Endian byte order.
+
+ @Param[in] val - The 32-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CPU_TO_LE32(val) SwapUint32(val)
+
+/**************************************************************************//**
+ @Description Converts a given 64-bit value from CPU byte order to
+ Little-Endian byte order.
+
+ @Param[in] val - The 64-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CPU_TO_LE64(val) SwapUint64(val)
+
+
+/**************************************************************************//**
+ @Description Converts a given 16-bit value from Little-Endian byte order to
+ CPU byte order.
+
+ @Param[in] val - The 16-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define LE16_TO_CPU(val) CPU_TO_LE16(val)
+
+/**************************************************************************//**
+ @Description Converts a given 32-bit value from Little-Endian byte order to
+ CPU byte order.
+
+ @Param[in] val - The 32-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define LE32_TO_CPU(val) CPU_TO_LE32(val)
+
+/**************************************************************************//**
+ @Description Converts a given 64-bit value from Little-Endian byte order to
+ CPU byte order.
+
+ @Param[in] val - The 64-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define LE64_TO_CPU(val) CPU_TO_LE64(val)
+
+/* @} */
+
+/**************************************************************************//**
+ @Collection Little-Endian Constant Conversion Macros
+
+ These macros convert given constants to or from Little-Endian
+ format. Use these macros when you want to read or write a specific
+ Little-Endian constant in memory, without a-priori knowing the
+ CPU byte order.
+
+ These macros use the byte-swap macros, therefore can be used for
+ conversion of constants in initialization structures.
+
+ @Cautions The parameters of these macros are evaluated multiple times.
+ For non-constant expressions, use the non-CONST macro versions.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Converts a given 16-bit constant from CPU byte order to
+ Little-Endian byte order.
+
+ @Param[in] val - The 16-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
+
+/**************************************************************************//**
+ @Description Converts a given 32-bit constant from CPU byte order to
+ Little-Endian byte order.
+
+ @Param[in] val - The 32-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
+
+/**************************************************************************//**
+ @Description Converts a given 64-bit constant from CPU byte order to
+ Little-Endian byte order.
+
+ @Param[in] val - The 64-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
+
+
+/**************************************************************************//**
+ @Description Converts a given 16-bit constant from Little-Endian byte order
+ to CPU byte order.
+
+ @Param[in] val - The 16-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
+
+/**************************************************************************//**
+ @Description Converts a given 32-bit constant from Little-Endian byte order
+ to CPU byte order.
+
+ @Param[in] val - The 32-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
+
+/**************************************************************************//**
+ @Description Converts a given 64-bit constant from Little-Endian byte order
+ to CPU byte order.
+
+ @Param[in] val - The 64-bit value to convert.
+
+ @Return The converted value.
+
+ @hideinitializer
+*//***************************************************************************/
+#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
+
+/* @} */
+
+
+/** @} */ /* end of endian_id group */
+/** @} */ /* end of gen_id group */
+
+
+#endif /* __ENDIAN_EXT_H */
+
diff --git a/sys/contrib/ncsw/inc/enet_ext.h b/sys/contrib/ncsw/inc/enet_ext.h
new file mode 100644
index 0000000..14f7760
--- /dev/null
+++ b/sys/contrib/ncsw/inc/enet_ext.h
@@ -0,0 +1,154 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File enet_ext.h
+
+ @Description Ethernet generic definitions and enums.
+*//***************************************************************************/
+
+#ifndef __ENET_EXT_H
+#define __ENET_EXT_H
+
+
+#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
+#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
+
+
+/**************************************************************************//**
+ @Description Ethernet Address
+*//***************************************************************************/
+typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
+
+/**************************************************************************//**
+ @Description Ethernet Address Type.
+*//***************************************************************************/
+typedef enum e_EnetAddrType
+{
+ e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
+ e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
+ e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
+} e_EnetAddrType;
+
+
+/**************************************************************************//**
+ @Description Ethernet MAC-PHY Interface
+*//***************************************************************************/
+typedef enum e_EnetInterface
+{
+ e_ENET_IF_MII = 0x00010000, /**< MII interface */
+ e_ENET_IF_RMII = 0x00020000, /**< RMII interface */
+ e_ENET_IF_SMII = 0x00030000, /**< SMII interface */
+ e_ENET_IF_GMII = 0x00040000, /**< GMII interface */
+ e_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
+ e_ENET_IF_TBI = 0x00060000, /**< TBI interface */
+ e_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
+ e_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
+ e_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
+ e_ENET_IF_QSGMII= 0x000a0000 /**< QSGMII interface */
+} e_EnetInterface;
+
+/**************************************************************************//**
+ @Description Ethernet Duplex Mode
+*//***************************************************************************/
+typedef enum e_EnetDuplexMode
+{
+ e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
+ e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
+} e_EnetDuplexMode;
+
+/**************************************************************************//**
+ @Description Ethernet Speed (nominal data rate)
+*//***************************************************************************/
+typedef enum e_EnetSpeed
+{
+ e_ENET_SPEED_10 = 10, /**< 10 Mbps */
+ e_ENET_SPEED_100 = 100, /**< 100 Mbps */
+ e_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
+ e_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
+} e_EnetSpeed;
+
+/**************************************************************************//**
+ @Description Ethernet mode (combination of MAC-PHY interface and speed)
+*//***************************************************************************/
+typedef enum e_EnetMode
+{
+ e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
+ e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
+ e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
+ e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
+ e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
+ e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
+ e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
+ e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
+ e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
+ e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
+ e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
+ e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
+ e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
+ e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10), /**< 10 Mbps SGMII */
+ e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100), /**< 100 Mbps SGMII */
+ e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000), /**< 1000 Mbps SGMII */
+ e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
+ e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000) /**< 1000 Mbps QSGMII */
+} e_EnetMode;
+
+
+#define IS_ENET_MODE_VALID(mode) \
+ (((mode) == e_ENET_MODE_MII_10 ) || \
+ ((mode) == e_ENET_MODE_MII_100 ) || \
+ ((mode) == e_ENET_MODE_RMII_10 ) || \
+ ((mode) == e_ENET_MODE_RMII_100 ) || \
+ ((mode) == e_ENET_MODE_SMII_10 ) || \
+ ((mode) == e_ENET_MODE_SMII_100 ) || \
+ ((mode) == e_ENET_MODE_GMII_1000 ) || \
+ ((mode) == e_ENET_MODE_RGMII_10 ) || \
+ ((mode) == e_ENET_MODE_RGMII_100 ) || \
+ ((mode) == e_ENET_MODE_RGMII_1000 ) || \
+ ((mode) == e_ENET_MODE_TBI_1000 ) || \
+ ((mode) == e_ENET_MODE_RTBI_1000 ) || \
+ ((mode) == e_ENET_MODE_SGMII_10 ) || \
+ ((mode) == e_ENET_MODE_SGMII_100 ) || \
+ ((mode) == e_ENET_MODE_SGMII_1000 ) || \
+ ((mode) == e_ENET_MODE_XGMII_10000) || \
+ ((mode) == e_ENET_MODE_QSGMII_1000))
+
+
+#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
+
+#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0xFFFF0000)
+#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
+
+
+
+#endif /* __ENET_EXT_H */
+
diff --git a/sys/contrib/ncsw/inc/error_ext.h b/sys/contrib/ncsw/inc/error_ext.h
new file mode 100644
index 0000000..778ba30
--- /dev/null
+++ b/sys/contrib/ncsw/inc/error_ext.h
@@ -0,0 +1,553 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ @File error_ext.h
+
+ @Description Error definitions.
+*//***************************************************************************/
+
+#ifndef __ERROR_EXT_H
+#define __ERROR_EXT_H
+
+#include "std_ext.h"
+#include "xx_ext.h"
+#include "core_ext.h"
+
+/**************************************************************************//**
+ @Group gen_id General Drivers Utilities
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group gen_error_id Errors, Events and Debug
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/******************************************************************************
+The scheme below provides the bits description for error codes:
+
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+| Reserved (should be zero) | Module ID |
+
+ 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+| Error Type |
+******************************************************************************/
+
+#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
+
+#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
+ /**< Extract module code from error code (#t_Error) */
+
+#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
+ /**< Extract error type (#e_ErrorType) from
+ error code (#t_Error) */
+
+
+/**************************************************************************//**
+ @Description Error Type Enumeration
+*//***************************************************************************/
+typedef enum e_ErrorType /* Comments / Associated Message Strings */
+{ /* ------------------------------------------------------------ */
+ E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
+
+ /* Invalid Function Calls */
+ ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
+ /* String: none. */
+ ,E_INVALID_OPERATION /**< The operation/command is invalid (unrecognized). */
+ /* String: none. */
+ ,E_NOT_SUPPORTED /**< The function is not supported or not implemented. */
+ /* String: none. */
+ ,E_NO_DEVICE /**< The associated device is not initialized. */
+ /* String: none. */
+
+ /* Invalid Parameters */
+ ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
+ /* String: none, unless the function takes in more than one
+ handle (in this case add the handle description) */
+ ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
+ /* String: none, unless the function takes in more than one
+ ID (in this case add the ID description) */
+ ,E_NULL_POINTER /**< Unexpected NULL pointer. */
+ /* String: pointer description. */
+ ,E_INVALID_VALUE /**< Invalid value. */
+ /* Use for non-enumeration parameters, and
+ only when other error types are not suitable.
+ String: parameter description + "(should be <attribute>)",
+ e.g: "Maximum Rx buffer length (should be divisible by 8)",
+ "Channel number (should be even)". */
+ ,E_INVALID_SELECTION /**< Invalid selection or mode. */
+ /* Use for enumeration values, only when other error types
+ are not suitable.
+ String: parameter description. */
+ ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
+ /* String: none, unless the function takes in more than one
+ communication mode indications (in this case add
+ parameter description). */
+ ,E_INVALID_BYTE_ORDER /**< Invalid byte order. */
+ /* String: none, unless the function takes in more than one
+ byte order indications (in this case add parameter
+ description). */
+ ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
+ /* String: none, unless the function takes in more than one
+ memory types (in this case add memory description,
+ e.g: "Data memory", "Buffer descriptors memory"). */
+ ,E_INVALID_INTR_QUEUE /**< Invalid interrupt queue. */
+ /* String: none, unless the function takes in more than one
+ interrupt queues (in this case add queue description,
+ e.g: "Rx interrupt queue", "Tx interrupt queue"). */
+ ,E_INVALID_PRIORITY /**< Invalid priority. */
+ /* String: none, unless the function takes in more than one
+ priority (in this case add priority description). */
+ ,E_INVALID_CLOCK /**< Invalid clock. */
+ /* String: none, unless the function takes in more than one
+ clocks (in this case add clock description,
+ e.g: "Rx clock", "Tx clock"). */
+ ,E_INVALID_RATE /**< Invalid rate value. */
+ /* String: none, unless the function takes in more than one
+ rate values (in this case add rate description). */
+ ,E_INVALID_ADDRESS /**< Invalid address. */
+ /* String: description of the specific violation. */
+ ,E_INVALID_BUS /**< Invalid bus type. */
+ /* String: none, unless the function takes in more than one
+ bus parameters (in this case add bus description). */
+ ,E_BUS_CONFLICT /**< Bus (or memory) type conflicts with another setting. */
+ /* String: description of the conflicting buses/memories. */
+ ,E_CONFLICT /**< Some setting conflicts with another setting. */
+ /* String: description of the conflicting settings. */
+ ,E_NOT_ALIGNED /**< Non-aligned address. */
+ /* String: parameter description + "(should be %d-bytes aligned)",
+ e.g: "Rx data buffer (should be 32-bytes aligned)". */
+ ,E_NOT_IN_RANGE /**< Parameter value is out of range. */
+ /* Don't use this error for enumeration parameters.
+ String: parameter description + "(should be %d-%d)",
+ e.g: "Number of pad characters (should be 0-15)". */
+
+ /* Frame/Buffer Errors */
+ ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
+ /* String: none. */
+ ,E_EMPTY_FRAME /**< Frame object is empty (has no buffers). */
+ /* String: none. */
+ ,E_EMPTY_BUFFER /**< Buffer object is empty (no data, or zero data length). */
+ /* String: none. */
+
+ /* Resource Errors */
+ ,E_NO_MEMORY /**< External memory allocation failed. */
+ /* String: description of item for which allocation failed. */
+ ,E_NOT_FOUND /**< Requested resource or item was not found. */
+ /* Use only when the resource/item is uniquely identified.
+ String: none, unless the operation is not the main goal
+ of the function (in this case add item description). */
+ ,E_NOT_AVAILABLE /**< Resource is unavailable. */
+ /* String: none, unless the operation is not the main goal
+ of the function (in this case add resource description). */
+ ,E_ALREADY_EXISTS /**< Requested resource or item already exists. */
+ /* Use when resource duplication or sharing are not allowed.
+ String: none, unless the operation is not the main goal
+ of the function (in this case add item description). */
+ ,E_FULL /**< Resource is full. */
+ /* String: none, unless the operation is not the main goal
+ of the function (in this case add resource description). */
+ ,E_EMPTY /**< Resource is empty. */
+ /* String: none, unless the operation is not the main goal
+ of the function (in this case add resource description). */
+ ,E_BUSY /**< Resource or module is busy. */
+ /* String: none, unless the operation is not the main goal
+ of the function (in this case add resource description). */
+ ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
+ /* String: none, unless the operation is not the main goal
+ of the function (in this case add item description). */
+
+ /* Read/Write Access Errors */
+ ,E_READ_FAILED /**< Read access failed on memory/device. */
+ /* String: none, or device name. */
+ ,E_WRITE_FAILED /**< Write access failed on memory/device. */
+ /* String: none, or device name. */
+
+ /* Send/Receive Failures */
+ ,E_SEND_FAILED /**< Send operation failed on device. */
+ /* String: none, or device name. */
+ ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
+ /* String: none, or device name. */
+
+ /* Operation time-out */
+ ,E_TIMEOUT /**< The operation timed out. */
+ /* String: none. */
+
+ ,E_DUMMY_LAST /* NEVER USED */
+
+} e_ErrorType;
+
+
+/**************************************************************************//**
+ @Description Event Type Enumeration
+*//***************************************************************************/
+typedef enum e_Event /* Comments / Associated Flags and Message Strings */
+{ /* ------------------------------------------------------------ */
+ EV_NO_EVENT = 0 /**< No event; Never used. */
+
+ ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
+ complete packets);
+ Flags: error flags in case of error, zero otherwise. */
+ /* String: reason for discard, e.g: "Error in frame",
+ "Disordered frame", "Incomplete frame", "No frame object". */
+ ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
+ Flags: usually status flags from the buffer descriptor. */
+ /* String: none. */
+ ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
+ Flags: usually status flags from the buffer descriptor. */
+ /* String: none. */
+ ,EV_NO_BUFFERS /**< System ran out of buffer objects;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_RX_QUEUE_FULL /**< Receive queue is full;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
+ Flags: zero. */
+ /* String: object description (name). */
+ ,EV_BUS_ERROR /**< Illegal access on bus;
+ Flags: the address (if available) or bus identifier */
+ /* String: bus/address/module description. */
+ ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
+ Flags: zero. */
+ /* String: none. */
+ ,EV_DUMMY_LAST
+
+} e_Event;
+
+
+/**************************************************************************//**
+ @Collection Debug Levels for Errors and Events
+
+ The level description refers to errors only.
+ For events, classification is done by the user.
+
+ The TRACE, INFO and WARNING levels are allowed only when using
+ the DBG macro, and are not allowed when using the error macros
+ (RETURN_ERROR or REPORT_ERROR).
+ @{
+*//***************************************************************************/
+#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
+#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
+ configuration. */
+#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
+ parameters may be successful. */
+#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
+#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
+#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
+
+#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
+
+/* @} */
+
+
+
+#define NO_MSG ("")
+
+#ifndef DEBUG_GLOBAL_LEVEL
+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
+#endif /* DEBUG_GLOBAL_LEVEL */
+
+#ifndef ERROR_GLOBAL_LEVEL
+#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
+#endif /* ERROR_GLOBAL_LEVEL */
+
+#ifndef EVENT_GLOBAL_LEVEL
+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
+#endif /* EVENT_GLOBAL_LEVEL */
+
+#ifdef EVENT_LOCAL_LEVEL
+#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
+#else
+#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
+#endif /* EVENT_LOCAL_LEVEL */
+
+
+#ifndef DEBUG_DYNAMIC_LEVEL
+#define DEBUG_USING_STATIC_LEVEL
+
+#ifdef DEBUG_STATIC_LEVEL
+#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
+#else
+#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
+#endif /* DEBUG_STATIC_LEVEL */
+
+#else /* DEBUG_DYNAMIC_LEVEL */
+#ifdef DEBUG_STATIC_LEVEL
+#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
+#else
+int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
+#endif /* DEBUG_STATIC_LEVEL */
+#endif /* !DEBUG_DYNAMIC_LEVEL */
+
+
+#ifndef ERROR_DYNAMIC_LEVEL
+
+#ifdef ERROR_STATIC_LEVEL
+#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
+#else
+#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
+#endif /* ERROR_STATIC_LEVEL */
+
+#else /* ERROR_DYNAMIC_LEVEL */
+#ifdef ERROR_STATIC_LEVEL
+#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
+#else
+int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
+#endif /* ERROR_STATIC_LEVEL */
+#endif /* !ERROR_DYNAMIC_LEVEL */
+
+#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
+#define PRINT_FMT_PARAMS CORE_GetId(), __FILE__, __LINE__, __FUNCTION__
+
+#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
+/* No debug/error/event messages at all */
+#define DBG(_level, _vmsg)
+
+#define REPORT_ERROR(_level, _err, _vmsg)
+
+#define RETURN_ERROR(_level, _err, _vmsg) \
+ return ERROR_CODE(_err)
+
+#if (REPORT_EVENTS > 0)
+
+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
+ do { \
+ if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
+ XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
+ } \
+ } while (0)
+
+#else
+
+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
+
+#endif /* (REPORT_EVENTS > 0) */
+
+
+#else /* DEBUG_ERRORS > 0 */
+
+extern const char *dbgLevelStrings[];
+extern const char *errTypeStrings[];
+extern const char *moduleStrings[];
+#if (REPORT_EVENTS > 0)
+extern const char *eventStrings[];
+#endif /* (REPORT_EVENTS > 0) */
+
+
+#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
+/* No need for DBG macro - debug level is higher anyway */
+#define DBG(_level, _vmsg)
+#else
+#define DBG(_level, _vmsg) \
+ do { \
+ if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
+ XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
+ dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
+ moduleStrings[__ERR_MODULE__ >> 16], \
+ PRINT_FMT_PARAMS); \
+ XX_Print _vmsg; \
+ XX_Print("\r\n"); \
+ } \
+ } while (0)
+#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
+
+
+#define REPORT_ERROR(_level, _err, _vmsg) \
+ do { \
+ if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
+ XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
+ dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
+ moduleStrings[__ERR_MODULE__ >> 16], \
+ PRINT_FMT_PARAMS, \
+ errTypeStrings[(GET_ERROR_TYPE(_err) - E_OK - 1)]); \
+ XX_Print _vmsg; \
+ XX_Print("\r\n"); \
+ } \
+ } while (0)
+
+
+#define RETURN_ERROR(_level, _err, _vmsg) \
+ do { \
+ REPORT_ERROR(_level, (_err), _vmsg); \
+ return ERROR_CODE(_err); \
+ } while (0)
+
+
+#if (REPORT_EVENTS > 0)
+
+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
+ do { \
+ if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
+ XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
+ dbgLevelStrings[_ev##_LEVEL - 1], \
+ moduleStrings[__ERR_MODULE__ >> 16], \
+ PRINT_FMT_PARAMS, \
+ eventStrings[((_ev) - EV_NO_EVENT - 1)], \
+ (uint16_t)(_flg)); \
+ XX_Print _vmsg; \
+ XX_Print("\r\n"); \
+ XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
+ } \
+ } while (0)
+
+#else /* not REPORT_EVENTS */
+
+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
+
+#endif /* (REPORT_EVENTS > 0) */
+
+#endif /* (DEBUG_ERRORS > 0) */
+
+
+/**************************************************************************//**
+ @Function ASSERT_COND
+
+ @Description Assertion macro.
+
+ @Param[in] _cond - The condition being checked, in positive form;
+ Failure of the condition triggers the assert.
+*//***************************************************************************/
+#ifdef DISABLE_ASSERTIONS
+#define ASSERT_COND(_cond)
+#else
+#define ASSERT_COND(_cond) \
+ do { \
+ if (!(_cond)) { \
+ XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
+ PRINT_FMT_PARAMS); \
+ XX_Exit(1); \
+ } \
+ } while (0)
+#endif /* DISABLE_ASSERTIONS */
+
+
+#ifdef DISABLE_INIT_PARAMETERS_CHECK
+
+#define CHECK_INIT_PARAMETERS(handle, f_check)
+#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
+
+#else
+
+#define CHECK_INIT_PARAMETERS(handle, f_check) \
+ do { \
+ t_Error err = f_check(handle); \
+ if (err != E_OK) { \
+ RETURN_ERROR(MAJOR, err, NO_MSG); \
+ } \
+ } while (0)
+
+#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
+ do { \
+ t_Error err = f_check(handle); \
+ if (err != E_OK) { \
+ REPORT_ERROR(MAJOR, err, NO_MSG); \
+ return (retval); \
+ } \
+ } while (0)
+
+#endif /* DISABLE_INIT_PARAMETERS_CHECK */
+
+#ifdef DISABLE_SANITY_CHECKS
+
+#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
+#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
+#define SANITY_CHECK_RETURN(_cond, _err)
+#define SANITY_CHECK_EXIT(_cond, _err)
+
+#else /* DISABLE_SANITY_CHECKS */
+
+#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
+ do { \
+ if (!(_cond)) { \
+ RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
+ } \
+ } while (0)
+
+#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
+ do { \
+ if (!(_cond)) { \
+ REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
+ return (retval); \
+ } \
+ } while (0)
+
+#define SANITY_CHECK_RETURN(_cond, _err) \
+ do { \
+ if (!(_cond)) { \
+ REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
+ return; \
+ } \
+ } while (0)
+
+#define SANITY_CHECK_EXIT(_cond, _err) \
+ do { \
+ if (!(_cond)) { \
+ REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
+ XX_Exit(1); \
+ } \
+ } while (0)
+
+#endif /* DISABLE_SANITY_CHECKS */
+
+/** @} */ /* end of Debug/error Utils group */
+
+/** @} */ /* end of General Utils group */
+
+#endif /* __ERROR_EXT_H */
+
+
diff --git a/sys/contrib/ncsw/inc/etc/list_ext.h b/sys/contrib/ncsw/inc/etc/list_ext.h
new file mode 100644
index 0000000..d6f3a66
--- /dev/null
+++ b/sys/contrib/ncsw/inc/etc/list_ext.h
@@ -0,0 +1,357 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+
+ @File list_ext.h
+
+ @Description External prototypes for list.c
+*//***************************************************************************/
+
+#ifndef __LIST_EXT_H
+#define __LIST_EXT_H
+
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group etc_id Utility Library Application Programming Interface
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group list_id List
+
+ @Description List module functions,definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description List structure.
+*//***************************************************************************/
+typedef struct List
+{
+ struct List *p_Next; /**< A pointer to the next list object */
+ struct List *p_Prev; /**< A pointer to the previous list object */
+} t_List;
+
+
+/**************************************************************************//**
+ @Function NCSW_LIST_FIRST/LIST_LAST/NCSW_LIST_NEXT/NCSW_LIST_PREV
+
+ @Description Macro to get first/last/next/previous entry in a list.
+
+ @Param[in] p_List - A pointer to a list.
+*//***************************************************************************/
+#define NCSW_LIST_FIRST(p_List) (p_List)->p_Next
+#define LIST_LAST(p_List) (p_List)->p_Prev
+#define NCSW_LIST_NEXT NCSW_LIST_FIRST
+#define NCSW_LIST_PREV LIST_LAST
+
+
+/**************************************************************************//**
+ @Function NCSW_LIST_INIT
+
+ @Description Macro for initialization of a list struct.
+
+ @Param[in] lst - The t_List object to initialize.
+*//***************************************************************************/
+#define NCSW_LIST_INIT(lst) {&(lst), &(lst)}
+
+
+/**************************************************************************//**
+ @Function LIST
+
+ @Description Macro to declare of a list.
+
+ @Param[in] listName - The list object name.
+*//***************************************************************************/
+#define LIST(listName) t_List listName = NCSW_LIST_INIT(listName)
+
+
+/**************************************************************************//**
+ @Function INIT_LIST
+
+ @Description Macro to initialize a list pointer.
+
+ @Param[in] p_List - The list pointer.
+*//***************************************************************************/
+#define INIT_LIST(p_List) NCSW_LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
+
+
+/**************************************************************************//**
+ @Function LIST_OBJECT
+
+ @Description Macro to get the struct (object) for this entry.
+
+ @Param[in] type - The type of the struct (object) this list is embedded in.
+ @Param[in] member - The name of the t_List object within the struct.
+
+ @Return The structure pointer for this entry.
+*//***************************************************************************/
+#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
+#define LIST_OBJECT(p_List, type, member) \
+ ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
+
+
+/**************************************************************************//**
+ @Function LIST_FOR_EACH
+
+ @Description Macro to iterate over a list.
+
+ @Param[in] p_Pos - A pointer to a list to use as a loop counter.
+ @Param[in] p_Head - A pointer to the head for your list pointer.
+
+ @Cautions You can't delete items with this routine.
+ For deletion use LIST_FOR_EACH_SAFE().
+*//***************************************************************************/
+#define LIST_FOR_EACH(p_Pos, p_Head) \
+ for (p_Pos = NCSW_LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = NCSW_LIST_NEXT(p_Pos))
+
+
+/**************************************************************************//**
+ @Function LIST_FOR_EACH_SAFE
+
+ @Description Macro to iterate over a list safe against removal of list entry.
+
+ @Param[in] p_Pos - A pointer to a list to use as a loop counter.
+ @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
+ @Param[in] p_Head - A pointer to the head for your list pointer.
+*//***************************************************************************/
+#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
+ for (p_Pos = NCSW_LIST_FIRST(p_Head), p_Tmp = NCSW_LIST_FIRST(p_Pos); \
+ p_Pos != (p_Head); \
+ p_Pos = p_Tmp, p_Tmp = NCSW_LIST_NEXT(p_Pos))
+
+
+/**************************************************************************//**
+ @Function LIST_FOR_EACH_OBJECT_SAFE
+
+ @Description Macro to iterate over list of given type safely.
+
+ @Param[in] p_Pos - A pointer to a list to use as a loop counter.
+ @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
+ @Param[in] type - The type of the struct this is embedded in.
+ @Param[in] p_Head - A pointer to the head for your list pointer.
+ @Param[in] member - The name of the list_struct within the struct.
+
+ @Cautions You can't delete items with this routine.
+ For deletion use LIST_FOR_EACH_SAFE().
+*//***************************************************************************/
+#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
+ for (p_Pos = LIST_OBJECT(NCSW_LIST_FIRST(p_Head), type, member), \
+ p_Tmp = LIST_OBJECT(NCSW_LIST_FIRST(&p_Pos->member), type, member); \
+ &p_Pos->member != (p_Head); \
+ p_Pos = p_Tmp, \
+ p_Tmp = LIST_OBJECT(NCSW_LIST_FIRST(&p_Pos->member), type, member))
+
+/**************************************************************************//**
+ @Function LIST_FOR_EACH_OBJECT
+
+ @Description Macro to iterate over list of given type.
+
+ @Param[in] p_Pos - A pointer to a list to use as a loop counter.
+ @Param[in] type - The type of the struct this is embedded in.
+ @Param[in] p_Head - A pointer to the head for your list pointer.
+ @Param[in] member - The name of the list_struct within the struct.
+
+ @Cautions You can't delete items with this routine.
+ For deletion use LIST_FOR_EACH_SAFE().
+*//***************************************************************************/
+#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
+ for (p_Pos = LIST_OBJECT(NCSW_LIST_FIRST(p_Head), type, member); \
+ &p_Pos->member != (p_Head); \
+ p_Pos = LIST_OBJECT(NCSW_LIST_FIRST(&(p_Pos->member)), type, member))
+
+
+/**************************************************************************//**
+ @Function LIST_Add
+
+ @Description Add a new entry to a list.
+
+ Insert a new entry after the specified head.
+ This is good for implementing stacks.
+
+ @Param[in] p_New - A pointer to a new list entry to be added.
+ @Param[in] p_Head - A pointer to a list head to add it after.
+
+ @Return none.
+*//***************************************************************************/
+static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
+{
+ NCSW_LIST_PREV(NCSW_LIST_NEXT(p_Head)) = p_New;
+ NCSW_LIST_NEXT(p_New) = NCSW_LIST_NEXT(p_Head);
+ NCSW_LIST_PREV(p_New) = p_Head;
+ NCSW_LIST_NEXT(p_Head) = p_New;
+}
+
+
+/**************************************************************************//**
+ @Function LIST_AddToTail
+
+ @Description Add a new entry to a list.
+
+ Insert a new entry before the specified head.
+ This is useful for implementing queues.
+
+ @Param[in] p_New - A pointer to a new list entry to be added.
+ @Param[in] p_Head - A pointer to a list head to add it after.
+
+ @Return none.
+*//***************************************************************************/
+static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
+{
+ NCSW_LIST_NEXT(NCSW_LIST_PREV(p_Head)) = p_New;
+ NCSW_LIST_PREV(p_New) = NCSW_LIST_PREV(p_Head);
+ NCSW_LIST_NEXT(p_New) = p_Head;
+ NCSW_LIST_PREV(p_Head) = p_New;
+}
+
+
+/**************************************************************************//**
+ @Function LIST_Del
+
+ @Description Deletes entry from a list.
+
+ @Param[in] p_Entry - A pointer to the element to delete from the list.
+
+ @Return none.
+
+ @Cautions LIST_IsEmpty() on entry does not return true after this,
+ the entry is in an undefined state.
+*//***************************************************************************/
+static __inline__ void LIST_Del(t_List *p_Entry)
+{
+ NCSW_LIST_PREV(NCSW_LIST_NEXT(p_Entry)) = NCSW_LIST_PREV(p_Entry);
+ NCSW_LIST_NEXT(NCSW_LIST_PREV(p_Entry)) = NCSW_LIST_NEXT(p_Entry);
+}
+
+
+/**************************************************************************//**
+ @Function LIST_DelAndInit
+
+ @Description Deletes entry from list and reinitialize it.
+
+ @Param[in] p_Entry - A pointer to the element to delete from the list.
+
+ @Return none.
+*//***************************************************************************/
+static __inline__ void LIST_DelAndInit(t_List *p_Entry)
+{
+ LIST_Del(p_Entry);
+ INIT_LIST(p_Entry);
+}
+
+
+/**************************************************************************//**
+ @Function LIST_Move
+
+ @Description Delete from one list and add as another's head.
+
+ @Param[in] p_Entry - A pointer to the list entry to move.
+ @Param[in] p_Head - A pointer to the list head that will precede our entry.
+
+ @Return none.
+*//***************************************************************************/
+static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
+{
+ LIST_Del(p_Entry);
+ LIST_Add(p_Entry, p_Head);
+}
+
+
+/**************************************************************************//**
+ @Function LIST_MoveToTail
+
+ @Description Delete from one list and add as another's tail.
+
+ @Param[in] p_Entry - A pointer to the entry to move.
+ @Param[in] p_Head - A pointer to the list head that will follow our entry.
+
+ @Return none.
+*//***************************************************************************/
+static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
+{
+ LIST_Del(p_Entry);
+ LIST_AddToTail(p_Entry, p_Head);
+}
+
+
+/**************************************************************************//**
+ @Function LIST_IsEmpty
+
+ @Description Tests whether a list is empty.
+
+ @Param[in] p_List - A pointer to the list to test.
+
+ @Return 1 if the list is empty, 0 otherwise.
+*//***************************************************************************/
+static __inline__ int LIST_IsEmpty(t_List *p_List)
+{
+ return (NCSW_LIST_FIRST(p_List) == p_List);
+}
+
+
+/**************************************************************************//**
+ @Function LIST_Append
+
+ @Description Join two lists.
+
+ @Param[in] p_NewList - A pointer to the new list to add.
+ @Param[in] p_Head - A pointer to the place to add it in the first list.
+
+ @Return none.
+*//***************************************************************************/
+void LIST_Append(t_List *p_NewList, t_List *p_Head);
+
+
+/**************************************************************************//**
+ @Function LIST_NumOfObjs
+
+ @Description Counts number of objects in the list
+
+ @Param[in] p_List - A pointer to the list which objects are to be counted.
+
+ @Return Number of objects in the list.
+*//***************************************************************************/
+int LIST_NumOfObjs(t_List *p_List);
+
+/** @} */ /* end of list_id group */
+/** @} */ /* end of etc_id group */
+
+
+#endif /* __LIST_EXT_H */
diff --git a/sys/contrib/ncsw/inc/etc/mem_ext.h b/sys/contrib/ncsw/inc/etc/mem_ext.h
new file mode 100644
index 0000000..16592d5
--- /dev/null
+++ b/sys/contrib/ncsw/inc/etc/mem_ext.h
@@ -0,0 +1,317 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+
+ @File mem_ext.h
+
+ @Description External prototypes for the memory manager object
+*//***************************************************************************/
+
+#ifndef __MEM_EXT_H
+#define __MEM_EXT_H
+
+#include "std_ext.h"
+#include "part_ext.h"
+
+
+/**************************************************************************//**
+ @Group etc_id Utility Library Application Programming Interface
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group mem_id Slab Memory Manager
+
+ @Description Slab Memory Manager module functions, definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/* Each block is of the following structure:
+ *
+ *
+ * +-----------+----------+---------------------------+-----------+-----------+
+ * | Alignment | Prefix | Data | Postfix | Alignment |
+ * | field | field | field | field | Padding |
+ * | | | | | |
+ * +-----------+----------+---------------------------+-----------+-----------+
+ * and at the beginning of all bytes, an additional optional padding might reside
+ * to ensure that the first blocks data field is aligned as requested.
+ */
+
+
+#define MEM_MAX_NAME_LENGTH 8
+
+/**************************************************************************//*
+ @Description Memory Segment structure
+*//***************************************************************************/
+
+typedef struct
+{
+ char name[MEM_MAX_NAME_LENGTH];
+ /* The segment's name */
+ uint8_t **p_Bases; /* Base addresses of the segments */
+ uint8_t **p_BlocksStack; /* Array of pointers to blocks */
+ t_Handle h_Spinlock;
+ uint16_t dataSize; /* Size of each data block */
+ uint16_t prefixSize; /* How many bytes to reserve before the data */
+ uint16_t postfixSize; /* How many bytes to reserve after the data */
+ uint16_t alignment; /* Requested alignment for the data field */
+ int allocOwner; /* Memory allocation owner */
+ uint32_t getFailures; /* Number of times get failed */
+ uint32_t num; /* Number of blocks in segment */
+ uint32_t current; /* Current block */
+ bool consecutiveMem; /* Allocate consecutive data blocks memory */
+#ifdef DEBUG_MEM_LEAKS
+ void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
+ uint32_t blockOffset;
+ uint32_t blockSize;
+#endif /* DEBUG_MEM_LEAKS */
+} t_MemorySegment;
+
+
+
+/**************************************************************************//**
+ @Function MEM_Init
+
+ @Description Create a new memory segment.
+
+ @Param[in] name - Name of memory partition.
+ @Param[in] p_Handle - Handle to new segment is returned through here.
+ @Param[in] num - Number of blocks in new segment.
+ @Param[in] dataSize - Size of blocks in segment.
+ @Param[in] prefixSize - How many bytes to allocate before the data.
+ @Param[in] postfixSize - How many bytes to allocate after the data.
+ @Param[in] alignment - Requested alignment for data field (in bytes).
+
+ @Return E_OK - success, E_NO_MEMORY - out of memory.
+*//***************************************************************************/
+t_Error MEM_Init(char name[],
+ t_Handle *p_Handle,
+ uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment);
+
+/**************************************************************************//**
+ @Function MEM_InitSmart
+
+ @Description Create a new memory segment.
+
+ @Param[in] name - Name of memory partition.
+ @Param[in] p_Handle - Handle to new segment is returned through here.
+ @Param[in] num - Number of blocks in new segment.
+ @Param[in] dataSize - Size of blocks in segment.
+ @Param[in] prefixSize - How many bytes to allocate before the data.
+ @Param[in] postfixSize - How many bytes to allocate after the data.
+ @Param[in] alignment - Requested alignment for data field (in bytes).
+ @Param[in] memPartitionId - Memory partition ID for allocation.
+ @Param[in] consecutiveMem - Whether to allocate the memory blocks
+ continuously or not.
+
+ @Return E_OK - success, E_NO_MEMORY - out of memory.
+*//***************************************************************************/
+t_Error MEM_InitSmart(char name[],
+ t_Handle *p_Handle,
+ uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment,
+ uint8_t memPartitionId,
+ bool consecutiveMem);
+
+/**************************************************************************//**
+ @Function MEM_InitByAddress
+
+ @Description Create a new memory segment with a specified base address.
+
+ @Param[in] name - Name of memory partition.
+ @Param[in] p_Handle - Handle to new segment is returned through here.
+ @Param[in] num - Number of blocks in new segment.
+ @Param[in] dataSize - Size of blocks in segment.
+ @Param[in] prefixSize - How many bytes to allocate before the data.
+ @Param[in] postfixSize - How many bytes to allocate after the data.
+ @Param[in] alignment - Requested alignment for data field (in bytes).
+ @Param[in] address - The required base address.
+
+ @Return E_OK - success, E_NO_MEMORY - out of memory.
+ *//***************************************************************************/
+t_Error MEM_InitByAddress(char name[],
+ t_Handle *p_Handle,
+ uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment,
+ uint8_t *address);
+
+/**************************************************************************//**
+ @Function MEM_Free
+
+ @Description Free a specific memory segment.
+
+ @Param[in] h_Mem - Handle to memory segment.
+
+ @Return None.
+*//***************************************************************************/
+void MEM_Free(t_Handle h_Mem);
+
+/**************************************************************************//**
+ @Function MEM_Get
+
+ @Description Get a block of memory from a segment.
+
+ @Param[in] h_Mem - Handle to memory segment.
+
+ @Return Pointer to new memory block on success,0 otherwise.
+*//***************************************************************************/
+void * MEM_Get(t_Handle h_Mem);
+
+/**************************************************************************//**
+ @Function MEM_GetN
+
+ @Description Get up to N blocks of memory from a segment.
+
+ The blocks are assumed to be of a fixed size (one size per segment).
+
+ @Param[in] h_Mem - Handle to memory segment.
+ @Param[in] num - Number of blocks to allocate.
+ @Param[out] array - Array of at least num pointers to which the addresses
+ of the allocated blocks are written.
+
+ @Return The number of blocks actually allocated.
+
+ @Cautions Interrupts are disabled for all of the allocation loop.
+ Although this loop is very short for each block (several machine
+ instructions), you should not allocate a very large number
+ of blocks via this routine.
+*//***************************************************************************/
+uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
+
+/**************************************************************************//**
+ @Function MEM_Put
+
+ @Description Put a block of memory back to a segment.
+
+ @Param[in] h_Mem - Handle to memory segment.
+ @Param[in] p_Block - The block to return.
+
+ @Return Pointer to new memory block on success,0 otherwise.
+*//***************************************************************************/
+t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
+
+/**************************************************************************//**
+ @Function MEM_ComputePartitionSize
+
+ @Description calculate a tight upper boundary of the size of a partition with
+ given attributes.
+
+ The returned value is suitable if one wants to use MEM_InitByAddress().
+
+ @Param[in] num - The number of blocks in the segment.
+ @Param[in] dataSize - Size of block to get.
+ @Param[in] prefixSize - The prefix size
+ @Param postfixSize - The postfix size
+ @Param[in] alignment - The requested alignment value (in bytes)
+
+ @Return The memory block size a segment with the given attributes needs.
+*//***************************************************************************/
+uint32_t MEM_ComputePartitionSize(uint32_t num,
+ uint16_t dataSize,
+ uint16_t prefixSize,
+ uint16_t postfixSize,
+ uint16_t alignment);
+
+#ifdef DEBUG_MEM_LEAKS
+#if !(defined(__MWERKS__) && (__dest_os == __ppc_eabi))
+#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
+#endif /* !(defined(__MWERKS__) && ... */
+
+/**************************************************************************//**
+ @Function MEM_CheckLeaks
+
+ @Description Report MEM object leaks.
+
+ This routine is automatically called by the MEM_Free() routine,
+ but it can also be invoked while the MEM object is alive.
+
+ @Param[in] h_Mem - Handle to memory segment.
+
+ @Return None.
+*//***************************************************************************/
+void MEM_CheckLeaks(t_Handle h_Mem);
+
+#else /* not DEBUG_MEM_LEAKS */
+#define MEM_CheckLeaks(h_Mem)
+#endif /* not DEBUG_MEM_LEAKS */
+
+/**************************************************************************//**
+ @Description Get base of MEM
+*//***************************************************************************/
+#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
+
+/**************************************************************************//**
+ @Description Get size of MEM block
+*//***************************************************************************/
+#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
+
+/**************************************************************************//**
+ @Description Get prefix size of MEM block
+*//***************************************************************************/
+#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
+
+/**************************************************************************//**
+ @Description Get postfix size of MEM block
+*//***************************************************************************/
+#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
+
+/**************************************************************************//**
+ @Description Get alignment of MEM block (in bytes)
+*//***************************************************************************/
+#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
+
+/**************************************************************************//**
+ @Description Get the number of blocks in the segment
+*//***************************************************************************/
+#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
+
+/** @} */ /* end of MEM group */
+/** @} */ /* end of etc_id group */
+
+
+#endif /* __MEM_EXT_H */
diff --git a/sys/contrib/ncsw/inc/etc/memcpy_ext.h b/sys/contrib/ncsw/inc/etc/memcpy_ext.h
new file mode 100644
index 0000000..e50c8a9
--- /dev/null
+++ b/sys/contrib/ncsw/inc/etc/memcpy_ext.h
@@ -0,0 +1,173 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+
+ @File memcpy_ext.h
+
+ @Description Efficient functions for copying and setting blocks of memory.
+*//***************************************************************************/
+
+#ifndef __MEMCPY_EXT_H
+#define __MEMCPY_EXT_H
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group etc_id Utility Library Application Programming Interface
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group mem_cpy Memory Copy
+
+ @Description Memory Copy module functions,definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function MemCpy32
+
+ @Description Copies one memory buffer into another one in 4-byte chunks!
+ Which should be more efficient than byte by byte.
+
+ For large buffers (over 60 bytes) this function is about 4 times
+ more efficient than the trivial memory copy. For short buffers
+ it is reduced to the trivial copy and may be a bit worse.
+
+ @Param[in] pDst - The address of the destination buffer.
+ @Param[in] pSrc - The address of the source buffer.
+ @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
+
+ @Return pDst (the address of the destination buffer).
+
+ @Cautions There is no parameter or boundary checking! It is up to the user
+ to supply non-null parameters as source & destination and size
+ that actually fits into the destination buffer.
+*//***************************************************************************/
+void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
+void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
+void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
+void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
+
+/**************************************************************************//**
+ @Function MemCpy64
+
+ @Description Copies one memory buffer into another one in 8-byte chunks!
+ Which should be more efficient than byte by byte.
+
+ For large buffers (over 60 bytes) this function is about 8 times
+ more efficient than the trivial memory copy. For short buffers
+ it is reduced to the trivial copy and may be a bit worse.
+
+ Some testing suggests that MemCpy32() preforms better than
+ MemCpy64() over small buffers. On average they break even at
+ 100 byte buffers. For buffers larger than that MemCpy64 is
+ superior.
+
+ @Param[in] pDst - The address of the destination buffer.
+ @Param[in] pSrc - The address of the source buffer.
+ @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
+
+ @Return pDst (the address of the destination buffer).
+
+ @Cautions There is no parameter or boundary checking! It is up to the user
+ to supply non null parameters as source & destination and size
+ that actually fits into their buffer.
+
+ Do not use under Linux.
+*//***************************************************************************/
+void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
+
+/**************************************************************************//**
+ @Function MemSet32
+
+ @Description Sets all bytes of a memory buffer to a specific value, in
+ 4-byte chunks.
+
+ @Param[in] pDst - The address of the destination buffer.
+ @Param[in] val - Value to set destination bytes to.
+ @Param[in] size - The number of bytes that will be set to val.
+
+ @Return pDst (the address of the destination buffer).
+
+ @Cautions There is no parameter or boundary checking! It is up to the user
+ to supply non null parameter as destination and size
+ that actually fits into the destination buffer.
+*//***************************************************************************/
+void * MemSet32(void* pDst, uint8_t val, uint32_t size);
+void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
+
+/**************************************************************************//**
+ @Function MemSet64
+
+ @Description Sets all bytes of a memory buffer to a specific value, in
+ 8-byte chunks.
+
+ @Param[in] pDst - The address of the destination buffer.
+ @Param[in] val - Value to set destination bytes to.
+ @Param[in] size - The number of bytes that will be set to val.
+
+ @Return pDst (the address of the destination buffer).
+
+ @Cautions There is no parameter or boundary checking! It is up to the user
+ to supply non null parameter as destination and size
+ that actually fits into the destination buffer.
+*//***************************************************************************/
+void * MemSet64(void* pDst, uint8_t val, uint32_t size);
+
+/**************************************************************************//**
+ @Function MemDisp
+
+ @Description Displays a block of memory in chunks of 32 bits.
+
+ @Param[in] addr - The address of the memory to display.
+ @Param[in] size - The number of bytes that will be displayed.
+
+ @Return None.
+
+ @Cautions There is no parameter or boundary checking! It is up to the user
+ to supply non null parameter as destination and size
+ that actually fits into the destination buffer.
+*//***************************************************************************/
+void MemDisp(uint8_t *addr, int size);
+
+/** @} */ /* end of mem_cpy group */
+/** @} */ /* end of etc_id group */
+
+
+#endif /* __MEMCPY_EXT_H */
diff --git a/sys/contrib/ncsw/inc/etc/mm_ext.h b/sys/contrib/ncsw/inc/etc/mm_ext.h
new file mode 100644
index 0000000..030f877
--- /dev/null
+++ b/sys/contrib/ncsw/inc/etc/mm_ext.h
@@ -0,0 +1,300 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**************************************************************************//**
+
+ @File mm_ext.h
+
+ @Description Memory Manager Application Programming Interface
+*//***************************************************************************/
+#ifndef __MM_EXT
+#define __MM_EXT
+
+#include "std_ext.h"
+
+#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
+ where maximum alignment defined as
+ MM_MAX_ALIGNMENT power of 2 */
+
+#define MM_MAX_NAME_LEN 32
+
+/**************************************************************************//**
+ @Group etc_id Utility Library Application Programming Interface
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group mm_grp Flexible Memory Manager
+
+ @Description Flexible Memory Manager module functions,definitions and enums.
+ (All of the following functions,definitions and enums can be found in mm_ext.h)
+
+ @{
+*//***************************************************************************/
+
+
+/**************************************************************************//**
+ @Function MM_Init
+
+ @Description Initializes a new MM object.
+
+ It initializes a new memory block consisting of base address
+ and size of the available memory by calling to MemBlock_Init
+ routine. It is also initializes a new free block for each
+ by calling FreeBlock_Init routine, which is pointed to
+ the almost all memory started from the required alignment
+ from the base address and to the end of the memory.
+ The handle to the new MM object is returned via "MM"
+ argument (passed by reference).
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] base - Base address of the MM.
+ @Param[in] size - Size of the MM.
+
+ @Return E_OK is returned on success. E_NOMEMORY is returned if the new MM object or a new free block can not be initialized.
+*//***************************************************************************/
+t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
+
+/**************************************************************************//**
+ @Function MM_Get
+
+ @Description Allocates a block of memory according to the given size and the alignment.
+
+ The Alignment argument tells from which
+ free list allocate a block of memory. 2^alignment indicates
+ the alignment that the base address of the allocated block
+ should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
+ are available for the alignment argument.
+ The routine passes through the specific free list of free
+ blocks and seeks for a first block that have anough memory
+ that is required (best fit).
+ After the block is found and data is allocated, it calls
+ the internal MM_CutFree routine to update all free lists
+ do not include a just allocated block. Of course, each
+ free list contains a free blocks with the same alignment.
+ It is also creates a busy block that holds
+ information about an allocated block.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] size - Size of the MM.
+ @Param[in] alignment - Index as a power of two defines a required
+ alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
+ @Param[in] name - The name that specifies an allocated block.
+
+ @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
+*//***************************************************************************/
+uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
+
+/**************************************************************************//**
+ @Function MM_GetBase
+
+ @Description Gets the base address of the required MM objects.
+
+ @Param[in] h_MM - Handle to the MM object.
+
+ @Return base address of the block.
+*//***************************************************************************/
+uint64_t MM_GetBase(t_Handle h_MM);
+
+/**************************************************************************//**
+ @Function MM_GetForce
+
+ @Description Force memory allocation.
+
+ It means to allocate a block of memory of the given
+ size from the given base address.
+ The routine checks if the required block can be allocated
+ (that is it is free) and then, calls the internal MM_CutFree
+ routine to update all free lists do not include that block.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] base - Base address of the MM.
+ @Param[in] size - Size of the MM.
+ @Param[in] name - Name that specifies an allocated block.
+
+ @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
+*//***************************************************************************/
+uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
+
+/**************************************************************************//**
+ @Function MM_GetForceMin
+
+ @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
+
+ The Alignment argument tells from which
+ free list allocate a block of memory. 2^alignment indicates
+ the alignment that the base address of the allocated block
+ should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
+ are available for the alignment argument.
+ The minimum baser address forces the location of the block
+ to be from a given address onward.
+ The routine passes through the specific free list of free
+ blocks and seeks for the first base address equal or smaller
+ than the required minimum address and end address larger than
+ than the required base + its size - i.e. that may contain
+ the required block.
+ After the block is found and data is allocated, it calls
+ the internal MM_CutFree routine to update all free lists
+ do not include a just allocated block. Of course, each
+ free list contains a free blocks with the same alignment.
+ It is also creates a busy block that holds
+ information about an allocated block.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] size - Size of the MM.
+ @Param[in] alignment - Index as a power of two defines a required
+ alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
+ @Param[in] min - The minimum base address of the block.
+ @Param[in] name - Name that specifies an allocated block.
+
+ @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
+*//***************************************************************************/
+uint64_t MM_GetForceMin(t_Handle h_MM,
+ uint64_t size,
+ uint64_t alignment,
+ uint64_t min,
+ char *name);
+
+/**************************************************************************//**
+ @Function MM_Put
+
+ @Description Puts a block of memory of the given base address back to the memory.
+
+ It checks if there is a busy block with the
+ given base address. If not, it returns 0, that
+ means can't free a block. Otherwise, it gets parameters of
+ the busy block and after it updates lists of free blocks,
+ removes that busy block from the list by calling to MM_CutBusy
+ routine.
+ After that it calls to MM_AddFree routine to add a new free
+ block to the free lists.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] base - Base address of the MM.
+
+ @Return The size of bytes released, 0 if failed.
+*//***************************************************************************/
+uint64_t MM_Put(t_Handle h_MM, uint64_t base);
+
+/**************************************************************************//**
+ @Function MM_PutForce
+
+ @Description Releases a block of memory of the required size from the required base address.
+
+ First, it calls to MM_CutBusy routine
+ to cut a free block from the busy list. And then, calls to
+ MM_AddFree routine to add the free block to the free lists.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] base - Base address of of a block to free.
+ @Param[in] size - Size of a block to free.
+
+ @Return The number of bytes released, 0 on failure.
+*//***************************************************************************/
+uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
+
+/**************************************************************************//**
+ @Function MM_Add
+
+ @Description Adds a new memory block for memory allocation.
+
+ When a new memory block is initialized and added to the
+ memory list, it calls to MM_AddFree routine to add the
+ new free block to the free lists.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] base - Base address of the memory block.
+ @Param[in] size - Size of the memory block.
+
+ @Return E_OK on success, otherwise returns an error code.
+*//***************************************************************************/
+t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
+
+/**************************************************************************//**
+ @Function MM_Dump
+
+ @Description Prints results of free and busy lists into the file.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] buff - A pointer to a buffer
+*//***************************************************************************/
+void MM_Dump(t_Handle h_MM, void *buff);
+
+/**************************************************************************//**
+ @Function MM_Free
+
+ @Description Releases memory allocated for MM object.
+
+ @Param[in] h_MM - Handle of the MM object.
+*//***************************************************************************/
+void MM_Free(t_Handle h_MM);
+
+/**************************************************************************//**
+ @Function MM_GetMemBlock
+
+ @Description Returns base address of the memory block specified by the index.
+
+ If index is 0, returns base address
+ of the first memory block, 1 - returns base address
+ of the second memory block, etc.
+ Note, those memory blocks are allocated by the
+ application before MM_Init or MM_Add and have to
+ be released by the application before or after invoking
+ the MM_Free routine.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] index - Index of the memory block.
+
+ @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
+*//***************************************************************************/
+uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
+
+/**************************************************************************//**
+ @Function MM_InRange
+
+ @Description Checks if a specific address is in the memory range of the passed MM object.
+
+ @Param[in] h_MM - Handle to the MM object.
+ @Param[in] addr - The address to be checked.
+
+ @Return TRUE if the address is in the address range of the block, FALSE otherwise.
+*//***************************************************************************/
+bool MM_InRange(t_Handle h_MM, uint64_t addr);
+
+
+/** @} */ /* end of mm_grp group */
+/** @} */ /* end of etc_id group */
+
+#endif /* __MM_EXT_H */
diff --git a/sys/contrib/ncsw/inc/etc/sprint_ext.h b/sys/contrib/ncsw/inc/etc/sprint_ext.h
new file mode 100644
index 0000000..e94fac0
--- /dev/null
+++ b/sys/contrib/ncsw/inc/etc/sprint_ext.h
@@ -0,0 +1,130 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/******************************************************************************
+
+ @File sprint_ext.h
+
+ @Description Debug routines (externals).
+
+*//***************************************************************************/
+
+#ifndef __SPRINT_EXT_H
+#define __SPRINT_EXT_H
+
+
+#if defined(NCSW_LINUX) && defined(__KERNEL__)
+#include <linux/kernel.h>
+
+#elif defined(NCSW_LINUX_USD)
+#include <stdio.h>
+#include "stdarg_ext.h"
+#include "std_ext.h"
+
+extern int vsscanf(const char *, const char *, va_list);
+
+#elif defined(NCSW_VXWORKS)
+#include "private/stdioP.h"
+
+#elif defined(NCSW_FREEBSD)
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+
+#else
+#include <stdio.h>
+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Group etc_id Utility Library Application Programming Interface
+
+ @Description External routines.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Group sprint_id Sprint
+
+ @Description Sprint & Sscan module functions,definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Function Sprint
+
+ @Description Format a string and place it in a buffer.
+
+ @Param[in] buff - The buffer to place the result into.
+ @Param[in] str - The format string to use.
+ @Param[in] ... - Arguments for the format string.
+
+ @Return Number of bytes formatted.
+*//***************************************************************************/
+int Sprint(char *buff, const char *str, ...);
+
+/**************************************************************************//**
+ @Function Snprint
+
+ @Description Format a string and place it in a buffer.
+
+ @Param[in] buf - The buffer to place the result into.
+ @Param[in] size - The size of the buffer, including the trailing null space.
+ @Param[in] fmt - The format string to use.
+ @Param[in] ... - Arguments for the format string.
+
+ @Return Number of bytes formatted.
+*//***************************************************************************/
+int Snprint(char * buf, uint32_t size, const char *fmt, ...);
+
+/**************************************************************************//**
+ @Function Sscan
+
+ @Description Unformat a buffer into a list of arguments.
+
+ @Param[in] buf - input buffer.
+ @Param[in] fmt - formatting of buffer.
+ @Param[out] ... - resulting arguments.
+
+ @Return Number of bytes unformatted.
+*//***************************************************************************/
+int Sscan(const char * buf, const char * fmt, ...);
+
+/** @} */ /* end of sprint_id group */
+/** @} */ /* end of etc_id group */
+
+
+#endif /* __SPRINT_EXT_H */
diff --git a/sys/contrib/ncsw/inc/integrations/P2041/dpaa_integration_ext.h b/sys/contrib/ncsw/inc/integrations/P2041/dpaa_integration_ext.h
new file mode 100644
index 0000000..f94fa70
--- /dev/null
+++ b/sys/contrib/ncsw/inc/integrations/P2041/dpaa_integration_ext.h
@@ -0,0 +1,349 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ **************************************************************************/
+/**
+
+ @File dpaa_integration_ext.h
+
+ @Description P2041 FM external definitions and structures.
+*//***************************************************************************/
+#ifndef __DPAA_INTEGRATION_EXT_H
+#define __DPAA_INTEGRATION_EXT_H
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Description DPAA SW Portals Enumeration.
+*//***************************************************************************/
+typedef enum
+{
+ e_DPAA_SWPORTAL0 = 0,
+ e_DPAA_SWPORTAL1,
+ e_DPAA_SWPORTAL2,
+ e_DPAA_SWPORTAL3,
+ e_DPAA_SWPORTAL4,
+ e_DPAA_SWPORTAL5,
+ e_DPAA_SWPORTAL6,
+ e_DPAA_SWPORTAL7,
+ e_DPAA_SWPORTAL8,
+ e_DPAA_SWPORTAL9,
+ e_DPAA_SWPORTAL_DUMMY_LAST
+} e_DpaaSwPortal;
+
+/**************************************************************************//**
+ @Description DPAA Direct Connect Portals Enumeration.
+*//***************************************************************************/
+typedef enum
+{
+ e_DPAA_DCPORTAL0 = 0,
+ e_DPAA_DCPORTAL1,
+ e_DPAA_DCPORTAL2,
+ e_DPAA_DCPORTAL3,
+ e_DPAA_DCPORTAL4,
+ e_DPAA_DCPORTAL_DUMMY_LAST
+} e_DpaaDcPortal;
+
+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
+
+/*****************************************************************************
+ QMan INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
+#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
+#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
+#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
+ /**< FQIDs range - 24 bits */
+
+/**************************************************************************//**
+ @Description Work Queue Channel assignments in QMan.
+*//***************************************************************************/
+typedef enum
+{
+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
+ e_QM_FQ_CHANNEL_SWPORTAL1,
+ e_QM_FQ_CHANNEL_SWPORTAL2,
+ e_QM_FQ_CHANNEL_SWPORTAL3,
+ e_QM_FQ_CHANNEL_SWPORTAL4,
+ e_QM_FQ_CHANNEL_SWPORTAL5,
+ e_QM_FQ_CHANNEL_SWPORTAL6,
+ e_QM_FQ_CHANNEL_SWPORTAL7,
+ e_QM_FQ_CHANNEL_SWPORTAL8,
+ e_QM_FQ_CHANNEL_SWPORTAL9,
+
+ e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
+ e_QM_FQ_CHANNEL_POOL2,
+ e_QM_FQ_CHANNEL_POOL3,
+ e_QM_FQ_CHANNEL_POOL4,
+ e_QM_FQ_CHANNEL_POOL5,
+ e_QM_FQ_CHANNEL_POOL6,
+ e_QM_FQ_CHANNEL_POOL7,
+ e_QM_FQ_CHANNEL_POOL8,
+ e_QM_FQ_CHANNEL_POOL9,
+ e_QM_FQ_CHANNEL_POOL10,
+ e_QM_FQ_CHANNEL_POOL11,
+ e_QM_FQ_CHANNEL_POOL12,
+ e_QM_FQ_CHANNEL_POOL13,
+ e_QM_FQ_CHANNEL_POOL14,
+ e_QM_FQ_CHANNEL_POOL15,
+
+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
+ connected to FMan 0; assigned in incrementing order to
+ each sub-portal (SP) in the portal */
+ e_QM_FQ_CHANNEL_FMAN0_SP1,
+ e_QM_FQ_CHANNEL_FMAN0_SP2,
+ e_QM_FQ_CHANNEL_FMAN0_SP3,
+ e_QM_FQ_CHANNEL_FMAN0_SP4,
+ e_QM_FQ_CHANNEL_FMAN0_SP5,
+ e_QM_FQ_CHANNEL_FMAN0_SP6,
+ e_QM_FQ_CHANNEL_FMAN0_SP7,
+ e_QM_FQ_CHANNEL_FMAN0_SP8,
+ e_QM_FQ_CHANNEL_FMAN0_SP9,
+ e_QM_FQ_CHANNEL_FMAN0_SP10,
+ e_QM_FQ_CHANNEL_FMAN0_SP11,
+
+ e_QM_FQ_CHANNEL_RMAN_SP2 = 0x62, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
+ e_QM_FQ_CHANNEL_RMAN_SP3,
+
+ e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
+ connected to SEC 4.x */
+
+ e_QM_FQ_CHANNEL_PME = 0xA0 /**< Dedicated channel serviced by Direct Connect Portal 3:
+ connected to PME */
+} e_QmFQChannel;
+
+/*****************************************************************************
+ BMan INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
+
+/*****************************************************************************
+ SEC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define SEC_NUM_OF_DECOS 2
+#define SEC_ALL_DECOS_MASK 0x00000003
+
+/*****************************************************************************
+ FM INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define INTG_MAX_NUM_OF_FM 1
+
+/* Ports defines */
+#define FM_MAX_NUM_OF_1G_MACS 5
+#define FM_MAX_NUM_OF_10G_MACS 1
+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
+#define FM_MAX_NUM_OF_OH_PORTS 7
+
+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
+
+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
+
+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
+#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
+#define FM_MAX_NUM_OF_SUB_PORTALS 12
+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
+
+/* RAMs defines */
+#define FM_MURAM_SIZE (160 * KILOBYTE)
+#define FM_IRAM_SIZE ( 64 * KILOBYTE)
+
+/* PCD defines */
+#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
+#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
+
+/* RTC defines */
+#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
+#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
+
+/* QMI defines */
+#define QMI_MAX_NUM_OF_TNUMS 64
+#define MAX_QMI_DEQ_SUBPORTAL 12
+#define QMI_DEF_TNUMS_THRESH 48
+
+/* FPM defines */
+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
+
+/* DMA defines */
+#define DMA_THRESH_MAX_COMMQ 31
+#define DMA_THRESH_MAX_BUF 127
+
+/* BMI defines */
+#define BMI_MAX_NUM_OF_TASKS 128
+#define BMI_MAX_NUM_OF_DMAS 32
+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
+#define PORT_MAX_WEIGHT 16 /**< Port weight in BMI arbitration register */
+
+
+/**************************************************************************//**
+ @Description Enum for inter-module interrupts registration
+*//***************************************************************************/
+typedef enum e_FmEventModules
+{
+ e_FM_MOD_PRS, /**< Parser event */
+ e_FM_MOD_KG, /**< Keygen event */
+ e_FM_MOD_PLCR, /**< Policer event */
+ e_FM_MOD_10G_MAC, /**< 10G MAC error event */
+ e_FM_MOD_1G_MAC, /**< 1G MAC error event */
+ e_FM_MOD_TMR, /**< Timer event */
+ e_FM_MOD_1G_MAC_TMR, /**< 1G MAC timer event */
+ e_FM_MOD_FMAN_CTRL, /**< FMAN Controller timer event */
+ e_FM_MOD_DUMMY_LAST
+} e_FmEventModules;
+
+/**************************************************************************//**
+ @Description Enum for interrupts types
+*//***************************************************************************/
+typedef enum e_FmIntrType
+{
+ e_FM_INTR_TYPE_ERR,
+ e_FM_INTR_TYPE_NORMAL
+} e_FmIntrType;
+
+/**************************************************************************//**
+ @Description Enum for inter-module interrupts registration
+*//***************************************************************************/
+typedef enum e_FmInterModuleEvent
+{
+ e_FM_EV_PRS, /**< Parser event */
+ e_FM_EV_ERR_PRS, /**< Parser error event */
+ e_FM_EV_KG, /**< Keygen event */
+ e_FM_EV_ERR_KG, /**< Keygen error event */
+ e_FM_EV_PLCR, /**< Policer event */
+ e_FM_EV_ERR_PLCR, /**< Policer error event */
+ e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
+ e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
+ e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
+ e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
+ e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
+ e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
+ e_FM_EV_TMR, /**< Timer event */
+ e_FM_EV_1G_MAC0_TMR, /**< 1G MAC 0 timer event */
+ e_FM_EV_1G_MAC1_TMR, /**< 1G MAC 1 timer event */
+ e_FM_EV_1G_MAC2_TMR, /**< 1G MAC 2 timer event */
+ e_FM_EV_1G_MAC3_TMR, /**< 1G MAC 3 timer event */
+ e_FM_EV_1G_MAC4_TMR, /**< 1G MAC 4 timer event */
+ e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
+ e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
+ e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
+ e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
+ e_FM_EV_DUMMY_LAST
+} e_FmInterModuleEvent;
+
+#define GET_FM_MODULE_EVENT(mod, id, intrType, event) \
+ switch(mod){ \
+ case e_FM_MOD_PRS: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
+ break; \
+ case e_FM_MOD_KG: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
+ break; \
+ case e_FM_MOD_PLCR: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
+ break; \
+ case e_FM_MOD_10G_MAC: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_10G_MAC0 : e_FM_EV_DUMMY_LAST; \
+ break; \
+ case e_FM_MOD_1G_MAC: \
+ switch(id){ \
+ case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC0 : e_FM_EV_DUMMY_LAST; break; \
+ case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC1 : e_FM_EV_DUMMY_LAST; break; \
+ case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC2 : e_FM_EV_DUMMY_LAST; break; \
+ case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC3 : e_FM_EV_DUMMY_LAST; break; \
+ case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC4 : e_FM_EV_DUMMY_LAST; break; \
+ } \
+ break; \
+ case e_FM_MOD_TMR: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
+ break; \
+ case e_FM_MOD_1G_MAC_TMR: \
+ switch(id){ \
+ case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC0_TMR; break; \
+ case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC1_TMR; break; \
+ case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC2_TMR; break; \
+ case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC3_TMR; break; \
+ case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC4_TMR; break; \
+ } \
+ break; \
+ case e_FM_MOD_FMAN_CTRL: \
+ if (intrType == e_FM_INTR_TYPE_ERR) event = e_FM_EV_DUMMY_LAST; \
+ else switch(id){ \
+ case(0): event = e_FM_EV_FMAN_CTRL_0; break; \
+ case(1): event = e_FM_EV_FMAN_CTRL_1; break; \
+ case(2): event = e_FM_EV_FMAN_CTRL_2; break; \
+ case(3): event = e_FM_EV_FMAN_CTRL_3; break; \
+ } \
+ break; \
+ default: event = e_FM_EV_DUMMY_LAST; \
+ break;}
+
+#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
+
+/* P2041 unique features */
+#define FM_QMI_DEQ_OPTIONS_SUPPORT
+#define FM_NO_DISPATCH_RAM_ECC
+#define FM_FIFO_ALLOCATION_OLD_ALG
+#define FM_NO_WATCHDOG
+#define FM_NO_TNUM_AGING
+#define FM_NO_TGEC_LOOPBACK
+#define FM_KG_NO_BYPASS_FQID_GEN
+#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
+#define FM_NO_BACKUP_POOLS
+#define FM_NO_OP_OBSERVED_POOLS
+#define FM_NO_ADVANCED_RATE_LIMITER
+#define FM_NO_OP_OBSERVED_CGS
+
+/* FM erratas */
+#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
+
+#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
+#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
+
+#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
+
+#define FM_LEN_CHECK_ERRATA_FMAN_SW002
+#define FM_PRS_MEM_ERRATA_FMAN_SW003
+
+#endif /* __DPAA_INTEGRATION_EXT_H */
diff --git a/sys/contrib/ncsw/inc/integrations/P2041/part_integration_ext.h b/sys/contrib/ncsw/inc/integrations/P2041/part_integration_ext.h
new file mode 100644
index 0000000..5a00dfb
--- /dev/null
+++ b/sys/contrib/ncsw/inc/integrations/P2041/part_integration_ext.h
@@ -0,0 +1,758 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ **************************************************************************/
+/**
+
+ @File part_integration_ext.h
+
+ @Description P2041 external definitions and structures.
+*//***************************************************************************/
+#ifndef __PART_INTEGRATION_EXT_H
+#define __PART_INTEGRATION_EXT_H
+
+#include "std_ext.h"
+#include "ddr_std_ext.h"
+#include "enet_ext.h"
+#include "dpaa_integration_ext.h"
+
+
+/**************************************************************************//**
+ @Group P2041_chip_id P2041 Application Programming Interface
+
+ @Description P2041 Chip functions,definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+#define CORE_E500MC
+
+#define INTG_MAX_NUM_OF_CORES 4
+
+
+/**************************************************************************//**
+ @Description Module types.
+*//***************************************************************************/
+typedef enum e_ModuleId
+{
+ e_MODULE_ID_DUART_1 = 0,
+ e_MODULE_ID_DUART_2,
+ e_MODULE_ID_DUART_3,
+ e_MODULE_ID_DUART_4,
+ e_MODULE_ID_LAW,
+ e_MODULE_ID_LBC,
+ e_MODULE_ID_PAMU,
+ e_MODULE_ID_QM, /**< Queue manager module */
+ e_MODULE_ID_BM, /**< Buffer manager module */
+ e_MODULE_ID_QM_CE_PORTAL_0,
+ e_MODULE_ID_QM_CI_PORTAL_0,
+ e_MODULE_ID_QM_CE_PORTAL_1,
+ e_MODULE_ID_QM_CI_PORTAL_1,
+ e_MODULE_ID_QM_CE_PORTAL_2,
+ e_MODULE_ID_QM_CI_PORTAL_2,
+ e_MODULE_ID_QM_CE_PORTAL_3,
+ e_MODULE_ID_QM_CI_PORTAL_3,
+ e_MODULE_ID_QM_CE_PORTAL_4,
+ e_MODULE_ID_QM_CI_PORTAL_4,
+ e_MODULE_ID_QM_CE_PORTAL_5,
+ e_MODULE_ID_QM_CI_PORTAL_5,
+ e_MODULE_ID_QM_CE_PORTAL_6,
+ e_MODULE_ID_QM_CI_PORTAL_6,
+ e_MODULE_ID_QM_CE_PORTAL_7,
+ e_MODULE_ID_QM_CI_PORTAL_7,
+ e_MODULE_ID_QM_CE_PORTAL_8,
+ e_MODULE_ID_QM_CI_PORTAL_8,
+ e_MODULE_ID_QM_CE_PORTAL_9,
+ e_MODULE_ID_QM_CI_PORTAL_9,
+ e_MODULE_ID_BM_CE_PORTAL_0,
+ e_MODULE_ID_BM_CI_PORTAL_0,
+ e_MODULE_ID_BM_CE_PORTAL_1,
+ e_MODULE_ID_BM_CI_PORTAL_1,
+ e_MODULE_ID_BM_CE_PORTAL_2,
+ e_MODULE_ID_BM_CI_PORTAL_2,
+ e_MODULE_ID_BM_CE_PORTAL_3,
+ e_MODULE_ID_BM_CI_PORTAL_3,
+ e_MODULE_ID_BM_CE_PORTAL_4,
+ e_MODULE_ID_BM_CI_PORTAL_4,
+ e_MODULE_ID_BM_CE_PORTAL_5,
+ e_MODULE_ID_BM_CI_PORTAL_5,
+ e_MODULE_ID_BM_CE_PORTAL_6,
+ e_MODULE_ID_BM_CI_PORTAL_6,
+ e_MODULE_ID_BM_CE_PORTAL_7,
+ e_MODULE_ID_BM_CI_PORTAL_7,
+ e_MODULE_ID_BM_CE_PORTAL_8,
+ e_MODULE_ID_BM_CI_PORTAL_8,
+ e_MODULE_ID_BM_CE_PORTAL_9,
+ e_MODULE_ID_BM_CI_PORTAL_9,
+ e_MODULE_ID_FM, /**< Frame manager module */
+ e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
+ e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
+ e_MODULE_ID_FM_BMI, /**< FM BMI block */
+ e_MODULE_ID_FM_QMI, /**< FM QMI block */
+ e_MODULE_ID_FM_PARSER, /**< FM parser block */
+ e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_10GRx, /**< FM Rx 10G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_10GTx, /**< FM Tx 10G MAC port block */
+ e_MODULE_ID_FM_PLCR, /**< FM Policer */
+ e_MODULE_ID_FM_KG, /**< FM Keygen */
+ e_MODULE_ID_FM_DMA, /**< FM DMA */
+ e_MODULE_ID_FM_FPM, /**< FM FPM */
+ e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
+ e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
+ e_MODULE_ID_FM_1GMDIO2, /**< FM 1G MDIO MAC 2*/
+ e_MODULE_ID_FM_1GMDIO3, /**< FM 1G MDIO MAC 3*/
+ e_MODULE_ID_FM_1GMDIO4, /**< FM 1G MDIO MAC 4*/
+ e_MODULE_ID_FM_1GMDIO5, /**< FM 1G MDIO MAC 5*/
+ e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
+ e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
+ e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
+ e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
+ e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
+ e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
+ e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
+ e_MODULE_ID_FM_10GMAC, /**< FM 10G MAC */
+
+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
+
+ e_MODULE_ID_PIC, /**< PIC */
+ e_MODULE_ID_GPIO, /**< GPIO */
+ e_MODULE_ID_SERDES, /**< SERDES */
+ e_MODULE_ID_CPC, /**< CoreNet-Platform-Cache */
+ e_MODULE_ID_DUMMY_LAST
+} e_ModuleId;
+
+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
+
+/* Offsets relative to CCSR base */
+#define P2041_OFFSET_LAW 0x00000c00
+#define P2041_OFFSET_DDR 0x00008000
+#define P2041_OFFSET_CPC 0x00010000
+#define P2041_OFFSET_CCM 0x00018000
+#define P2041_OFFSET_PAMU 0x00020000
+#define P2041_OFFSET_PIC 0x00040000
+#define P2041_OFFSET_GUTIL 0x000e0000
+#define P2041_OFFSET_RCPM 0x000e2000
+#define P2041_OFFSET_SERDES 0x000ea000
+#define P2041_OFFSET_DMA1 0x00100100
+#define P2041_OFFSET_DMA2 0x00101100
+#define P2041_OFFSET_ESPI 0x00110000
+#define P2041_OFFSET_ESDHC 0x00114000
+#define P2041_OFFSET_I2C1 0x00118000
+#define P2041_OFFSET_I2C2 0x00118100
+#define P2041_OFFSET_I2C3 0x00119000
+#define P2041_OFFSET_I2C4 0x00119100
+#define P2041_OFFSET_DUART1 0x0011c500
+#define P2041_OFFSET_DUART2 0x0011c600
+#define P2041_OFFSET_DUART3 0x0011d500
+#define P2041_OFFSET_DUART4 0x0011d600
+#define P2041_OFFSET_LBC 0x00124000
+#define P2041_OFFSET_GPIO 0x00130000
+#define P2041_OFFSET_PCIE1 0x00200000
+#define P2041_OFFSET_PCIE2 0x00201000
+#define P2041_OFFSET_PCIE3 0x00202000
+#define P2041_OFFSET_USB1 0x00210000
+#define P2041_OFFSET_USB2 0x00211000
+#define P2041_OFFSET_USB_PHY 0x00214000
+#define P2041_OFFSET_SATA1 0x00220000
+#define P2041_OFFSET_SATA2 0x00221000
+#define P2041_OFFSET_SEC_GEN 0x00300000
+#define P2041_OFFSET_SEC_JQ0 0x00301000
+#define P2041_OFFSET_SEC_JQ1 0x00302000
+#define P2041_OFFSET_SEC_JQ2 0x00303000
+#define P2041_OFFSET_SEC_JQ3 0x00304000
+#define P2041_OFFSET_SEC_RESERVED 0x00305000
+#define P2041_OFFSET_SEC_RTIC 0x00306000
+#define P2041_OFFSET_SEC_QI 0x00307000
+#define P2041_OFFSET_SEC_DECO0_CCB0 0x00308000
+#define P2041_OFFSET_SEC_DECO1_CCB1 0x00309000
+#define P2041_OFFSET_PME 0x00316000
+#define P2041_OFFSET_QM 0x00318000
+#define P2041_OFFSET_BM 0x0031a000
+#define P2041_OFFSET_FM 0x00400000
+
+#define P2041_OFFSET_FM_MURAM P2041_OFFSET_FM
+#define P2041_OFFSET_FM_BMI (P2041_OFFSET_FM + 0x00080000)
+#define P2041_OFFSET_FM_QMI (P2041_OFFSET_FM + 0x00080400)
+#define P2041_OFFSET_FM_PARSER (P2041_OFFSET_FM + 0x00080800)
+#define P2041_OFFSET_FM_PORT_HO1 (P2041_OFFSET_FM + 0x00081000) /* host command/offline parser */
+#define P2041_OFFSET_FM_PORT_HO2 (P2041_OFFSET_FM + 0x00082000)
+#define P2041_OFFSET_FM_PORT_HO3 (P2041_OFFSET_FM + 0x00083000)
+#define P2041_OFFSET_FM_PORT_HO4 (P2041_OFFSET_FM + 0x00084000)
+#define P2041_OFFSET_FM_PORT_HO5 (P2041_OFFSET_FM + 0x00085000)
+#define P2041_OFFSET_FM_PORT_HO6 (P2041_OFFSET_FM + 0x00086000)
+#define P2041_OFFSET_FM_PORT_HO7 (P2041_OFFSET_FM + 0x00087000)
+#define P2041_OFFSET_FM_PORT_1GRX1 (P2041_OFFSET_FM + 0x00088000)
+#define P2041_OFFSET_FM_PORT_1GRX2 (P2041_OFFSET_FM + 0x00089000)
+#define P2041_OFFSET_FM_PORT_1GRX3 (P2041_OFFSET_FM + 0x0008a000)
+#define P2041_OFFSET_FM_PORT_1GRX4 (P2041_OFFSET_FM + 0x0008b000)
+#define P2041_OFFSET_FM_PORT_1GRX5 (P2041_OFFSET_FM + 0x0008c000)
+#define P2041_OFFSET_FM_PORT_10GRX (P2041_OFFSET_FM + 0x00090000)
+#define P2041_OFFSET_FM_PORT_1GTX1 (P2041_OFFSET_FM + 0x000a8000)
+#define P2041_OFFSET_FM_PORT_1GTX2 (P2041_OFFSET_FM + 0x000a9000)
+#define P2041_OFFSET_FM_PORT_1GTX3 (P2041_OFFSET_FM + 0x000aa000)
+#define P2041_OFFSET_FM_PORT_1GTX4 (P2041_OFFSET_FM + 0x000ab000)
+#define P2041_OFFSET_FM_PORT_1GTX5 (P2041_OFFSET_FM + 0x000ac000)
+#define P2041_OFFSET_FM_PORT_10GTX (P2041_OFFSET_FM + 0x000b0000)
+#define P2041_OFFSET_FM_PLCR (P2041_OFFSET_FM + 0x000c0000)
+#define P2041_OFFSET_FM_KG (P2041_OFFSET_FM + 0x000c1000)
+#define P2041_OFFSET_FM_DMA (P2041_OFFSET_FM + 0x000c2000)
+#define P2041_OFFSET_FM_FPM (P2041_OFFSET_FM + 0x000c3000)
+#define P2041_OFFSET_FM_IRAM (P2041_OFFSET_FM + 0x000c4000)
+#define P2041_OFFSET_FM_PARSER_IRAM (P2041_OFFSET_FM + 0x000c7000)
+#define P2041_OFFSET_FM_1GMAC1 (P2041_OFFSET_FM + 0x000e0000)
+#define P2041_OFFSET_FM_1GMDIO (P2041_OFFSET_FM + 0x000e1000 + 0x120)
+#define P2041_OFFSET_FM_1GMAC2 (P2041_OFFSET_FM + 0x000e2000)
+#define P2041_OFFSET_FM_1GMAC3 (P2041_OFFSET_FM + 0x000e4000)
+#define P2041_OFFSET_FM_1GMAC4 (P2041_OFFSET_FM + 0x000e6000)
+#define P2041_OFFSET_FM_1GMAC5 (P2041_OFFSET_FM + 0x000e8000)
+#define P2041_OFFSET_FM_10GMAC (P2041_OFFSET_FM + 0x000f0000)
+#define P2041_OFFSET_FM_10GMDIO (P2041_OFFSET_FM + 0x000f1000 + 0x030)
+#define P2041_OFFSET_FM_RTC (P2041_OFFSET_FM + 0x000fe000)
+
+/* Offsets relative to QM or BM portals base */
+#define P2041_OFFSET_PORTALS_CE_AREA 0x000000 /* cache enabled area */
+#define P2041_OFFSET_PORTALS_CI_AREA 0x100000 /* cache inhibited area */
+
+#define P2041_CE_PORTAL_SIZE 0x4000
+#define P2041_CI_PORTAL_SIZE 0x1000
+
+#define P2041_OFFSET_PORTALS_CE(portal) \
+ (P2041_OFFSET_PORTALS_CE_AREA + P2041_CE_PORTAL_SIZE * (portal))
+#define P2041_OFFSET_PORTALS_CI(portal) \
+ (P2041_OFFSET_PORTALS_CI_AREA + P2041_CI_PORTAL_SIZE * (portal))
+
+
+/**************************************************************************//**
+ @Description Transaction source ID (for memory conrollers error reporting).
+*//***************************************************************************/
+typedef enum e_TransSrc
+{
+ e_TRANS_SRC_PCIE_1 = 0x0, /**< PCI Express 1 */
+ e_TRANS_SRC_PCIE_2 = 0x1, /**< PCI Express 2 */
+ e_TRANS_SRC_PCIE_3 = 0x2, /**< PCI Express 3 */
+ e_TRANS_SRC_SRIO_1 = 0x8, /**< SRIO 1 */
+ e_TRANS_SRC_SRIO_2 = 0x9, /**< SRIO 2 */
+ e_TRANS_SRC_BMAN = 0x18, /**< BMan */
+ e_TRANS_SRC_PAMU = 0x1C, /**< PAMU */
+ e_TRANS_SRC_PME = 0x20, /**< PME */
+ e_TRANS_SRC_SEC = 0x21, /**< Security engine */
+ e_TRANS_SRC_QMAN = 0x3C, /**< QMan */
+ e_TRANS_SRC_USB_1 = 0x40, /**< USB 1 */
+ e_TRANS_SRC_USB_2 = 0x41, /**< USB 2 */
+ e_TRANS_SRC_ESDHC = 0x44, /**< eSDHC */
+ e_TRANS_SRC_PBL = 0x48, /**< Pre-boot loader */
+ e_TRANS_SRC_NPC = 0x4B, /**< Nexus port controller */
+ e_TRANS_SRC_RMAN = 0x5D, /**< RIO message manager */
+ e_TRANS_SRC_SATA_1 = 0x60, /**< SATA 1 */
+ e_TRANS_SRC_SATA_2 = 0x61, /**< SATA 2 */
+ e_TRANS_SRC_DMA_1 = 0x70, /**< DMA 1 */
+ e_TRANS_SRC_DMA_2 = 0x71, /**< DMA 2 */
+ e_TRANS_SRC_CORE_0_INST = 0x80, /**< Processor 0 (instruction) */
+ e_TRANS_SRC_CORE_0_DATA = 0x81, /**< Processor 0 (data) */
+ e_TRANS_SRC_CORE_1_INST = 0x82, /**< Processor 1 (instruction) */
+ e_TRANS_SRC_CORE_1_DATA = 0x83, /**< Processor 1 (data) */
+ e_TRANS_SRC_CORE_2_INST = 0x84, /**< Processor 2 (instruction) */
+ e_TRANS_SRC_CORE_2_DATA = 0x85, /**< Processor 2 (data) */
+ e_TRANS_SRC_CORE_3_INST = 0x86, /**< Processor 3 (instruction) */
+ e_TRANS_SRC_CORE_3_DATA = 0x87, /**< Processor 3 (data) */
+ e_TRANS_SRC_FM_10G = 0xC0, /**< FM XAUI */
+ e_TRANS_SRC_FM_HO_1 = 0xC1, /**< FM offline, host 1 */
+ e_TRANS_SRC_FM_HO_2 = 0xC2, /**< FM offline, host 2 */
+ e_TRANS_SRC_FM_HO_3 = 0xC3, /**< FM offline, host 3 */
+ e_TRANS_SRC_FM_HO_4 = 0xC4, /**< FM offline, host 4 */
+ e_TRANS_SRC_FM_HO_5 = 0xC5, /**< FM offline, host 5 */
+ e_TRANS_SRC_FM_HO_6 = 0xC6, /**< FM offline, host 6 */
+ e_TRANS_SRC_FM_HO_7 = 0xC7, /**< FM offline, host 7 */
+ e_TRANS_SRC_FM_GETH_1 = 0xC8, /**< FM GETH 1 */
+ e_TRANS_SRC_FM_GETH_2 = 0xC9, /**< FM GETH 2 */
+ e_TRANS_SRC_FM_GETH_3 = 0xCA, /**< FM GETH 3 */
+ e_TRANS_SRC_FM_GETH_4 = 0xCB, /**< FM GETH 4 */
+ e_TRANS_SRC_FM_GETH_5 = 0xCC /**< FM GETH 5 */
+} e_TransSrc;
+
+/**************************************************************************//**
+ @Description Local Access Window Target interface ID
+*//***************************************************************************/
+typedef enum e_P2041LawTargetId
+{
+ e_P2041_LAW_TARGET_PCIE_1 = 0x0, /**< PCI Express 1 */
+ e_P2041_LAW_TARGET_PCIE_2 = 0x1, /**< PCI Express 2 */
+ e_P2041_LAW_TARGET_PCIE_3 = 0x2, /**< PCI Express 3 */
+ e_P2041_LAW_TARGET_SRIO_1 = 0x8, /**< SRIO 1 */
+ e_P2041_LAW_TARGET_SRIO_2 = 0x9, /**< SRIO 2 */
+ e_P2041_LAW_TARGET_DDR_CPC = 0x10, /**< DDR controller or CPC SRAM */
+ e_P2041_LAW_TARGET_BMAN = 0x18, /**< BMAN target interface ID */
+ e_P2041_LAW_TARGET_DCSR = 0x1D, /**< DCSR */
+ e_P2041_LAW_TARGET_LBC = 0x1F, /**< Local Bus target interface ID */
+ e_P2041_LAW_TARGET_QMAN = 0x3C, /**< QMAN target interface ID */
+ e_P2041_LAW_TARGET_NONE = 0xFF /**< None */
+} e_P2041LawTargetId;
+
+/***************************************************************
+ P2041 general routines
+****************************************************************/
+/**************************************************************************//**
+ @Group P2041_init_grp P2041 Initialization Unit
+
+ @Description P2041 initialization unit API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Part ID and revision number
+*//***************************************************************************/
+typedef enum e_P2041DeviceName
+{
+ e_P2041_REV_INVALID = 0x00000000, /**< Invalid revision */
+ e_P2040_REV_1_0 = (int)0x82180010, /**< P2040 with security, revision 1.0 */
+ e_P2040_REV_1_0_NO_SEC = (int)0x82100010, /**< P2040 without security, revision 1.0 */
+ e_P2041_REV_1_0 = (int)0x82180110, /**< P2041 with security, revision 1.0 */
+ e_P2041_REV_1_0_NO_SEC = (int)0x82100110 /**< P2041 without security, revision 1.0 */
+} e_P2041DeviceName;
+
+/**************************************************************************//**
+ @Description Device Disable Register
+*//***************************************************************************/
+typedef enum e_P2041DeviceDisable
+{
+ e_P2041_DEV_DISABLE_PCIE_1 = 0, /**< PCI Express controller 1 disable */
+ e_P2041_DEV_DISABLE_PCIE_2, /**< PCI Express controller 2 disable */
+ e_P2041_DEV_DISABLE_PCIE_3, /**< PCI Express controller 3 disable */
+ e_P2041_DEV_DISABLE_RMAN = 4, /**< RapidIO message manager disable */
+ e_P2041_DEV_DISABLE_SRIO_1, /**< Serial RapidIO controller 1 disable */
+ e_P2041_DEV_DISABLE_SRIO_2, /**< Serial RapidIO controller 2 disable */
+ e_P2041_DEV_DISABLE_DMA_1 = 9, /**< DMA controller 1 disable */
+ e_P2041_DEV_DISABLE_DMA_2, /**< DMA controller 2 disable */
+ e_P2041_DEV_DISABLE_DDR, /**< DDR controller disable */
+ e_P2041_DEV_DISABLE_SATA_1 = 17, /**< SATA controller 1 disable */
+ e_P2041_DEV_DISABLE_SATA_2, /**< SATA controller 2 disable */
+ e_P2041_DEV_DISABLE_LBC, /**< eLBC controller disable */
+ e_P2041_DEV_DISABLE_USB_1, /**< USB controller 1 disable */
+ e_P2041_DEV_DISABLE_USB_2, /**< USB controller 2 disable */
+ e_P2041_DEV_DISABLE_ESDHC = 23, /**< eSDHC controller disable */
+ e_P2041_DEV_DISABLE_GPIO, /**< GPIO controller disable */
+ e_P2041_DEV_DISABLE_ESPI, /**< eSPI controller disable */
+ e_P2041_DEV_DISABLE_I2C_1, /**< I2C module 1 (controllers 1 and 2) disable */
+ e_P2041_DEV_DISABLE_I2C_2, /**< I2C module 2 (controllers 3 and 4) disable */
+ e_P2041_DEV_DISABLE_DUART_1 = 30, /**< DUART controller 1 disable */
+ e_P2041_DEV_DISABLE_DUART_2, /**< DUART controller 2 disable */
+ e_P2041_DEV_DISABLE_DISR1_DUMMY_LAST = 32,
+ /**< Dummy entry signing end of DEVDISR1 register controllers */
+ e_P2041_DEV_DISABLE_PME = e_P2041_DEV_DISABLE_DISR1_DUMMY_LAST,
+ /**< Pattern match engine disable */
+ e_P2041_DEV_DISABLE_SEC, /**< Security disable */
+ e_P2041_DEV_DISABLE_QM_BM = e_P2041_DEV_DISABLE_DISR1_DUMMY_LAST + 4,
+ /**< Queue manager/buffer manager disable */
+ e_P2041_DEV_DISABLE_FM = e_P2041_DEV_DISABLE_DISR1_DUMMY_LAST + 6,
+ /**< Frame manager disable */
+ e_P2041_DEV_DISABLE_10G, /**< 10G Ethernet controller disable */
+ e_P2041_DEV_DISABLE_DTSEC_1,
+ /**< dTSEC controller 1 disable */
+ e_P2041_DEV_DISABLE_DTSEC_2, /**< dTSEC controller 2 disable */
+ e_P2041_DEV_DISABLE_DTSEC_3, /**< dTSEC controller 3 disable */
+ e_P2041_DEV_DISABLE_DTSEC_4, /**< dTSEC controller 4 disable */
+ e_P2041_DEV_DISABLE_DTSEC_5 /**< dTSEC controller 5 disable */
+} e_P2041DeviceDisable;
+
+
+/**************************************************************************//*
+ @Description structure representing P2041 devices configuration
+*//***************************************************************************/
+typedef struct t_P2041Devices
+{
+ struct
+ {
+ struct
+ {
+ bool enabled;
+ uint8_t serdesBank;
+ uint16_t serdesLane; /**< Most significant bits represent lanes used by this bank,
+ one bit for lane, lane A is the first and so on, e.g.,
+ set 0xF000 for ABCD lanes */
+ e_EnetInterface ethIf;
+ uint8_t ratio;
+ bool divByTwo;
+ bool isTwoHalfSgmii;
+ } dtsecs[FM_MAX_NUM_OF_1G_MACS];
+ struct
+ {
+ bool enabled;
+ uint8_t serdesBank;
+ uint16_t serdesLane;
+ } tgec;
+ } fm;
+} t_P2041Devices;
+
+/**************************************************************************//**
+ @Function P2041_GetRevInfo
+
+ @Description Obtain revision information.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return Part ID and revision.
+*//***************************************************************************/
+e_P2041DeviceName P2041_GetRevInfo(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P2041_GetE500Factor
+
+ @Description Obtain core's multiplication factors.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+ @Param[in] coreIndex - Core index.
+ @Param[out] p_E500MulFactor - E500 to CCB multification factor.
+ @Param[out] p_E500DivFactor - E500 to CCB division factor.
+
+*//***************************************************************************/
+void P2041_GetE500Factor(uintptr_t gutilBase,
+ uint8_t coreIndex,
+ uint32_t *p_E500MulFactor,
+ uint32_t *p_E500DivFactor);
+
+/**************************************************************************//**
+ @Function P2041_GetCcbFactor
+
+ @Description Obtain system multiplication factor.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return System multiplication factor.
+*//***************************************************************************/
+uint32_t P2041_GetCcbFactor(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P2041_GetDdrFactor
+
+ @Description Obtain DDR clock multiplication factor.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return DDR clock multiplication factor.
+*//***************************************************************************/
+uint32_t P2041_GetDdrFactor(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P2041_GetDdrType
+
+ @Description Obtain DDR memory type.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return DDR type.
+*//***************************************************************************/
+e_DdrType P2041_GetDdrType(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P2041_GetFmFactor
+
+ @Description returns FM multiplication factors. (This value is returned using
+ two parameters to avoid using float parameter).
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+ @Param[out] p_FmMulFactor - FM to CCB multification factor.
+ @Param[out] p_FmDivFactor - FM to CCB division factor.
+
+*//***************************************************************************/
+void P2041_GetFmFactor(uintptr_t gutilBase,
+ uint32_t *p_FmMulFactor,
+ uint32_t *p_FmDivFactor);
+
+
+void P2041_CoreTimeBaseEnable(uintptr_t rcpmBase);
+void P2041_CoreTimeBaseDisable(uintptr_t rcpmBase);
+
+typedef enum e_SerdesProtocol
+{
+ SRDS_PROTOCOL_NONE = 0,
+ SRDS_PROTOCOL_PCIE1,
+ SRDS_PROTOCOL_PCIE2,
+ SRDS_PROTOCOL_PCIE3,
+ SRDS_PROTOCOL_SRIO1,
+ SRDS_PROTOCOL_SRIO2,
+ SRDS_PROTOCOL_SGMII_FM,
+ SRDS_PROTOCOL_XAUI_FM,
+ SRDS_PROTOCOL_SATA1,
+ SRDS_PROTOCOL_SATA2,
+ SRDS_PROTOCOL_AURORA
+} e_SerdesProtocol;
+
+t_Error P2041_DeviceDisable(uintptr_t gutilBase, e_P2041DeviceDisable device, bool disable);
+void P2041_GetDevicesConfiguration(uintptr_t gutilBase, t_P2041Devices *p_Devices);
+t_Error P2041_PamuDisableBypass(uintptr_t gutilBase, uint8_t pamuId, bool disable);
+void P2041_SetDmaLiodn(uintptr_t gutilBase, uint8_t dmaId, uint16_t liodn);
+uint32_t P2041_SerdesRcwGetProtocol(uintptr_t gutilBase);
+bool P2041_SerdesRcwIsDeviceConfigured(uintptr_t gutilBase, e_SerdesProtocol device);
+bool P2041_SerdesRcwIsLaneEnabled(uintptr_t gutilBase, uint32_t lane);
+
+/** @} */ /* end of P2041_init_grp group */
+/** @} */ /* end of P2041_grp group */
+
+
+/*****************************************************************************
+ INTEGRATION-SPECIFIC MODULE CODES
+******************************************************************************/
+#define MODULE_UNKNOWN 0x00000000
+#define MODULE_MEM 0x00010000
+#define MODULE_MM 0x00020000
+#define MODULE_CORE 0x00030000
+#define MODULE_P2041 0x00040000
+#define MODULE_P2041_PLATFORM 0x00050000
+#define MODULE_PM 0x00060000
+#define MODULE_MMU 0x00070000
+#define MODULE_PIC 0x00080000
+#define MODULE_CPC 0x00090000
+#define MODULE_DUART 0x000a0000
+#define MODULE_SERDES 0x000b0000
+#define MODULE_PIO 0x000c0000
+#define MODULE_QM 0x000d0000
+#define MODULE_BM 0x000e0000
+#define MODULE_SEC 0x000f0000
+#define MODULE_LAW 0x00100000
+#define MODULE_LBC 0x00110000
+#define MODULE_PAMU 0x00120000
+#define MODULE_FM 0x00130000
+#define MODULE_FM_MURAM 0x00140000
+#define MODULE_FM_PCD 0x00150000
+#define MODULE_FM_RTC 0x00160000
+#define MODULE_FM_MAC 0x00170000
+#define MODULE_FM_PORT 0x00180000
+#define MODULE_DPA_PORT 0x00190000
+#define MODULE_MII 0x001a0000
+#define MODULE_I2C 0x001b0000
+#define MODULE_DMA 0x001c0000
+#define MODULE_DDR 0x001d0000
+#define MODULE_ESPI 0x001e0000
+
+/*****************************************************************************
+ PAMU INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define PAMU_NUM_OF_PARTITIONS 4
+
+
+/*****************************************************************************
+ LAW INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define LAW_NUM_OF_WINDOWS 32
+#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
+#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
+
+
+/*****************************************************************************
+ LBC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+/**************************************************************************//**
+ @Group lbc_exception_grp LBC Exception Unit
+
+ @Description LBC Exception unit API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Anchor lbc_exbm
+
+ @Collection LBC Errors Bit Mask
+
+ These errors are reported through the exceptions callback..
+ The values can be or'ed in any combination in the errors mask
+ parameter of the errors report structure.
+
+ These errors can also be passed as a bit-mask to
+ LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
+ for enabling or disabling error checking.
+ @{
+*//***************************************************************************/
+#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
+#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
+#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
+#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
+
+#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
+ LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
+ /**< All possible errors */
+/* @} */
+/** @} */ /* end of lbc_exception_grp group */
+
+#define LBC_INCORRECT_ERROR_REPORT_ERRATA
+
+#define LBC_NUM_OF_BANKS 4
+#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
+#define LBC_PARITY_SUPPORT
+#define LBC_ADDRESS_HOLD_TIME_CTRL
+#define LBC_HIGH_CLK_DIVIDERS
+#define LBC_FCM_AVAILABLE
+
+/*****************************************************************************
+ GPIO INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
+ Each port contains up to 32 I/O pins. */
+
+#define GPIO_VALID_PIN_MASKS \
+ { /* Port A */ 0xFFFFFFFF }
+
+#define GPIO_VALID_INTR_MASKS \
+ { /* Port A */ 0xFFFFFFFF }
+
+
+/*****************************************************************************
+ SERDES INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define SRDS_MAX_LANES 10 /* Lanes C - H on bank 1, lanes A - D on bank 2 */
+#define SRDS_MAX_BANK 2
+
+/* Serdes lanes general information provided in the following form:
+ 1) Lane index in Serdes Control Registers Map
+ 2) Lane enable/disable bit number in RCW
+ 3) Lane bank index */
+#define SRDS_LANES \
+{ \
+ { 2, 154, 0 }, \
+ { 3, 155, 0 }, \
+ { 4, 156, 0 }, \
+ { 5, 157, 0 }, \
+ { 6, 158, 0 }, \
+ { 7, 159, 0 }, \
+ { 16, 162, 1 }, \
+ { 17, 163, 1 }, \
+ { 18, 164, 1 }, \
+ { 19, 165, 1 } \
+}
+
+#define SRDS_PROTOCOL_OPTIONS \
+/* Protocol Lane assignment */ \
+{ \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x02 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x05 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x08 */ {SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x09 */ {SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x0A */ {SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x0F */ {SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x14 */ {SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x16 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x17 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x19 */ {SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x1A */ {SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
+/* 0x1C */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_SGMII_FM, 0, 0} \
+}
+
+
+/*****************************************************************************
+ DDR INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define DDR_NUM_OF_VALID_CS 4
+
+/*****************************************************************************
+ DMA INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define DMA_NUM_OF_CONTROLLERS 2
+
+/*****************************************************************************
+ CPC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+
+#define CPC_MAX_SIZE_SRAM_ERRATA_CPC4
+#define CPC_HARDWARE_FLUSH_ERRATA_CPC10
+
+
+#endif /* __PART_INTEGRATION_EXT_H */
diff --git a/sys/contrib/ncsw/inc/integrations/P3041/dpaa_integration_ext.h b/sys/contrib/ncsw/inc/integrations/P3041/dpaa_integration_ext.h
new file mode 100644
index 0000000..caa4344
--- /dev/null
+++ b/sys/contrib/ncsw/inc/integrations/P3041/dpaa_integration_ext.h
@@ -0,0 +1,371 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ **************************************************************************/
+/**
+
+ @File dpaa_integration_ext.h
+
+ @Description P3041 FM external definitions and structures.
+*//***************************************************************************/
+#ifndef __DPAA_INTEGRATION_EXT_H
+#define __DPAA_INTEGRATION_EXT_H
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Description DPAA SW Portals Enumeration.
+*//***************************************************************************/
+typedef enum
+{
+ e_DPAA_SWPORTAL0 = 0,
+ e_DPAA_SWPORTAL1,
+ e_DPAA_SWPORTAL2,
+ e_DPAA_SWPORTAL3,
+ e_DPAA_SWPORTAL4,
+ e_DPAA_SWPORTAL5,
+ e_DPAA_SWPORTAL6,
+ e_DPAA_SWPORTAL7,
+ e_DPAA_SWPORTAL8,
+ e_DPAA_SWPORTAL9,
+ e_DPAA_SWPORTAL_DUMMY_LAST
+} e_DpaaSwPortal;
+
+/**************************************************************************//**
+ @Description DPAA Direct Connect Portals Enumeration.
+*//***************************************************************************/
+typedef enum
+{
+ e_DPAA_DCPORTAL0 = 0,
+ e_DPAA_DCPORTAL1,
+ e_DPAA_DCPORTAL2,
+ e_DPAA_DCPORTAL3,
+ e_DPAA_DCPORTAL4,
+ e_DPAA_DCPORTAL_DUMMY_LAST
+} e_DpaaDcPortal;
+
+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
+
+/*****************************************************************************
+ QMan INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
+#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
+#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
+#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
+ /**< FQIDs range - 24 bits */
+
+/**************************************************************************//**
+ @Description Work Queue Channel assignments in QMan.
+*//***************************************************************************/
+typedef enum
+{
+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
+ e_QM_FQ_CHANNEL_SWPORTAL1,
+ e_QM_FQ_CHANNEL_SWPORTAL2,
+ e_QM_FQ_CHANNEL_SWPORTAL3,
+ e_QM_FQ_CHANNEL_SWPORTAL4,
+ e_QM_FQ_CHANNEL_SWPORTAL5,
+ e_QM_FQ_CHANNEL_SWPORTAL6,
+ e_QM_FQ_CHANNEL_SWPORTAL7,
+ e_QM_FQ_CHANNEL_SWPORTAL8,
+ e_QM_FQ_CHANNEL_SWPORTAL9,
+
+ e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
+ e_QM_FQ_CHANNEL_POOL2,
+ e_QM_FQ_CHANNEL_POOL3,
+ e_QM_FQ_CHANNEL_POOL4,
+ e_QM_FQ_CHANNEL_POOL5,
+ e_QM_FQ_CHANNEL_POOL6,
+ e_QM_FQ_CHANNEL_POOL7,
+ e_QM_FQ_CHANNEL_POOL8,
+ e_QM_FQ_CHANNEL_POOL9,
+ e_QM_FQ_CHANNEL_POOL10,
+ e_QM_FQ_CHANNEL_POOL11,
+ e_QM_FQ_CHANNEL_POOL12,
+ e_QM_FQ_CHANNEL_POOL13,
+ e_QM_FQ_CHANNEL_POOL14,
+ e_QM_FQ_CHANNEL_POOL15,
+
+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
+ connected to FMan 0; assigned in incrementing order to
+ each sub-portal (SP) in the portal */
+ e_QM_FQ_CHANNEL_FMAN0_SP1,
+ e_QM_FQ_CHANNEL_FMAN0_SP2,
+ e_QM_FQ_CHANNEL_FMAN0_SP3,
+ e_QM_FQ_CHANNEL_FMAN0_SP4,
+ e_QM_FQ_CHANNEL_FMAN0_SP5,
+ e_QM_FQ_CHANNEL_FMAN0_SP6,
+ e_QM_FQ_CHANNEL_FMAN0_SP7,
+ e_QM_FQ_CHANNEL_FMAN0_SP8,
+ e_QM_FQ_CHANNEL_FMAN0_SP9,
+ e_QM_FQ_CHANNEL_FMAN0_SP10,
+ e_QM_FQ_CHANNEL_FMAN0_SP11,
+
+ e_QM_FQ_CHANNEL_RMAN_SP2 = 0x62, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
+ e_QM_FQ_CHANNEL_RMAN_SP3,
+
+ e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
+ connected to SEC 4.x */
+
+ e_QM_FQ_CHANNEL_PME = 0xA0 /**< Dedicated channel serviced by Direct Connect Portal 3:
+ connected to PME */
+} e_QmFQChannel;
+
+/*****************************************************************************
+ BMan INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
+
+/*****************************************************************************
+ FM INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define INTG_MAX_NUM_OF_FM 1
+
+/* Ports defines */
+#define FM_MAX_NUM_OF_1G_MACS 5
+#define FM_MAX_NUM_OF_10G_MACS 1
+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
+#define FM_MAX_NUM_OF_OH_PORTS 7
+
+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
+
+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
+
+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
+#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
+#define FM_MAX_NUM_OF_SUB_PORTALS 12
+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
+
+/* RAMs defines */
+#define FM_MURAM_SIZE (160 * KILOBYTE)
+#define FM_IRAM_SIZE ( 64 * KILOBYTE)
+
+/* PCD defines */
+#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
+#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
+
+/* RTC defines */
+#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
+#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
+
+/* QMI defines */
+#define QMI_MAX_NUM_OF_TNUMS 64
+#define MAX_QMI_DEQ_SUBPORTAL 12
+#define QMI_DEF_TNUMS_THRESH 48
+
+/* FPM defines */
+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
+
+/* DMA defines */
+#define DMA_THRESH_MAX_COMMQ 31
+#define DMA_THRESH_MAX_BUF 127
+
+/* BMI defines */
+#define BMI_MAX_NUM_OF_TASKS 128
+#define BMI_MAX_NUM_OF_DMAS 32
+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
+#define PORT_MAX_WEIGHT 16
+
+
+/**************************************************************************//**
+ @Description Enum for inter-module interrupts registration
+*//***************************************************************************/
+typedef enum e_FmEventModules
+{
+ e_FM_MOD_PRS, /**< Parser event */
+ e_FM_MOD_KG, /**< Keygen event */
+ e_FM_MOD_PLCR, /**< Policer event */
+ e_FM_MOD_10G_MAC, /**< 10G MAC error event */
+ e_FM_MOD_1G_MAC, /**< 1G MAC error event */
+ e_FM_MOD_TMR, /**< Timer event */
+ e_FM_MOD_1G_MAC_TMR, /**< 1G MAC timer event */
+ e_FM_MOD_FMAN_CTRL, /**< FMAN Controller timer event */
+ e_FM_MOD_DUMMY_LAST
+} e_FmEventModules;
+
+/**************************************************************************//**
+ @Description Enum for interrupts types
+*//***************************************************************************/
+typedef enum e_FmIntrType
+{
+ e_FM_INTR_TYPE_ERR,
+ e_FM_INTR_TYPE_NORMAL
+} e_FmIntrType;
+
+/**************************************************************************//**
+ @Description Enum for inter-module interrupts registration
+*//***************************************************************************/
+typedef enum e_FmInterModuleEvent
+{
+ e_FM_EV_PRS, /**< Parser event */
+ e_FM_EV_ERR_PRS, /**< Parser error event */
+ e_FM_EV_KG, /**< Keygen event */
+ e_FM_EV_ERR_KG, /**< Keygen error event */
+ e_FM_EV_PLCR, /**< Policer event */
+ e_FM_EV_ERR_PLCR, /**< Policer error event */
+ e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
+ e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
+ e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
+ e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
+ e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
+ e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
+ e_FM_EV_TMR, /**< Timer event */
+ e_FM_EV_1G_MAC0_TMR, /**< 1G MAC 0 timer event */
+ e_FM_EV_1G_MAC1_TMR, /**< 1G MAC 1 timer event */
+ e_FM_EV_1G_MAC2_TMR, /**< 1G MAC 2 timer event */
+ e_FM_EV_1G_MAC3_TMR, /**< 1G MAC 3 timer event */
+ e_FM_EV_1G_MAC4_TMR, /**< 1G MAC 4 timer event */
+ e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
+ e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
+ e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
+ e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
+ e_FM_EV_DUMMY_LAST
+} e_FmInterModuleEvent;
+
+#define GET_FM_MODULE_EVENT(mod, id, intrType, event) \
+ switch(mod){ \
+ case e_FM_MOD_PRS: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
+ break; \
+ case e_FM_MOD_KG: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
+ break; \
+ case e_FM_MOD_PLCR: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
+ break; \
+ case e_FM_MOD_10G_MAC: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_10G_MAC0 : e_FM_EV_DUMMY_LAST; \
+ break; \
+ case e_FM_MOD_1G_MAC: \
+ switch(id){ \
+ case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC0 : e_FM_EV_DUMMY_LAST; break; \
+ case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC1 : e_FM_EV_DUMMY_LAST; break; \
+ case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC2 : e_FM_EV_DUMMY_LAST; break; \
+ case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC3 : e_FM_EV_DUMMY_LAST; break; \
+ case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC4 : e_FM_EV_DUMMY_LAST; break; \
+ } \
+ break; \
+ case e_FM_MOD_TMR: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
+ break; \
+ case e_FM_MOD_1G_MAC_TMR: \
+ switch(id){ \
+ case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC0_TMR; break; \
+ case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC1_TMR; break; \
+ case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC2_TMR; break; \
+ case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC3_TMR; break; \
+ case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC4_TMR; break; \
+ } \
+ break; \
+ case e_FM_MOD_FMAN_CTRL: \
+ if (intrType == e_FM_INTR_TYPE_ERR) event = e_FM_EV_DUMMY_LAST; \
+ else switch(id){ \
+ case(0): event = e_FM_EV_FMAN_CTRL_0; break; \
+ case(1): event = e_FM_EV_FMAN_CTRL_1; break; \
+ case(2): event = e_FM_EV_FMAN_CTRL_2; break; \
+ case(3): event = e_FM_EV_FMAN_CTRL_3; break; \
+ } \
+ break; \
+ default: event = e_FM_EV_DUMMY_LAST; \
+ break;}
+
+#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
+
+/* P3041 unique features */
+#define FM_QMI_DEQ_OPTIONS_SUPPORT
+#define FM_NO_DISPATCH_RAM_ECC
+#define FM_FIFO_ALLOCATION_OLD_ALG
+#define FM_NO_WATCHDOG
+#define FM_NO_TNUM_AGING
+#define FM_NO_TGEC_LOOPBACK
+#define FM_KG_NO_BYPASS_FQID_GEN
+#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
+#define FM_NO_BACKUP_POOLS
+#define FM_NO_OP_OBSERVED_POOLS
+#define FM_NO_ADVANCED_RATE_LIMITER
+#define FM_NO_OP_OBSERVED_CGS
+
+/* FM erratas */
+#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
+#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
+#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
+
+#define FM_NO_RX_PREAM_ERRATA_DTSECx1
+#define FM_RX_PREAM_4_ERRATA_DTSEC_A001 FM_NO_RX_PREAM_ERRATA_DTSECx1
+#define FM_GRS_ERRATA_DTSEC_A002
+#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
+#define FM_GTS_ERRATA_DTSEC_A004
+#define FM_PAUSE_BLOCK_ERRATA_DTSEC_A006 /* do nothing */
+#define FM_RESERVED_ACCESS_TO_DISABLED_DEV_ERRATA_DTSEC_A0011 /* do nothing */
+#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012 FM_GTS_ERRATA_DTSEC_A004
+#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
+#define FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3
+#define FM_TX_LOCKUP_ERRATA_DTSEC6
+
+#define FM_IM_TX_SYNC_SKIP_TNUM_ERRATA_FMAN_A001 /* Implemented by ucode */
+#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
+#define FM_IM_TX_SHARED_TNUM_ERRATA_FMAN4 /* Implemented by ucode */
+#define FM_IM_GS_DEADLOCK_ERRATA_FMAN5 /* Implemented by ucode */
+#define FM_IM_DEQ_PIPELINE_DEPTH_ERRATA_FMAN10 /* Implemented by ucode */
+#define FM_CC_GEN6_MISSMATCH_ERRATA_FMAN12 /* Implemented by ucode */
+#define FM_CC_CHANGE_SHARED_TNUM_ERRATA_FMAN13 /* Implemented by ucode */
+#define FM_IM_LARGE_MRBLR_ERRATA_FMAN15 /* Implemented by ucode */
+#define FM_BMI_TO_RISC_ENQ_ERRATA_FMANc /* No implementation, Out of LLD scope */
+#define FM_INVALID_SWPRS_DATA_ERRATA_FMANd
+/* #define FM_PRS_MPLS_SSA_ERRATA_FMANj */ /* No implementation, No patch yet */
+/* #define FM_PRS_INITIAL_PLANID_ERRATA_FMANk */ /* No implementation, No patch yet */
+
+#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
+
+#define FM_NO_COPY_CTXA_CTXB_ERRATA_FMAN_SW001
+#define FM_PRS_MEM_ERRATA_FMAN_SW003
+#define FM_LEN_CHECK_ERRATA_FMAN_SW002
+#define FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
+
+
+#endif /* __DPAA_INTEGRATION_EXT_H */
diff --git a/sys/contrib/ncsw/inc/integrations/P3041/part_integration_ext.h b/sys/contrib/ncsw/inc/integrations/P3041/part_integration_ext.h
new file mode 100644
index 0000000..0eb5746
--- /dev/null
+++ b/sys/contrib/ncsw/inc/integrations/P3041/part_integration_ext.h
@@ -0,0 +1,995 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ **************************************************************************/
+/**
+
+ @File part_integration_ext.h
+
+ @Description P3041 external definitions and structures.
+*//***************************************************************************/
+#ifndef __PART_INTEGRATION_EXT_H
+#define __PART_INTEGRATION_EXT_H
+
+#include "std_ext.h"
+#include "ddr_std_ext.h"
+#include "enet_ext.h"
+#include "dpaa_integration_ext.h"
+
+
+/**************************************************************************//**
+ @Group P3041_chip_id P3041 Application Programming Interface
+
+ @Description P3041 Chip functions,definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+#define CORE_E500MC
+
+#define INTG_MAX_NUM_OF_CORES 4
+
+
+/**************************************************************************//**
+ @Description Module types.
+*//***************************************************************************/
+typedef enum e_ModuleId
+{
+ e_MODULE_ID_DUART_1 = 0,
+ e_MODULE_ID_DUART_2,
+ e_MODULE_ID_DUART_3,
+ e_MODULE_ID_DUART_4,
+ e_MODULE_ID_LAW,
+ e_MODULE_ID_LBC,
+ e_MODULE_ID_PAMU,
+ e_MODULE_ID_QM, /**< Queue manager module */
+ e_MODULE_ID_BM, /**< Buffer manager module */
+ e_MODULE_ID_QM_CE_PORTAL_0,
+ e_MODULE_ID_QM_CI_PORTAL_0,
+ e_MODULE_ID_QM_CE_PORTAL_1,
+ e_MODULE_ID_QM_CI_PORTAL_1,
+ e_MODULE_ID_QM_CE_PORTAL_2,
+ e_MODULE_ID_QM_CI_PORTAL_2,
+ e_MODULE_ID_QM_CE_PORTAL_3,
+ e_MODULE_ID_QM_CI_PORTAL_3,
+ e_MODULE_ID_QM_CE_PORTAL_4,
+ e_MODULE_ID_QM_CI_PORTAL_4,
+ e_MODULE_ID_QM_CE_PORTAL_5,
+ e_MODULE_ID_QM_CI_PORTAL_5,
+ e_MODULE_ID_QM_CE_PORTAL_6,
+ e_MODULE_ID_QM_CI_PORTAL_6,
+ e_MODULE_ID_QM_CE_PORTAL_7,
+ e_MODULE_ID_QM_CI_PORTAL_7,
+ e_MODULE_ID_QM_CE_PORTAL_8,
+ e_MODULE_ID_QM_CI_PORTAL_8,
+ e_MODULE_ID_QM_CE_PORTAL_9,
+ e_MODULE_ID_QM_CI_PORTAL_9,
+ e_MODULE_ID_BM_CE_PORTAL_0,
+ e_MODULE_ID_BM_CI_PORTAL_0,
+ e_MODULE_ID_BM_CE_PORTAL_1,
+ e_MODULE_ID_BM_CI_PORTAL_1,
+ e_MODULE_ID_BM_CE_PORTAL_2,
+ e_MODULE_ID_BM_CI_PORTAL_2,
+ e_MODULE_ID_BM_CE_PORTAL_3,
+ e_MODULE_ID_BM_CI_PORTAL_3,
+ e_MODULE_ID_BM_CE_PORTAL_4,
+ e_MODULE_ID_BM_CI_PORTAL_4,
+ e_MODULE_ID_BM_CE_PORTAL_5,
+ e_MODULE_ID_BM_CI_PORTAL_5,
+ e_MODULE_ID_BM_CE_PORTAL_6,
+ e_MODULE_ID_BM_CI_PORTAL_6,
+ e_MODULE_ID_BM_CE_PORTAL_7,
+ e_MODULE_ID_BM_CI_PORTAL_7,
+ e_MODULE_ID_BM_CE_PORTAL_8,
+ e_MODULE_ID_BM_CI_PORTAL_8,
+ e_MODULE_ID_BM_CE_PORTAL_9,
+ e_MODULE_ID_BM_CI_PORTAL_9,
+ e_MODULE_ID_FM, /**< Frame manager module */
+ e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
+ e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
+ e_MODULE_ID_FM_BMI, /**< FM BMI block */
+ e_MODULE_ID_FM_QMI, /**< FM QMI block */
+ e_MODULE_ID_FM_PARSER, /**< FM parser block */
+ e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_10GRx, /**< FM Rx 10G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_10GTx, /**< FM Tx 10G MAC port block */
+ e_MODULE_ID_FM_PLCR, /**< FM Policer */
+ e_MODULE_ID_FM_KG, /**< FM Keygen */
+ e_MODULE_ID_FM_DMA, /**< FM DMA */
+ e_MODULE_ID_FM_FPM, /**< FM FPM */
+ e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
+ e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
+ e_MODULE_ID_FM_1GMDIO2, /**< FM 1G MDIO MAC 2*/
+ e_MODULE_ID_FM_1GMDIO3, /**< FM 1G MDIO MAC 3*/
+ e_MODULE_ID_FM_1GMDIO4, /**< FM 1G MDIO MAC 4*/
+ e_MODULE_ID_FM_1GMDIO5, /**< FM 1G MDIO MAC 5*/
+ e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
+ e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
+ e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
+ e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
+ e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
+ e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
+ e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
+ e_MODULE_ID_FM_10GMAC, /**< FM 10G MAC */
+
+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
+
+ e_MODULE_ID_PIC, /**< PIC */
+ e_MODULE_ID_GPIO, /**< GPIO */
+ e_MODULE_ID_SERDES, /**< SERDES */
+ e_MODULE_ID_CPC, /**< CoreNet-Platform-Cache */
+ e_MODULE_ID_DUMMY_LAST
+} e_ModuleId;
+
+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
+
+/* Offsets relative to CCSR base */
+#define P3041_OFFSET_LAW 0x00000c00
+#define P3041_OFFSET_DDR 0x00008000
+#define P3041_OFFSET_CPC 0x00010000
+#define P3041_OFFSET_CCM 0x00018000
+#define P3041_OFFSET_PAMU 0x00020000
+#define P3041_OFFSET_PIC 0x00040000
+#define P3041_OFFSET_GUTIL 0x000e0000
+#define P3041_OFFSET_RCPM 0x000e2000
+#define P3041_OFFSET_SERDES 0x000ea000
+#define P3041_OFFSET_DMA1 0x00100100
+#define P3041_OFFSET_DMA2 0x00101100
+#define P3041_OFFSET_ESPI 0x00110000
+#define P3041_OFFSET_ESDHC 0x00114000
+#define P3041_OFFSET_I2C1 0x00118000
+#define P3041_OFFSET_I2C2 0x00118100
+#define P3041_OFFSET_I2C3 0x00119000
+#define P3041_OFFSET_I2C4 0x00119100
+#define P3041_OFFSET_DUART1 0x0011c500
+#define P3041_OFFSET_DUART2 0x0011c600
+#define P3041_OFFSET_DUART3 0x0011d500
+#define P3041_OFFSET_DUART4 0x0011d600
+#define P3041_OFFSET_LBC 0x00124000
+#define P3041_OFFSET_GPIO 0x00130000
+#define P3041_OFFSET_PCIE1 0x00200000
+#define P3041_OFFSET_PCIE2 0x00201000
+#define P3041_OFFSET_PCIE3 0x00202000
+#define P3041_OFFSET_PCIE4 0x00203000
+#define P3041_OFFSET_USB1 0x00210000
+#define P3041_OFFSET_USB2 0x00211000
+#define P3041_OFFSET_USB_PHY 0x00214000
+#define P3041_OFFSET_SATA1 0x00220000
+#define P3041_OFFSET_SATA2 0x00221000
+#define P3041_OFFSET_SEC_GEN 0x00300000
+#define P3041_OFFSET_SEC_JQ0 0x00301000
+#define P3041_OFFSET_SEC_JQ1 0x00302000
+#define P3041_OFFSET_SEC_JQ2 0x00303000
+#define P3041_OFFSET_SEC_JQ3 0x00304000
+#define P3041_OFFSET_SEC_RESERVED 0x00305000
+#define P3041_OFFSET_SEC_RTIC 0x00306000
+#define P3041_OFFSET_SEC_QI 0x00307000
+#define P3041_OFFSET_SEC_DECO0_CCB0 0x00308000
+#define P3041_OFFSET_SEC_DECO1_CCB1 0x00309000
+#define P3041_OFFSET_PME 0x00316000
+#define P3041_OFFSET_QM 0x00318000
+#define P3041_OFFSET_BM 0x0031a000
+#define P3041_OFFSET_FM 0x00400000
+
+#define P3041_OFFSET_FM_MURAM P3041_OFFSET_FM
+#define P3041_OFFSET_FM_BMI (P3041_OFFSET_FM + 0x00080000)
+#define P3041_OFFSET_FM_QMI (P3041_OFFSET_FM + 0x00080400)
+#define P3041_OFFSET_FM_PARSER (P3041_OFFSET_FM + 0x00080800)
+#define P3041_OFFSET_FM_PORT_HO1 (P3041_OFFSET_FM + 0x00081000) /* host command/offline parser */
+#define P3041_OFFSET_FM_PORT_HO2 (P3041_OFFSET_FM + 0x00082000)
+#define P3041_OFFSET_FM_PORT_HO3 (P3041_OFFSET_FM + 0x00083000)
+#define P3041_OFFSET_FM_PORT_HO4 (P3041_OFFSET_FM + 0x00084000)
+#define P3041_OFFSET_FM_PORT_HO5 (P3041_OFFSET_FM + 0x00085000)
+#define P3041_OFFSET_FM_PORT_HO6 (P3041_OFFSET_FM + 0x00086000)
+#define P3041_OFFSET_FM_PORT_HO7 (P3041_OFFSET_FM + 0x00087000)
+#define P3041_OFFSET_FM_PORT_1GRX1 (P3041_OFFSET_FM + 0x00088000)
+#define P3041_OFFSET_FM_PORT_1GRX2 (P3041_OFFSET_FM + 0x00089000)
+#define P3041_OFFSET_FM_PORT_1GRX3 (P3041_OFFSET_FM + 0x0008a000)
+#define P3041_OFFSET_FM_PORT_1GRX4 (P3041_OFFSET_FM + 0x0008b000)
+#define P3041_OFFSET_FM_PORT_1GRX5 (P3041_OFFSET_FM + 0x0008c000)
+#define P3041_OFFSET_FM_PORT_10GRX (P3041_OFFSET_FM + 0x00090000)
+#define P3041_OFFSET_FM_PORT_1GTX1 (P3041_OFFSET_FM + 0x000a8000)
+#define P3041_OFFSET_FM_PORT_1GTX2 (P3041_OFFSET_FM + 0x000a9000)
+#define P3041_OFFSET_FM_PORT_1GTX3 (P3041_OFFSET_FM + 0x000aa000)
+#define P3041_OFFSET_FM_PORT_1GTX4 (P3041_OFFSET_FM + 0x000ab000)
+#define P3041_OFFSET_FM_PORT_1GTX5 (P3041_OFFSET_FM + 0x000ac000)
+#define P3041_OFFSET_FM_PORT_10GTX (P3041_OFFSET_FM + 0x000b0000)
+#define P3041_OFFSET_FM_PLCR (P3041_OFFSET_FM + 0x000c0000)
+#define P3041_OFFSET_FM_KG (P3041_OFFSET_FM + 0x000c1000)
+#define P3041_OFFSET_FM_DMA (P3041_OFFSET_FM + 0x000c2000)
+#define P3041_OFFSET_FM_FPM (P3041_OFFSET_FM + 0x000c3000)
+#define P3041_OFFSET_FM_IRAM (P3041_OFFSET_FM + 0x000c4000)
+#define P3041_OFFSET_FM_PARSER_IRAM (P3041_OFFSET_FM + 0x000c7000)
+#define P3041_OFFSET_FM_1GMAC1 (P3041_OFFSET_FM + 0x000e0000)
+#define P3041_OFFSET_FM_1GMDIO (P3041_OFFSET_FM + 0x000e1000 + 0x120)
+#define P3041_OFFSET_FM_1GMAC2 (P3041_OFFSET_FM + 0x000e2000)
+#define P3041_OFFSET_FM_1GMAC3 (P3041_OFFSET_FM + 0x000e4000)
+#define P3041_OFFSET_FM_1GMAC4 (P3041_OFFSET_FM + 0x000e6000)
+#define P3041_OFFSET_FM_1GMAC5 (P3041_OFFSET_FM + 0x000e8000)
+#define P3041_OFFSET_FM_10GMAC (P3041_OFFSET_FM + 0x000f0000)
+#define P3041_OFFSET_FM_10GMDIO (P3041_OFFSET_FM + 0x000f1000 + 0x030)
+#define P3041_OFFSET_FM_RTC (P3041_OFFSET_FM + 0x000fe000)
+
+/* Offsets relative to QM or BM portals base */
+#define P3041_OFFSET_PORTALS_CE_AREA 0x000000 /* cache enabled area */
+#define P3041_OFFSET_PORTALS_CI_AREA 0x100000 /* cache inhibited area */
+
+#define P3041_CE_PORTAL_SIZE 0x4000
+#define P3041_CI_PORTAL_SIZE 0x1000
+
+#define P3041_OFFSET_PORTALS_CE(portal) \
+ (P3041_OFFSET_PORTALS_CE_AREA + P3041_CE_PORTAL_SIZE * (portal))
+#define P3041_OFFSET_PORTALS_CI(portal) \
+ (P3041_OFFSET_PORTALS_CI_AREA + P3041_CI_PORTAL_SIZE * (portal))
+
+
+/**************************************************************************//**
+ @Description Transaction source ID (for memory controllers error reporting).
+*//***************************************************************************/
+typedef enum e_TransSrc
+{
+ e_TRANS_SRC_PCIE_1 = 0x0, /**< PCI Express 1 */
+ e_TRANS_SRC_PCIE_2 = 0x1, /**< PCI Express 2 */
+ e_TRANS_SRC_PCIE_3 = 0x2, /**< PCI Express 3 */
+ e_TRANS_SRC_PCIE_4 = 0x3, /**< PCI Express 4 */
+ e_TRANS_SRC_SRIO_1 = 0x8, /**< SRIO 1 */
+ e_TRANS_SRC_SRIO_2 = 0x9, /**< SRIO 2 */
+ e_TRANS_SRC_BMAN = 0x18, /**< BMan */
+ e_TRANS_SRC_PAMU = 0x1C, /**< PAMU */
+ e_TRANS_SRC_PME = 0x20, /**< PME */
+ e_TRANS_SRC_SEC = 0x21, /**< Security engine */
+ e_TRANS_SRC_QMAN = 0x3C, /**< QMan */
+ e_TRANS_SRC_USB_1 = 0x40, /**< USB 1 */
+ e_TRANS_SRC_USB_2 = 0x41, /**< USB 2 */
+ e_TRANS_SRC_ESDHC = 0x44, /**< eSDHC */
+ e_TRANS_SRC_PBL = 0x48, /**< Pre-boot loader */
+ e_TRANS_SRC_NPC = 0x4B, /**< Nexus port controller */
+ e_TRANS_SRC_RMAN = 0x5D, /**< RIO message manager */
+ e_TRANS_SRC_SATA_1 = 0x60, /**< SATA 1 */
+ e_TRANS_SRC_SATA_2 = 0x61, /**< SATA 2 */
+ e_TRANS_SRC_DMA_1 = 0x70, /**< DMA 1 */
+ e_TRANS_SRC_DMA_2 = 0x71, /**< DMA 2 */
+ e_TRANS_SRC_CORE_0_INST = 0x80, /**< Processor 0 (instruction) */
+ e_TRANS_SRC_CORE_0_DATA = 0x81, /**< Processor 0 (data) */
+ e_TRANS_SRC_CORE_1_INST = 0x82, /**< Processor 1 (instruction) */
+ e_TRANS_SRC_CORE_1_DATA = 0x83, /**< Processor 1 (data) */
+ e_TRANS_SRC_CORE_2_INST = 0x84, /**< Processor 2 (instruction) */
+ e_TRANS_SRC_CORE_2_DATA = 0x85, /**< Processor 2 (data) */
+ e_TRANS_SRC_CORE_3_INST = 0x86, /**< Processor 3 (instruction) */
+ e_TRANS_SRC_CORE_3_DATA = 0x87, /**< Processor 3 (data) */
+ e_TRANS_SRC_FM_10G = 0xC0, /**< FM XAUI */
+ e_TRANS_SRC_FM_HO_1 = 0xC1, /**< FM offline, host 1 */
+ e_TRANS_SRC_FM_HO_2 = 0xC2, /**< FM offline, host 2 */
+ e_TRANS_SRC_FM_HO_3 = 0xC3, /**< FM offline, host 3 */
+ e_TRANS_SRC_FM_HO_4 = 0xC4, /**< FM offline, host 4 */
+ e_TRANS_SRC_FM_HO_5 = 0xC5, /**< FM offline, host 5 */
+ e_TRANS_SRC_FM_HO_6 = 0xC6, /**< FM offline, host 6 */
+ e_TRANS_SRC_FM_HO_7 = 0xC7, /**< FM offline, host 7 */
+ e_TRANS_SRC_FM_GETH_1 = 0xC8, /**< FM GETH 1 */
+ e_TRANS_SRC_FM_GETH_2 = 0xC9, /**< FM GETH 2 */
+ e_TRANS_SRC_FM_GETH_3 = 0xCA, /**< FM GETH 3 */
+ e_TRANS_SRC_FM_GETH_4 = 0xCB, /**< FM GETH 4 */
+ e_TRANS_SRC_FM_GETH_5 = 0xCC /**< FM GETH 5 */
+} e_TransSrc;
+
+/**************************************************************************//**
+ @Description Local Access Window Target interface ID
+*//***************************************************************************/
+typedef enum e_P3041LawTargetId
+{
+ e_P3041_LAW_TARGET_PCIE_1 = 0x0, /**< PCI Express 1 */
+ e_P3041_LAW_TARGET_PCIE_2 = 0x1, /**< PCI Express 2 */
+ e_P3041_LAW_TARGET_PCIE_3 = 0x2, /**< PCI Express 3 */
+ e_P3041_LAW_TARGET_PCIE_4 = 0x3, /**< PCI Express 4 */
+ e_P3041_LAW_TARGET_SRIO_1 = 0x8, /**< SRIO 1 */
+ e_P3041_LAW_TARGET_SRIO_2 = 0x9, /**< SRIO 2 */
+ e_P3041_LAW_TARGET_DDR_CPC = 0x10, /**< DDR controller or CPC SRAM */
+ e_P3041_LAW_TARGET_BMAN = 0x18, /**< BMAN target interface ID */
+ e_P3041_LAW_TARGET_DCSR = 0x1D, /**< DCSR */
+ e_P3041_LAW_TARGET_LBC = 0x1F, /**< Local Bus target interface ID */
+ e_P3041_LAW_TARGET_QMAN = 0x3C, /**< QMAN target interface ID */
+ e_P3041_LAW_TARGET_NONE = 0xFF /**< None */
+} e_P3041LawTargetId;
+
+/***************************************************************
+ P3041 general routines
+****************************************************************/
+/**************************************************************************//**
+ @Group P3041_init_grp P3041 Initialization Unit
+
+ @Description P3041 initialization unit API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Part ID and revision number
+*//***************************************************************************/
+typedef enum e_P3041DeviceName
+{
+ e_P3041_REV_INVALID = 0x00000000, /**< Invalid revision */
+ e_P3041_REV_1_0 = (int)0x82190310, /**< P3041 with security, revision 1.0 */
+ e_P3041_REV_1_0_NO_SEC = (int)0x82110310 /**< P3041 without security, revision 1.0 */
+} e_P3041DeviceName;
+
+/**************************************************************************//**
+ @Description Device Disable Register
+*//***************************************************************************/
+typedef enum e_P3041DeviceDisable
+{
+ e_P3041_DEV_DISABLE_PCIE_1 = 0, /**< PCI Express controller 1 disable */
+ e_P3041_DEV_DISABLE_PCIE_2, /**< PCI Express controller 2 disable */
+ e_P3041_DEV_DISABLE_PCIE_3, /**< PCI Express controller 3 disable */
+ e_P3041_DEV_DISABLE_PCIE_4, /**< PCI Express controller 4 disable */
+ e_P3041_DEV_DISABLE_RMAN, /**< RapidIO message manager disable */
+ e_P3041_DEV_DISABLE_SRIO_1, /**< Serial RapidIO controller 1 disable */
+ e_P3041_DEV_DISABLE_SRIO_2, /**< Serial RapidIO controller 2 disable */
+ e_P3041_DEV_DISABLE_DMA_1 = 9, /**< DMA controller 1 disable */
+ e_P3041_DEV_DISABLE_DMA_2, /**< DMA controller 2 disable */
+ e_P3041_DEV_DISABLE_DDR, /**< DDR controller disable */
+ e_P3041_DEV_DISABLE_SATA_1 = 17, /**< SATA controller 1 disable */
+ e_P3041_DEV_DISABLE_SATA_2, /**< SATA controller 2 disable */
+ e_P3041_DEV_DISABLE_LBC, /**< eLBC controller disable */
+ e_P3041_DEV_DISABLE_USB_1, /**< USB controller 1 disable */
+ e_P3041_DEV_DISABLE_USB_2, /**< USB controller 2 disable */
+ e_P3041_DEV_DISABLE_ESDHC = 23, /**< eSDHC controller disable */
+ e_P3041_DEV_DISABLE_GPIO, /**< GPIO controller disable */
+ e_P3041_DEV_DISABLE_ESPI, /**< eSPI controller disable */
+ e_P3041_DEV_DISABLE_I2C_1, /**< I2C module 1 (controllers 1 and 2) disable */
+ e_P3041_DEV_DISABLE_I2C_2, /**< I2C module 2 (controllers 3 and 4) disable */
+ e_P3041_DEV_DISABLE_DUART_1 = 30, /**< DUART controller 1 disable */
+ e_P3041_DEV_DISABLE_DUART_2, /**< DUART controller 2 disable */
+ e_P3041_DEV_DISABLE_DISR1_DUMMY_LAST = 32,
+ /**< Dummy entry signing end of DEVDISR1 register controllers */
+ e_P3041_DEV_DISABLE_PME = e_P3041_DEV_DISABLE_DISR1_DUMMY_LAST,
+ /**< Pattern match engine disable */
+ e_P3041_DEV_DISABLE_SEC, /**< Security disable */
+ e_P3041_DEV_DISABLE_QM_BM = e_P3041_DEV_DISABLE_DISR1_DUMMY_LAST + 4,
+ /**< Queue manager/buffer manager disable */
+ e_P3041_DEV_DISABLE_FM = e_P3041_DEV_DISABLE_DISR1_DUMMY_LAST + 6,
+ /**< Frame manager disable */
+ e_P3041_DEV_DISABLE_10G, /**< 10G Ethernet controller disable */
+ e_P3041_DEV_DISABLE_DTSEC_1, /**< dTSEC controller 1 disable */
+ e_P3041_DEV_DISABLE_DTSEC_2, /**< dTSEC controller 2 disable */
+ e_P3041_DEV_DISABLE_DTSEC_3, /**< dTSEC controller 3 disable */
+ e_P3041_DEV_DISABLE_DTSEC_4, /**< dTSEC controller 4 disable */
+ e_P3041_DEV_DISABLE_DTSEC_5 /**< dTSEC controller 5 disable */
+} e_P3041DeviceDisable;
+
+
+/**************************************************************************//*
+ @Description structure representing P3041 devices configuration
+*//***************************************************************************/
+typedef struct t_P3041Devices
+{
+ struct
+ {
+ struct
+ {
+ bool enabled;
+ uint8_t serdesBank;
+ uint16_t serdesLane; /**< Most significant bits represent lanes used by this bank,
+ one bit for lane, lane A is the first and so on, e.g.,
+ set 0xF000 for ABCD lanes */
+ e_EnetInterface ethIf;
+ uint8_t ratio;
+ bool divByTwo;
+ bool isTwoHalfSgmii;
+ } dtsecs[FM_MAX_NUM_OF_1G_MACS];
+ struct
+ {
+ bool enabled;
+ uint8_t serdesBank;
+ uint16_t serdesLane;
+ } tgec;
+ } fm;
+} t_P3041Devices;
+
+/**************************************************************************//**
+ @Function P3041_GetRevInfo
+
+ @Description Obtain revision information.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return Part ID and revision.
+*//***************************************************************************/
+e_P3041DeviceName P3041_GetRevInfo(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P3041_GetE500Factor
+
+ @Description Obtain core's multiplication factors.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+ @Param[in] coreIndex - Core index.
+ @Param[out] p_E500MulFactor - E500 to CCB multification factor.
+ @Param[out] p_E500DivFactor - E500 to CCB division factor.
+
+*//***************************************************************************/
+void P3041_GetE500Factor(uintptr_t gutilBase,
+ uint8_t coreIndex,
+ uint32_t *p_E500MulFactor,
+ uint32_t *p_E500DivFactor);
+
+/**************************************************************************//**
+ @Function P3041_GetCcbFactor
+
+ @Description Obtain system multiplication factor.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return System multiplication factor.
+*//***************************************************************************/
+uint32_t P3041_GetCcbFactor(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P3041_GetDdrFactor
+
+ @Description Obtain DDR clock multiplication factor.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return DDR clock multiplication factor.
+*//***************************************************************************/
+uint32_t P3041_GetDdrFactor(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P3041_GetDdrType
+
+ @Description Obtain DDR memory type.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return DDR type.
+*//***************************************************************************/
+e_DdrType P3041_GetDdrType(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P3041_GetFmFactor
+
+ @Description returns FM multiplication factors. (This value is returned using
+ two parameters to avoid using float parameter).
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+ @Param[out] p_FmMulFactor - FM to CCB multification factor.
+ @Param[out] p_FmDivFactor - FM to CCB division factor.
+
+*//***************************************************************************/
+void P3041_GetFmFactor(uintptr_t gutilBase,
+ uint32_t *p_FmMulFactor,
+ uint32_t *p_FmDivFactor);
+
+
+void P3041_CoreTimeBaseEnable(uintptr_t rcpmBase);
+void P3041_CoreTimeBaseDisable(uintptr_t rcpmBase);
+
+typedef enum e_SerdesProtocol
+{
+ SRDS_PROTOCOL_NONE = 0,
+ SRDS_PROTOCOL_PCIE1,
+ SRDS_PROTOCOL_PCIE2,
+ SRDS_PROTOCOL_PCIE3,
+ SRDS_PROTOCOL_PCIE4,
+ SRDS_PROTOCOL_SRIO1,
+ SRDS_PROTOCOL_SRIO2,
+ SRDS_PROTOCOL_SGMII_FM,
+ SRDS_PROTOCOL_XAUI_FM,
+ SRDS_PROTOCOL_SATA1,
+ SRDS_PROTOCOL_SATA2,
+ SRDS_PROTOCOL_AURORA
+} e_SerdesProtocol;
+
+t_Error P3041_DeviceDisable(uintptr_t gutilBase, e_P3041DeviceDisable device, bool disable);
+void P3041_GetDevicesConfiguration(uintptr_t gutilBase, t_P3041Devices *p_Devices);
+t_Error P3041_PamuDisableBypass(uintptr_t gutilBase, uint8_t pamuId, bool disable);
+uint32_t P3041_SerdesRcwGetProtocol(uintptr_t gutilBase);
+bool P3041_SerdesRcwIsDeviceConfigured(uintptr_t gutilBase, e_SerdesProtocol device);
+bool P3041_SerdesRcwIsLaneEnabled(uintptr_t gutilBase, uint32_t lane);
+
+/** @} */ /* end of P3041_init_grp group */
+/** @} */ /* end of P3041_grp group */
+
+
+/*****************************************************************************
+ INTEGRATION-SPECIFIC MODULE CODES
+******************************************************************************/
+#define MODULE_UNKNOWN 0x00000000
+#define MODULE_MEM 0x00010000
+#define MODULE_MM 0x00020000
+#define MODULE_CORE 0x00030000
+#define MODULE_P3041 0x00040000
+#define MODULE_P3041_PLATFORM 0x00050000
+#define MODULE_PM 0x00060000
+#define MODULE_MMU 0x00070000
+#define MODULE_PIC 0x00080000
+#define MODULE_CPC 0x00090000
+#define MODULE_DUART 0x000a0000
+#define MODULE_SERDES 0x000b0000
+#define MODULE_PIO 0x000c0000
+#define MODULE_QM 0x000d0000
+#define MODULE_BM 0x000e0000
+#define MODULE_SEC 0x000f0000
+#define MODULE_LAW 0x00100000
+#define MODULE_LBC 0x00110000
+#define MODULE_PAMU 0x00120000
+#define MODULE_FM 0x00130000
+#define MODULE_FM_MURAM 0x00140000
+#define MODULE_FM_PCD 0x00150000
+#define MODULE_FM_RTC 0x00160000
+#define MODULE_FM_MAC 0x00170000
+#define MODULE_FM_PORT 0x00180000
+#define MODULE_DPA 0x00190000
+#define MODULE_MII 0x001a0000
+#define MODULE_I2C 0x001b0000
+#define MODULE_DMA 0x001c0000
+#define MODULE_DDR 0x001d0000
+#define MODULE_ESPI 0x001e0000
+
+/*****************************************************************************
+ PAMU INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define PAMU_NUM_OF_PARTITIONS 4
+
+
+/*****************************************************************************
+ LAW INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define LAW_NUM_OF_WINDOWS 32
+#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
+#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
+
+
+/*****************************************************************************
+ LBC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+/**************************************************************************//**
+ @Group lbc_exception_grp LBC Exception Unit
+
+ @Description LBC Exception unit API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Anchor lbc_exbm
+
+ @Collection LBC Errors Bit Mask
+
+ These errors are reported through the exceptions callback..
+ The values can be or'ed in any combination in the errors mask
+ parameter of the errors report structure.
+
+ These errors can also be passed as a bit-mask to
+ LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
+ for enabling or disabling error checking.
+ @{
+*//***************************************************************************/
+#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
+#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
+#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
+#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
+
+#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
+ LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
+ /**< All possible errors */
+/* @} */
+/** @} */ /* end of lbc_exception_grp group */
+
+#define LBC_INCORRECT_ERROR_REPORT_ERRATA
+
+#define LBC_NUM_OF_BANKS 8
+#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
+#define LBC_PARITY_SUPPORT
+#define LBC_HIGH_CLK_DIVIDERS
+#define LBC_FCM_AVAILABLE
+
+/*****************************************************************************
+ GPIO INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
+ Each port contains up to 32 I/O pins. */
+
+#define GPIO_VALID_PIN_MASKS \
+ { /* Port A */ 0xFFFFFFFF }
+
+#define GPIO_VALID_INTR_MASKS \
+ { /* Port A */ 0xFFFFFFFF }
+
+
+/*****************************************************************************
+ SERDES INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define SRDS_MAX_LANES 18
+#define SRDS_MAX_BANK 3
+
+/* Serdes lanes general information provided in the following form:
+ 1) Lane index in Serdes Control Registers Map
+ 2) Lane enable/disable bit number in RCW
+ 3) Lane bank index */
+#define SRDS_LANES \
+{ \
+ { 0, 152, 0 }, \
+ { 1, 153, 0 }, \
+ { 2, 154, 0 }, \
+ { 3, 155, 0 }, \
+ { 4, 156, 0 }, \
+ { 5, 157, 0 }, \
+ { 6, 158, 0 }, \
+ { 7, 159, 0 }, \
+ { 8, 160, 0 }, \
+ { 9, 161, 0 }, \
+ { 16, 162, 1 }, \
+ { 17, 163, 1 }, \
+ { 18, 164, 1 }, \
+ { 19, 165, 1 }, \
+ { 20, 166, 2 }, \
+ { 21, 167, 2 }, \
+ { 22, 168, 2 }, \
+ { 23, 169, 2 } \
+}
+
+#define SRDS_PROTOCOL_ALL_OPTIONS
+/* Serdes lanes assignment and multiplexing.
+ Each option is selected by SRDS_PRTCL bits of RCW. */
+#define SRDS_PROTOCOL_OPTIONS \
+/* Protocol Lane assignment */ \
+{ \
+/* 0x00 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_PCIE4, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x01 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_PCIE4, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x02 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_PCIE4, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x03 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x04 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x05 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x06 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x07 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x08 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x09 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x0A */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x0B */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x0C */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x0D */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x0E */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x0F */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x10 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x11 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x12 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x13 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x14 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x15 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x16 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1}, \
+/* 0x17 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x18 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x19 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x1A */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x1B */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x1C */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x1D */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x1E */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x1F */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x20 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x21 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x22 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x23 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x24 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x25 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x26 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x27 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x28 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x29 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x2A */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x2B */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x2C */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x2D */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x2E */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x2F */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x30 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x31 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x32 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x33 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x34 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x35 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x36 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x37 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2} \
+}
+
+/*****************************************************************************
+ DDR INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define DDR_NUM_OF_VALID_CS 4
+
+/*****************************************************************************
+ DMA INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define DMA_NUM_OF_CONTROLLERS 2
+
+/*****************************************************************************
+ CPC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+
+#define CPC_MAX_SIZE_SRAM_ERRATA_CPC4
+#define CPC_HARDWARE_FLUSH_ERRATA_CPC10
+
+
+#endif /* __PART_INTEGRATION_EXT_H */
diff --git a/sys/contrib/ncsw/inc/integrations/P5020/dpaa_integration_ext.h b/sys/contrib/ncsw/inc/integrations/P5020/dpaa_integration_ext.h
new file mode 100644
index 0000000..6283b1a
--- /dev/null
+++ b/sys/contrib/ncsw/inc/integrations/P5020/dpaa_integration_ext.h
@@ -0,0 +1,374 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ **************************************************************************/
+/**
+
+ @File dpaa_integration_ext.h
+
+ @Description P5020 FM external definitions and structures.
+*//***************************************************************************/
+#ifndef __DPAA_INTEGRATION_EXT_H
+#define __DPAA_INTEGRATION_EXT_H
+
+#include "std_ext.h"
+
+
+/**************************************************************************//**
+ @Description DPAA SW Portals Enumeration.
+*//***************************************************************************/
+typedef enum
+{
+ e_DPAA_SWPORTAL0 = 0,
+ e_DPAA_SWPORTAL1,
+ e_DPAA_SWPORTAL2,
+ e_DPAA_SWPORTAL3,
+ e_DPAA_SWPORTAL4,
+ e_DPAA_SWPORTAL5,
+ e_DPAA_SWPORTAL6,
+ e_DPAA_SWPORTAL7,
+ e_DPAA_SWPORTAL8,
+ e_DPAA_SWPORTAL9,
+ e_DPAA_SWPORTAL_DUMMY_LAST
+} e_DpaaSwPortal;
+
+/**************************************************************************//**
+ @Description DPAA Direct Connect Portals Enumeration.
+*//***************************************************************************/
+typedef enum
+{
+ e_DPAA_DCPORTAL0 = 0,
+ e_DPAA_DCPORTAL1,
+ e_DPAA_DCPORTAL2,
+ e_DPAA_DCPORTAL3,
+ e_DPAA_DCPORTAL4,
+ e_DPAA_DCPORTAL_DUMMY_LAST
+} e_DpaaDcPortal;
+
+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
+
+/*****************************************************************************
+ QMan INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
+#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
+#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
+#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
+ /**< FQIDs range - 24 bits */
+
+/**************************************************************************//**
+ @Description Work Queue Channel assignments in QMan.
+*//***************************************************************************/
+typedef enum
+{
+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
+ e_QM_FQ_CHANNEL_SWPORTAL1,
+ e_QM_FQ_CHANNEL_SWPORTAL2,
+ e_QM_FQ_CHANNEL_SWPORTAL3,
+ e_QM_FQ_CHANNEL_SWPORTAL4,
+ e_QM_FQ_CHANNEL_SWPORTAL5,
+ e_QM_FQ_CHANNEL_SWPORTAL6,
+ e_QM_FQ_CHANNEL_SWPORTAL7,
+ e_QM_FQ_CHANNEL_SWPORTAL8,
+ e_QM_FQ_CHANNEL_SWPORTAL9,
+
+ e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
+ e_QM_FQ_CHANNEL_POOL2,
+ e_QM_FQ_CHANNEL_POOL3,
+ e_QM_FQ_CHANNEL_POOL4,
+ e_QM_FQ_CHANNEL_POOL5,
+ e_QM_FQ_CHANNEL_POOL6,
+ e_QM_FQ_CHANNEL_POOL7,
+ e_QM_FQ_CHANNEL_POOL8,
+ e_QM_FQ_CHANNEL_POOL9,
+ e_QM_FQ_CHANNEL_POOL10,
+ e_QM_FQ_CHANNEL_POOL11,
+ e_QM_FQ_CHANNEL_POOL12,
+ e_QM_FQ_CHANNEL_POOL13,
+ e_QM_FQ_CHANNEL_POOL14,
+ e_QM_FQ_CHANNEL_POOL15,
+
+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
+ connected to FMan 0; assigned in incrementing order to
+ each sub-portal (SP) in the portal */
+ e_QM_FQ_CHANNEL_FMAN0_SP1,
+ e_QM_FQ_CHANNEL_FMAN0_SP2,
+ e_QM_FQ_CHANNEL_FMAN0_SP3,
+ e_QM_FQ_CHANNEL_FMAN0_SP4,
+ e_QM_FQ_CHANNEL_FMAN0_SP5,
+ e_QM_FQ_CHANNEL_FMAN0_SP6,
+ e_QM_FQ_CHANNEL_FMAN0_SP7,
+ e_QM_FQ_CHANNEL_FMAN0_SP8,
+ e_QM_FQ_CHANNEL_FMAN0_SP9,
+ e_QM_FQ_CHANNEL_FMAN0_SP10,
+ e_QM_FQ_CHANNEL_FMAN0_SP11,
+
+ e_QM_FQ_CHANNEL_RMAN_SP2 = 0x62, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
+ e_QM_FQ_CHANNEL_RMAN_SP3,
+
+ e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
+ connected to SEC 4.x */
+
+ e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
+ connected to PME */
+ e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
+ connected to RAID */
+} e_QmFQChannel;
+
+/*****************************************************************************
+ BMan INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
+
+/*****************************************************************************
+ FM INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define INTG_MAX_NUM_OF_FM 1
+
+/* Ports defines */
+#define FM_MAX_NUM_OF_1G_MACS 5
+#define FM_MAX_NUM_OF_10G_MACS 1
+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
+#define FM_MAX_NUM_OF_OH_PORTS 7
+
+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
+
+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
+
+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
+#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
+#define FM_MAX_NUM_OF_SUB_PORTALS 12
+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
+
+/* RAMs defines */
+#define FM_MURAM_SIZE (160 * KILOBYTE)
+#define FM_IRAM_SIZE ( 64 * KILOBYTE)
+
+/* PCD defines */
+#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
+#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
+
+/* RTC defines */
+#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
+#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
+
+/* QMI defines */
+#define QMI_MAX_NUM_OF_TNUMS 64
+#define MAX_QMI_DEQ_SUBPORTAL 12
+#define QMI_DEF_TNUMS_THRESH 48
+
+/* FPM defines */
+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
+
+/* DMA defines */
+#define DMA_THRESH_MAX_COMMQ 31
+#define DMA_THRESH_MAX_BUF 127
+
+/* BMI defines */
+#define BMI_MAX_NUM_OF_TASKS 128
+#define BMI_MAX_NUM_OF_DMAS 32
+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
+#define PORT_MAX_WEIGHT 16
+
+
+/**************************************************************************//**
+ @Description Enum for inter-module interrupts registration
+*//***************************************************************************/
+typedef enum e_FmEventModules
+{
+ e_FM_MOD_PRS, /**< Parser event */
+ e_FM_MOD_KG, /**< Keygen event */
+ e_FM_MOD_PLCR, /**< Policer event */
+ e_FM_MOD_10G_MAC, /**< 10G MAC error event */
+ e_FM_MOD_1G_MAC, /**< 1G MAC error event */
+ e_FM_MOD_TMR, /**< Timer event */
+ e_FM_MOD_1G_MAC_TMR, /**< 1G MAC timer event */
+ e_FM_MOD_FMAN_CTRL, /**< FMAN Controller timer event */
+ e_FM_MOD_DUMMY_LAST
+} e_FmEventModules;
+
+/**************************************************************************//**
+ @Description Enum for interrupts types
+*//***************************************************************************/
+typedef enum e_FmIntrType
+{
+ e_FM_INTR_TYPE_ERR,
+ e_FM_INTR_TYPE_NORMAL
+} e_FmIntrType;
+
+/**************************************************************************//**
+ @Description Enum for inter-module interrupts registration
+*//***************************************************************************/
+typedef enum e_FmInterModuleEvent
+{
+ e_FM_EV_PRS, /**< Parser event */
+ e_FM_EV_ERR_PRS, /**< Parser error event */
+ e_FM_EV_KG, /**< Keygen event */
+ e_FM_EV_ERR_KG, /**< Keygen error event */
+ e_FM_EV_PLCR, /**< Policer event */
+ e_FM_EV_ERR_PLCR, /**< Policer error event */
+ e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
+ e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
+ e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
+ e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
+ e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
+ e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
+ e_FM_EV_TMR, /**< Timer event */
+ e_FM_EV_1G_MAC0_TMR, /**< 1G MAC 0 timer event */
+ e_FM_EV_1G_MAC1_TMR, /**< 1G MAC 1 timer event */
+ e_FM_EV_1G_MAC2_TMR, /**< 1G MAC 2 timer event */
+ e_FM_EV_1G_MAC3_TMR, /**< 1G MAC 3 timer event */
+ e_FM_EV_1G_MAC4_TMR, /**< 1G MAC 4 timer event */
+ e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
+ e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
+ e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
+ e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
+ e_FM_EV_DUMMY_LAST
+} e_FmInterModuleEvent;
+
+#define GET_FM_MODULE_EVENT(mod, id, intrType, event) \
+ switch(mod){ \
+ case e_FM_MOD_PRS: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
+ break; \
+ case e_FM_MOD_KG: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
+ break; \
+ case e_FM_MOD_PLCR: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
+ break; \
+ case e_FM_MOD_10G_MAC: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_10G_MAC0 : e_FM_EV_DUMMY_LAST; \
+ break; \
+ case e_FM_MOD_1G_MAC: \
+ switch(id){ \
+ case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC0 : e_FM_EV_DUMMY_LAST; break; \
+ case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC1 : e_FM_EV_DUMMY_LAST; break; \
+ case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC2 : e_FM_EV_DUMMY_LAST; break; \
+ case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC3 : e_FM_EV_DUMMY_LAST; break; \
+ case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_1G_MAC4 : e_FM_EV_DUMMY_LAST; break; \
+ } \
+ break; \
+ case e_FM_MOD_TMR: \
+ if (id) event = e_FM_EV_DUMMY_LAST; \
+ else event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
+ break; \
+ case e_FM_MOD_1G_MAC_TMR: \
+ switch(id){ \
+ case(0): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC0_TMR; break; \
+ case(1): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC1_TMR; break; \
+ case(2): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC2_TMR; break; \
+ case(3): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC3_TMR; break; \
+ case(4): event = (intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_1G_MAC4_TMR; break; \
+ } \
+ break; \
+ case e_FM_MOD_FMAN_CTRL: \
+ if (intrType == e_FM_INTR_TYPE_ERR) event = e_FM_EV_DUMMY_LAST; \
+ else switch(id){ \
+ case(0): event = e_FM_EV_FMAN_CTRL_0; break; \
+ case(1): event = e_FM_EV_FMAN_CTRL_1; break; \
+ case(2): event = e_FM_EV_FMAN_CTRL_2; break; \
+ case(3): event = e_FM_EV_FMAN_CTRL_3; break; \
+ } \
+ break; \
+ default: event = e_FM_EV_DUMMY_LAST; \
+ break;}
+
+#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
+
+/* P5020 unique features */
+#define FM_QMI_DEQ_OPTIONS_SUPPORT
+#define FM_NO_DISPATCH_RAM_ECC
+#define FM_FIFO_ALLOCATION_OLD_ALG
+#define FM_NO_WATCHDOG
+#define FM_NO_TNUM_AGING
+#define FM_NO_TGEC_LOOPBACK
+#define FM_KG_NO_BYPASS_FQID_GEN
+#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
+#define FM_NO_BACKUP_POOLS
+#define FM_NO_OP_OBSERVED_POOLS
+#define FM_NO_ADVANCED_RATE_LIMITER
+#define FM_NO_OP_OBSERVED_CGS
+
+/* FM erratas */
+#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
+#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
+#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
+#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
+
+#define FM_NO_RX_PREAM_ERRATA_DTSECx1
+#define FM_RX_PREAM_4_ERRATA_DTSEC_A001 FM_NO_RX_PREAM_ERRATA_DTSECx1
+#define FM_GRS_ERRATA_DTSEC_A002
+#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
+#define FM_GTS_ERRATA_DTSEC_A004
+#define FM_PAUSE_BLOCK_ERRATA_DTSEC_A006 /* do nothing */
+#define FM_RESERVED_ACCESS_TO_DISABLED_DEV_ERRATA_DTSEC_A0011 /* do nothing */
+#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012 FM_GTS_ERRATA_DTSEC_A004
+#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
+#define FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3
+#define FM_TX_LOCKUP_ERRATA_DTSEC6
+
+#define FM_IM_TX_SYNC_SKIP_TNUM_ERRATA_FMAN_A001 /* Implemented by ucode */
+#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
+#define FM_IM_TX_SHARED_TNUM_ERRATA_FMAN4 /* Implemented by ucode */
+#define FM_IM_GS_DEADLOCK_ERRATA_FMAN5 /* Implemented by ucode */
+#define FM_IM_DEQ_PIPELINE_DEPTH_ERRATA_FMAN10 /* Implemented by ucode */
+#define FM_CC_GEN6_MISSMATCH_ERRATA_FMAN12 /* Implemented by ucode */
+#define FM_CC_CHANGE_SHARED_TNUM_ERRATA_FMAN13 /* Implemented by ucode */
+#define FM_IM_LARGE_MRBLR_ERRATA_FMAN15 /* Implemented by ucode */
+#define FM_BMI_TO_RISC_ENQ_ERRATA_FMANc /* No implementation, Out of LLD scope */
+#define FM_INVALID_SWPRS_DATA_ERRATA_FMANd
+//#define FM_PRS_MPLS_SSA_ERRATA_FMANj /* No implementation, No patch yet */
+//#define FM_PRS_INITIAL_PLANID_ERRATA_FMANk /* No implementation, No patch yet */
+
+#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
+
+#define FM_NO_COPY_CTXA_CTXB_ERRATA_FMAN_SW001
+#define FM_PRS_MEM_ERRATA_FMAN_SW003
+#define FM_LEN_CHECK_ERRATA_FMAN_SW002
+
+#define FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
+
+
+#endif /* __DPAA_INTEGRATION_EXT_H */
diff --git a/sys/contrib/ncsw/inc/integrations/P5020/part_integration_ext.h b/sys/contrib/ncsw/inc/integrations/P5020/part_integration_ext.h
new file mode 100644
index 0000000..5c0f3bb
--- /dev/null
+++ b/sys/contrib/ncsw/inc/integrations/P5020/part_integration_ext.h
@@ -0,0 +1,1004 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ **************************************************************************/
+/**
+
+ @File part_integration_ext.h
+
+ @Description P5020 external definitions and structures.
+*//***************************************************************************/
+#ifndef __PART_INTEGRATION_EXT_H
+#define __PART_INTEGRATION_EXT_H
+
+#include "std_ext.h"
+#include "ddr_std_ext.h"
+#include "enet_ext.h"
+#include "dpaa_integration_ext.h"
+
+
+/**************************************************************************//**
+ @Group P5020_chip_id P5020 Application Programming Interface
+
+ @Description P5020 Chip functions,definitions and enums.
+
+ @{
+*//***************************************************************************/
+
+#define CORE_E500MC
+
+#define INTG_MAX_NUM_OF_CORES 2
+
+
+/**************************************************************************//**
+ @Description Module types.
+*//***************************************************************************/
+typedef enum e_ModuleId
+{
+ e_MODULE_ID_DUART_1 = 0,
+ e_MODULE_ID_DUART_2,
+ e_MODULE_ID_DUART_3,
+ e_MODULE_ID_DUART_4,
+ e_MODULE_ID_LAW,
+ e_MODULE_ID_LBC,
+ e_MODULE_ID_PAMU,
+ e_MODULE_ID_QM, /**< Queue manager module */
+ e_MODULE_ID_BM, /**< Buffer manager module */
+ e_MODULE_ID_QM_CE_PORTAL_0,
+ e_MODULE_ID_QM_CI_PORTAL_0,
+ e_MODULE_ID_QM_CE_PORTAL_1,
+ e_MODULE_ID_QM_CI_PORTAL_1,
+ e_MODULE_ID_QM_CE_PORTAL_2,
+ e_MODULE_ID_QM_CI_PORTAL_2,
+ e_MODULE_ID_QM_CE_PORTAL_3,
+ e_MODULE_ID_QM_CI_PORTAL_3,
+ e_MODULE_ID_QM_CE_PORTAL_4,
+ e_MODULE_ID_QM_CI_PORTAL_4,
+ e_MODULE_ID_QM_CE_PORTAL_5,
+ e_MODULE_ID_QM_CI_PORTAL_5,
+ e_MODULE_ID_QM_CE_PORTAL_6,
+ e_MODULE_ID_QM_CI_PORTAL_6,
+ e_MODULE_ID_QM_CE_PORTAL_7,
+ e_MODULE_ID_QM_CI_PORTAL_7,
+ e_MODULE_ID_QM_CE_PORTAL_8,
+ e_MODULE_ID_QM_CI_PORTAL_8,
+ e_MODULE_ID_QM_CE_PORTAL_9,
+ e_MODULE_ID_QM_CI_PORTAL_9,
+ e_MODULE_ID_BM_CE_PORTAL_0,
+ e_MODULE_ID_BM_CI_PORTAL_0,
+ e_MODULE_ID_BM_CE_PORTAL_1,
+ e_MODULE_ID_BM_CI_PORTAL_1,
+ e_MODULE_ID_BM_CE_PORTAL_2,
+ e_MODULE_ID_BM_CI_PORTAL_2,
+ e_MODULE_ID_BM_CE_PORTAL_3,
+ e_MODULE_ID_BM_CI_PORTAL_3,
+ e_MODULE_ID_BM_CE_PORTAL_4,
+ e_MODULE_ID_BM_CI_PORTAL_4,
+ e_MODULE_ID_BM_CE_PORTAL_5,
+ e_MODULE_ID_BM_CI_PORTAL_5,
+ e_MODULE_ID_BM_CE_PORTAL_6,
+ e_MODULE_ID_BM_CI_PORTAL_6,
+ e_MODULE_ID_BM_CE_PORTAL_7,
+ e_MODULE_ID_BM_CI_PORTAL_7,
+ e_MODULE_ID_BM_CE_PORTAL_8,
+ e_MODULE_ID_BM_CI_PORTAL_8,
+ e_MODULE_ID_BM_CE_PORTAL_9,
+ e_MODULE_ID_BM_CI_PORTAL_9,
+ e_MODULE_ID_FM, /**< Frame manager module */
+ e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
+ e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
+ e_MODULE_ID_FM_BMI, /**< FM BMI block */
+ e_MODULE_ID_FM_QMI, /**< FM QMI block */
+ e_MODULE_ID_FM_PARSER, /**< FM parser block */
+ e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
+ e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_10GRx, /**< FM Rx 10G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
+ e_MODULE_ID_FM_PORT_10GTx, /**< FM Tx 10G MAC port block */
+ e_MODULE_ID_FM_PLCR, /**< FM Policer */
+ e_MODULE_ID_FM_KG, /**< FM Keygen */
+ e_MODULE_ID_FM_DMA, /**< FM DMA */
+ e_MODULE_ID_FM_FPM, /**< FM FPM */
+ e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
+ e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
+ e_MODULE_ID_FM_1GMDIO2, /**< FM 1G MDIO MAC 2*/
+ e_MODULE_ID_FM_1GMDIO3, /**< FM 1G MDIO MAC 3*/
+ e_MODULE_ID_FM_1GMDIO4, /**< FM 1G MDIO MAC 4*/
+ e_MODULE_ID_FM_1GMDIO5, /**< FM 1G MDIO MAC 5*/
+ e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
+ e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
+ e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
+ e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
+ e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
+ e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
+ e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
+ e_MODULE_ID_FM_10GMAC, /**< FM 10G MAC */
+
+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
+
+ e_MODULE_ID_PIC, /**< PIC */
+ e_MODULE_ID_GPIO, /**< GPIO */
+ e_MODULE_ID_SERDES, /**< SERDES */
+ e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
+ e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
+ e_MODULE_ID_DUMMY_LAST
+} e_ModuleId;
+
+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
+
+/* Offsets relative to CCSR base */
+#define P5020_OFFSET_LAW 0x00000c00
+#define P5020_OFFSET_DDR1 0x00008000
+#define P5020_OFFSET_DDR2 0x00009000
+#define P5020_OFFSET_CPC1 0x00010000
+#define P5020_OFFSET_CPC2 0x00011000
+#define P5020_OFFSET_CCF 0x00018000
+#define P5020_OFFSET_PAMU 0x00020000
+#define P5020_OFFSET_PIC 0x00040000
+#define P5020_OFFSET_GUTIL 0x000e0000
+#define P5020_OFFSET_RCPM 0x000e2000
+#define P5020_OFFSET_SERDES 0x000ea000
+#define P5020_OFFSET_DMA1 0x00100100
+#define P5020_OFFSET_DMA2 0x00101100
+#define P5020_OFFSET_ESPI 0x00110000
+#define P5020_OFFSET_ESDHC 0x00114000
+#define P5020_OFFSET_I2C1 0x00118000
+#define P5020_OFFSET_I2C2 0x00118100
+#define P5020_OFFSET_I2C3 0x00119000
+#define P5020_OFFSET_I2C4 0x00119100
+#define P5020_OFFSET_DUART1 0x0011c500
+#define P5020_OFFSET_DUART2 0x0011c600
+#define P5020_OFFSET_DUART3 0x0011d500
+#define P5020_OFFSET_DUART4 0x0011d600
+#define P5020_OFFSET_LBC 0x00124000
+#define P5020_OFFSET_GPIO 0x00130000
+#define P5020_OFFSET_PCIE1 0x00200000
+#define P5020_OFFSET_PCIE2 0x00201000
+#define P5020_OFFSET_PCIE3 0x00202000
+#define P5020_OFFSET_PCIE4 0x00203000
+#define P5020_OFFSET_USB1 0x00210000
+#define P5020_OFFSET_USB2 0x00211000
+#define P5020_OFFSET_USB_PHY 0x00214000
+#define P5020_OFFSET_SATA1 0x00220000
+#define P5020_OFFSET_SATA2 0x00221000
+#define P5020_OFFSET_SEC_GEN 0x00300000
+#define P5020_OFFSET_SEC_JQ0 0x00301000
+#define P5020_OFFSET_SEC_JQ1 0x00302000
+#define P5020_OFFSET_SEC_JQ2 0x00303000
+#define P5020_OFFSET_SEC_JQ3 0x00304000
+#define P5020_OFFSET_SEC_RESERVED 0x00305000
+#define P5020_OFFSET_SEC_RTIC 0x00306000
+#define P5020_OFFSET_SEC_QI 0x00307000
+#define P5020_OFFSET_SEC_DECO0_CCB0 0x00308000
+#define P5020_OFFSET_SEC_DECO1_CCB1 0x00309000
+#define P5020_OFFSET_PME 0x00316000
+#define P5020_OFFSET_QM 0x00318000
+#define P5020_OFFSET_BM 0x0031a000
+#define P5020_OFFSET_RAID 0x00320000
+#define P5020_OFFSET_FM 0x00400000
+
+#define P5020_OFFSET_FM_MURAM P5020_OFFSET_FM
+#define P5020_OFFSET_FM_BMI (P5020_OFFSET_FM + 0x00080000)
+#define P5020_OFFSET_FM_QMI (P5020_OFFSET_FM + 0x00080400)
+#define P5020_OFFSET_FM_PARSER (P5020_OFFSET_FM + 0x00080800)
+#define P5020_OFFSET_FM_PORT_HO1 (P5020_OFFSET_FM + 0x00081000) /* host command/offline parser */
+#define P5020_OFFSET_FM_PORT_HO2 (P5020_OFFSET_FM + 0x00082000)
+#define P5020_OFFSET_FM_PORT_HO3 (P5020_OFFSET_FM + 0x00083000)
+#define P5020_OFFSET_FM_PORT_HO4 (P5020_OFFSET_FM + 0x00084000)
+#define P5020_OFFSET_FM_PORT_HO5 (P5020_OFFSET_FM + 0x00085000)
+#define P5020_OFFSET_FM_PORT_HO6 (P5020_OFFSET_FM + 0x00086000)
+#define P5020_OFFSET_FM_PORT_HO7 (P5020_OFFSET_FM + 0x00087000)
+#define P5020_OFFSET_FM_PORT_1GRX1 (P5020_OFFSET_FM + 0x00088000)
+#define P5020_OFFSET_FM_PORT_1GRX2 (P5020_OFFSET_FM + 0x00089000)
+#define P5020_OFFSET_FM_PORT_1GRX3 (P5020_OFFSET_FM + 0x0008a000)
+#define P5020_OFFSET_FM_PORT_1GRX4 (P5020_OFFSET_FM + 0x0008b000)
+#define P5020_OFFSET_FM_PORT_1GRX5 (P5020_OFFSET_FM + 0x0008c000)
+#define P5020_OFFSET_FM_PORT_10GRX (P5020_OFFSET_FM + 0x00090000)
+#define P5020_OFFSET_FM_PORT_1GTX1 (P5020_OFFSET_FM + 0x000a8000)
+#define P5020_OFFSET_FM_PORT_1GTX2 (P5020_OFFSET_FM + 0x000a9000)
+#define P5020_OFFSET_FM_PORT_1GTX3 (P5020_OFFSET_FM + 0x000aa000)
+#define P5020_OFFSET_FM_PORT_1GTX4 (P5020_OFFSET_FM + 0x000ab000)
+#define P5020_OFFSET_FM_PORT_1GTX5 (P5020_OFFSET_FM + 0x000ac000)
+#define P5020_OFFSET_FM_PORT_10GTX (P5020_OFFSET_FM + 0x000b0000)
+#define P5020_OFFSET_FM_PLCR (P5020_OFFSET_FM + 0x000c0000)
+#define P5020_OFFSET_FM_KG (P5020_OFFSET_FM + 0x000c1000)
+#define P5020_OFFSET_FM_DMA (P5020_OFFSET_FM + 0x000c2000)
+#define P5020_OFFSET_FM_FPM (P5020_OFFSET_FM + 0x000c3000)
+#define P5020_OFFSET_FM_IRAM (P5020_OFFSET_FM + 0x000c4000)
+#define P5020_OFFSET_FM_PARSER_IRAM (P5020_OFFSET_FM + 0x000c7000)
+#define P5020_OFFSET_FM_1GMAC1 (P5020_OFFSET_FM + 0x000e0000)
+#define P5020_OFFSET_FM_1GMDIO (P5020_OFFSET_FM + 0x000e1000 + 0x120)
+#define P5020_OFFSET_FM_1GMAC2 (P5020_OFFSET_FM + 0x000e2000)
+#define P5020_OFFSET_FM_1GMAC3 (P5020_OFFSET_FM + 0x000e4000)
+#define P5020_OFFSET_FM_1GMAC4 (P5020_OFFSET_FM + 0x000e6000)
+#define P5020_OFFSET_FM_1GMAC5 (P5020_OFFSET_FM + 0x000e8000)
+#define P5020_OFFSET_FM_10GMAC (P5020_OFFSET_FM + 0x000f0000)
+#define P5020_OFFSET_FM_10GMDIO (P5020_OFFSET_FM + 0x000f1000 + 0x030)
+#define P5020_OFFSET_FM_RTC (P5020_OFFSET_FM + 0x000fe000)
+
+/* Offsets relative to QM or BM portals base */
+#define P5020_OFFSET_PORTALS_CE_AREA 0x000000 /* cache enabled area */
+#define P5020_OFFSET_PORTALS_CI_AREA 0x100000 /* cache inhibited area */
+
+#define P5020_CE_PORTAL_SIZE 0x4000
+#define P5020_CI_PORTAL_SIZE 0x1000
+
+#define P5020_OFFSET_PORTALS_CE(portal) \
+ (P5020_OFFSET_PORTALS_CE_AREA + P5020_CE_PORTAL_SIZE * (portal))
+#define P5020_OFFSET_PORTALS_CI(portal) \
+ (P5020_OFFSET_PORTALS_CI_AREA + P5020_CI_PORTAL_SIZE * (portal))
+
+
+/**************************************************************************//**
+ @Description Transaction source ID (for memory controllers error reporting).
+*//***************************************************************************/
+typedef enum e_TransSrc
+{
+ e_TRANS_SRC_PCIE_1 = 0x0, /**< PCI Express 1 */
+ e_TRANS_SRC_PCIE_2 = 0x1, /**< PCI Express 2 */
+ e_TRANS_SRC_PCIE_3 = 0x2, /**< PCI Express 3 */
+ e_TRANS_SRC_PCIE_4 = 0x3, /**< PCI Express 4 */
+ e_TRANS_SRC_SRIO_1 = 0x8, /**< SRIO 1 */
+ e_TRANS_SRC_SRIO_2 = 0x9, /**< SRIO 2 */
+ e_TRANS_SRC_BMAN = 0x18, /**< BMan */
+ e_TRANS_SRC_PAMU = 0x1C, /**< PAMU */
+ e_TRANS_SRC_PME = 0x20, /**< PME */
+ e_TRANS_SRC_SEC = 0x21, /**< Security engine */
+ e_TRANS_SRC_RAID = 0x28, /**< RAID engine */
+ e_TRANS_SRC_QMAN = 0x3C, /**< QMan */
+ e_TRANS_SRC_USB_1 = 0x40, /**< USB 1 */
+ e_TRANS_SRC_USB_2 = 0x41, /**< USB 2 */
+ e_TRANS_SRC_ESDHC = 0x44, /**< eSDHC */
+ e_TRANS_SRC_PBL = 0x48, /**< Pre-boot loader */
+ e_TRANS_SRC_NPC = 0x4B, /**< Nexus port controller */
+ e_TRANS_SRC_RMAN = 0x5D, /**< RIO message manager */
+ e_TRANS_SRC_SATA_1 = 0x60, /**< SATA 1 */
+ e_TRANS_SRC_SATA_2 = 0x61, /**< SATA 2 */
+ e_TRANS_SRC_DMA_1 = 0x70, /**< DMA 1 */
+ e_TRANS_SRC_DMA_2 = 0x71, /**< DMA 2 */
+ e_TRANS_SRC_CORE_0_INST = 0x80, /**< Processor 0 (instruction) */
+ e_TRANS_SRC_CORE_0_DATA = 0x81, /**< Processor 0 (data) */
+ e_TRANS_SRC_CORE_1_INST = 0x82, /**< Processor 1 (instruction) */
+ e_TRANS_SRC_CORE_1_DATA = 0x83, /**< Processor 1 (data) */
+ e_TRANS_SRC_FM_10G = 0xC0, /**< FM XAUI */
+ e_TRANS_SRC_FM_HO_1 = 0xC1, /**< FM offline, host 1 */
+ e_TRANS_SRC_FM_HO_2 = 0xC2, /**< FM offline, host 2 */
+ e_TRANS_SRC_FM_HO_3 = 0xC3, /**< FM offline, host 3 */
+ e_TRANS_SRC_FM_HO_4 = 0xC4, /**< FM offline, host 4 */
+ e_TRANS_SRC_FM_HO_5 = 0xC5, /**< FM offline, host 5 */
+ e_TRANS_SRC_FM_HO_6 = 0xC6, /**< FM offline, host 6 */
+ e_TRANS_SRC_FM_HO_7 = 0xC7, /**< FM offline, host 7 */
+ e_TRANS_SRC_FM_GETH_1 = 0xC8, /**< FM GETH 1 */
+ e_TRANS_SRC_FM_GETH_2 = 0xC9, /**< FM GETH 2 */
+ e_TRANS_SRC_FM_GETH_3 = 0xCA, /**< FM GETH 3 */
+ e_TRANS_SRC_FM_GETH_4 = 0xCB, /**< FM GETH 4 */
+ e_TRANS_SRC_FM_GETH_5 = 0xCC /**< FM GETH 5 */
+} e_TransSrc;
+
+/**************************************************************************//**
+ @Description Local Access Window Target interface ID
+*//***************************************************************************/
+typedef enum e_P5020LawTargetId
+{
+ e_P5020_LAW_TARGET_PCIE_1 = 0x0, /**< PCI Express 1 */
+ e_P5020_LAW_TARGET_PCIE_2 = 0x1, /**< PCI Express 2 */
+ e_P5020_LAW_TARGET_PCIE_3 = 0x2, /**< PCI Express 3 */
+ e_P5020_LAW_TARGET_PCIE_4 = 0x3, /**< PCI Express 4 */
+ e_P5020_LAW_TARGET_SRIO_1 = 0x8, /**< SRIO 1 */
+ e_P5020_LAW_TARGET_SRIO_2 = 0x9, /**< SRIO 2 */
+ e_P5020_LAW_TARGET_LOCAL_SPACE = 0xF, /**< Inbound ATMUs */
+ e_P5020_LAW_TARGET_DDR_CPC_1 = 0x10, /**< DDR controller 1 or CPC 1 SRAM */
+ e_P5020_LAW_TARGET_DDR_CPC_2 = 0x11, /**< DDR controller 2 or CPC 2 SRAM */
+ e_P5020_LAW_TARGET_DDR_CPC_INTLV = 0x14, /**< Interleaved DDR controllers or CPC SRAM */
+ e_P5020_LAW_TARGET_BMAN = 0x18, /**< BMAN target interface ID */
+ e_P5020_LAW_TARGET_DCSR = 0x1D, /**< DCSR */
+ e_P5020_LAW_TARGET_LBC = 0x1F, /**< Local Bus target interface ID */
+ e_P5020_LAW_TARGET_QMAN = 0x3C, /**< QMAN target interface ID */
+ e_P5020_LAW_TARGET_NONE = 0xFF /**< None */
+} e_P5020LawTargetId;
+
+/***************************************************************
+ P5020 general routines
+****************************************************************/
+/**************************************************************************//**
+ @Group P5020_init_grp P5020 Initialization Unit
+
+ @Description P5020 initialization unit API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Description Part ID and revision number
+*//***************************************************************************/
+typedef enum e_P5020DeviceName
+{
+ e_P5020_REV_INVALID = 0x00000000, /**< Invalid revision */
+ e_P5020_REV_1_0 = (int)0x82280010, /**< P5020 with security, revision 1.0 */
+ e_P5020_REV_1_0_NO_SEC = (int)0x82200010, /**< P5020 without security, revision 1.0 */
+ e_P5010_REV_1_0 = (int)0x82290010, /**< P5010 with security, revision 1.0 */
+ e_P5010_REV_1_0_NO_SEC = (int)0x82210010 /**< P5010 without security, revision 1.0 */
+} e_P5020DeviceName;
+
+/**************************************************************************//**
+ @Description Device Disable Register
+*//***************************************************************************/
+typedef enum e_P5020DeviceDisable
+{
+ e_P5020_DEV_DISABLE_PCIE_1 = 0, /**< PCI Express controller 1 disable */
+ e_P5020_DEV_DISABLE_PCIE_2, /**< PCI Express controller 2 disable */
+ e_P5020_DEV_DISABLE_PCIE_3, /**< PCI Express controller 3 disable */
+ e_P5020_DEV_DISABLE_PCIE_4, /**< PCI Express controller 4 disable */
+ e_P5020_DEV_DISABLE_RMAN, /**< RapidIO message manager disable */
+ e_P5020_DEV_DISABLE_SRIO_1, /**< Serial RapidIO controller 1 disable */
+ e_P5020_DEV_DISABLE_SRIO_2, /**< Serial RapidIO controller 2 disable */
+ e_P5020_DEV_DISABLE_DMA_1 = 9, /**< DMA controller 1 disable */
+ e_P5020_DEV_DISABLE_DMA_2, /**< DMA controller 2 disable */
+ e_P5020_DEV_DISABLE_DDR_1, /**< DDR controller 1 disable */
+ e_P5020_DEV_DISABLE_DDR_2, /**< DDR controller 2 disable */
+ e_P5020_DEV_DISABLE_SATA_1 = 17, /**< SATA controller 1 disable */
+ e_P5020_DEV_DISABLE_SATA_2, /**< SATA controller 2 disable */
+ e_P5020_DEV_DISABLE_LBC, /**< eLBC controller disable */
+ e_P5020_DEV_DISABLE_USB_1, /**< USB controller 1 disable */
+ e_P5020_DEV_DISABLE_USB_2, /**< USB controller 2 disable */
+ e_P5020_DEV_DISABLE_ESDHC = 23, /**< eSDHC controller disable */
+ e_P5020_DEV_DISABLE_GPIO, /**< GPIO controller disable */
+ e_P5020_DEV_DISABLE_ESPI, /**< eSPI controller disable */
+ e_P5020_DEV_DISABLE_I2C_1, /**< I2C module 1 (controllers 1 and 2) disable */
+ e_P5020_DEV_DISABLE_I2C_2, /**< I2C module 2 (controllers 3 and 4) disable */
+ e_P5020_DEV_DISABLE_DUART_1 = 30, /**< DUART controller 1 disable */
+ e_P5020_DEV_DISABLE_DUART_2, /**< DUART controller 2 disable */
+ e_P5020_DEV_DISABLE_DISR1_DUMMY_LAST = 32,
+ /**< Dummy entry signing end of DEVDISR1 register controllers */
+ e_P5020_DEV_DISABLE_PME = e_P5020_DEV_DISABLE_DISR1_DUMMY_LAST,
+ /**< Pattern match engine disable */
+ e_P5020_DEV_DISABLE_SEC, /**< Security disable */
+ e_P5020_DEV_DISABLE_RAID, /**< RAID engine disable */
+ e_P5020_DEV_DISABLE_QM_BM = e_P5020_DEV_DISABLE_DISR1_DUMMY_LAST + 4,
+ /**< Queue manager/buffer manager disable */
+ e_P5020_DEV_DISABLE_FM = e_P5020_DEV_DISABLE_DISR1_DUMMY_LAST + 6,
+ /**< Frame manager disable */
+ e_P5020_DEV_DISABLE_10G, /**< 10G Ethernet controller disable */
+ e_P5020_DEV_DISABLE_DTSEC_1, /**< dTSEC controller 1 disable */
+ e_P5020_DEV_DISABLE_DTSEC_2, /**< dTSEC controller 2 disable */
+ e_P5020_DEV_DISABLE_DTSEC_3, /**< dTSEC controller 3 disable */
+ e_P5020_DEV_DISABLE_DTSEC_4, /**< dTSEC controller 4 disable */
+ e_P5020_DEV_DISABLE_DTSEC_5 /**< dTSEC controller 5 disable */
+} e_P5020DeviceDisable;
+
+
+/**************************************************************************//*
+ @Description structure representing P5020 devices configuration
+*//***************************************************************************/
+typedef struct t_P5020Devices
+{
+ struct
+ {
+ struct
+ {
+ bool enabled;
+ uint8_t serdesBank;
+ uint16_t serdesLane; /**< Most significant bits represent lanes used by this bank,
+ one bit for lane, lane A is the first and so on, e.g.,
+ set 0xF000 for ABCD lanes */
+ e_EnetInterface ethIf;
+ uint8_t ratio;
+ bool divByTwo;
+ bool isTwoHalfSgmii;
+ } dtsecs[FM_MAX_NUM_OF_1G_MACS];
+ struct
+ {
+ bool enabled;
+ uint8_t serdesBank;
+ uint16_t serdesLane;
+ } tgec;
+ } fm;
+} t_P5020Devices;
+
+/**************************************************************************//**
+ @Function P5020_GetRevInfo
+
+ @Description Obtain revision information.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return Part ID and revision.
+*//***************************************************************************/
+e_P5020DeviceName P5020_GetRevInfo(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P5020_GetE500Factor
+
+ @Description Obtain core's multiplication factors.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+ @Param[in] coreIndex - Core index.
+ @Param[out] p_E500MulFactor - E500 to CCB multification factor.
+ @Param[out] p_E500DivFactor - E500 to CCB division factor.
+
+*//***************************************************************************/
+void P5020_GetE500Factor(uintptr_t gutilBase,
+ uint8_t coreIndex,
+ uint32_t *p_E500MulFactor,
+ uint32_t *p_E500DivFactor);
+
+/**************************************************************************//**
+ @Function P5020_GetCcbFactor
+
+ @Description Obtain system multiplication factor.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return System multiplication factor.
+*//***************************************************************************/
+uint32_t P5020_GetCcbFactor(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P5020_GetDdrFactor
+
+ @Description Obtain DDR clock multiplication factor.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return DDR clock multiplication factor.
+*//***************************************************************************/
+uint32_t P5020_GetDdrFactor(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P5020_GetDdrType
+
+ @Description Obtain DDR memory type.
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+
+ @Return DDR type.
+*//***************************************************************************/
+e_DdrType P5020_GetDdrType(uintptr_t gutilBase);
+
+/**************************************************************************//**
+ @Function P5020_GetFmFactor
+
+ @Description returns FM multiplication factors. (This value is returned using
+ two parameters to avoid using float parameter).
+
+ @Param[in] gutilBase - Gutil memory map virtual base address.
+ @Param[out] p_FmMulFactor - FM to CCB multification factor.
+ @Param[out] p_FmDivFactor - FM to CCB division factor.
+
+*//***************************************************************************/
+void P5020_GetFmFactor(uintptr_t gutilBase,
+ uint32_t *p_FmMulFactor,
+ uint32_t *p_FmDivFactor);
+
+
+void P5020_CoreTimeBaseEnable(uintptr_t rcpmBase);
+void P5020_CoreTimeBaseDisable(uintptr_t rcpmBase);
+
+typedef enum e_SerdesProtocol
+{
+ SRDS_PROTOCOL_NONE = 0,
+ SRDS_PROTOCOL_PCIE1,
+ SRDS_PROTOCOL_PCIE2,
+ SRDS_PROTOCOL_PCIE3,
+ SRDS_PROTOCOL_PCIE4,
+ SRDS_PROTOCOL_SRIO1,
+ SRDS_PROTOCOL_SRIO2,
+ SRDS_PROTOCOL_SGMII_FM,
+ SRDS_PROTOCOL_XAUI_FM,
+ SRDS_PROTOCOL_SATA1,
+ SRDS_PROTOCOL_SATA2,
+ SRDS_PROTOCOL_AURORA
+} e_SerdesProtocol;
+
+t_Error P5020_DeviceDisable(uintptr_t gutilBase, e_P5020DeviceDisable device, bool disable);
+void P5020_GetDevicesConfiguration(uintptr_t gutilBase, t_P5020Devices *p_Devices);
+t_Error P5020_PamuDisableBypass(uintptr_t gutilBase, uint8_t pamuId, bool disable);
+uint32_t P5020_SerdesRcwGetProtocol(uintptr_t gutilBase);
+bool P5020_SerdesRcwIsDeviceConfigured(uintptr_t gutilBase, e_SerdesProtocol device);
+bool P5020_SerdesRcwIsLaneEnabled(uintptr_t gutilBase, uint32_t lane);
+
+/** @} */ /* end of P5020_init_grp group */
+/** @} */ /* end of P5020_grp group */
+
+
+/*****************************************************************************
+ INTEGRATION-SPECIFIC MODULE CODES
+******************************************************************************/
+#define MODULE_UNKNOWN 0x00000000
+#define MODULE_MEM 0x00010000
+#define MODULE_MM 0x00020000
+#define MODULE_CORE 0x00030000
+#define MODULE_P5020 0x00040000
+#define MODULE_P5020_PLATFORM 0x00050000
+#define MODULE_PM 0x00060000
+#define MODULE_MMU 0x00070000
+#define MODULE_PIC 0x00080000
+#define MODULE_CPC 0x00090000
+#define MODULE_DUART 0x000a0000
+#define MODULE_SERDES 0x000b0000
+#define MODULE_PIO 0x000c0000
+#define MODULE_QM 0x000d0000
+#define MODULE_BM 0x000e0000
+#define MODULE_SEC 0x000f0000
+#define MODULE_LAW 0x00100000
+#define MODULE_LBC 0x00110000
+#define MODULE_PAMU 0x00120000
+#define MODULE_FM 0x00130000
+#define MODULE_FM_MURAM 0x00140000
+#define MODULE_FM_PCD 0x00150000
+#define MODULE_FM_RTC 0x00160000
+#define MODULE_FM_MAC 0x00170000
+#define MODULE_FM_PORT 0x00180000
+#define MODULE_DPA 0x00190000
+#define MODULE_MII 0x001a0000
+#define MODULE_I2C 0x001b0000
+#define MODULE_DMA 0x001c0000
+#define MODULE_DDR 0x001d0000
+#define MODULE_ESPI 0x001e0000
+
+/*****************************************************************************
+ PAMU INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define PAMU_NUM_OF_PARTITIONS 4
+
+
+/*****************************************************************************
+ LAW INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define LAW_NUM_OF_WINDOWS 32
+#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
+#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
+
+
+/*****************************************************************************
+ LBC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+/**************************************************************************//**
+ @Group lbc_exception_grp LBC Exception Unit
+
+ @Description LBC Exception unit API functions, definitions and enums
+
+ @{
+*//***************************************************************************/
+
+/**************************************************************************//**
+ @Anchor lbc_exbm
+
+ @Collection LBC Errors Bit Mask
+
+ These errors are reported through the exceptions callback..
+ The values can be or'ed in any combination in the errors mask
+ parameter of the errors report structure.
+
+ These errors can also be passed as a bit-mask to
+ LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
+ for enabling or disabling error checking.
+ @{
+*//***************************************************************************/
+#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
+#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
+#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
+#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
+
+#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
+ LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
+ /**< All possible errors */
+/* @} */
+/** @} */ /* end of lbc_exception_grp group */
+
+#define LBC_INCORRECT_ERROR_REPORT_ERRATA
+
+#define LBC_NUM_OF_BANKS 8
+#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
+#define LBC_PARITY_SUPPORT
+#define LBC_ADDRESS_HOLD_TIME_CTRL
+#define LBC_HIGH_CLK_DIVIDERS
+#define LBC_FCM_AVAILABLE
+
+/*****************************************************************************
+ GPIO INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
+ Each port contains up to 32 I/O pins. */
+
+#define GPIO_VALID_PIN_MASKS \
+ { /* Port A */ 0xFFFFFFFF }
+
+#define GPIO_VALID_INTR_MASKS \
+ { /* Port A */ 0xFFFFFFFF }
+
+
+/*****************************************************************************
+ SERDES INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define SRDS_MAX_LANES 18
+#define SRDS_MAX_BANK 3
+
+/* Serdes lanes general information provided in the following form:
+ 1) Lane index in Serdes Control Registers Map
+ 2) Lane enable/disable bit number in RCW
+ 3) Lane bank index */
+#define SRDS_LANES \
+{ \
+ { 0, 152, 0 }, \
+ { 1, 153, 0 }, \
+ { 2, 154, 0 }, \
+ { 3, 155, 0 }, \
+ { 4, 156, 0 }, \
+ { 5, 157, 0 }, \
+ { 6, 158, 0 }, \
+ { 7, 159, 0 }, \
+ { 8, 160, 0 }, \
+ { 9, 161, 0 }, \
+ { 16, 162, 1 }, \
+ { 17, 163, 1 }, \
+ { 18, 164, 1 }, \
+ { 19, 165, 1 }, \
+ { 20, 166, 2 }, \
+ { 21, 167, 2 }, \
+ { 22, 168, 2 }, \
+ { 23, 169, 2 } \
+}
+
+#define SRDS_PROTOCOL_ALL_OPTIONS
+/* Serdes lanes assignment and multiplexing.
+ Each option is selected by SRDS_PRTCL bits of RCW. */
+#define SRDS_PROTOCOL_OPTIONS \
+/* Protocol Lane assignment */ \
+{ \
+/* 0x00 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_PCIE4, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x01 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_PCIE4, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x02 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_PCIE4, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x03 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x04 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x05 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x06 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x07 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x08 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x09 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x0A */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x0B */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x0C */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x0D */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x0E */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x0F */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x10 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x11 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x12 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x13 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x14 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x15 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x16 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1}, \
+/* 0x17 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x18 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x19 */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x1A */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x1B */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x1C */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x1D */ {SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x1E */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x1F */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x20 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x21 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x22 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x23 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x24 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x25 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x26 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM}, \
+/* 0x27 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x28 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x29 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x2A */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x2B */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x2C */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x2D */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x2E */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x2F */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO2, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x30 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x31 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_SGMII_FM, 0, 0, 0}, \
+/* 0x32 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM}, \
+/* 0x33 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, SRDS_PROTOCOL_SRIO1, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x34 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x35 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x36 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2}, \
+/* 0x37 */ {SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE1, SRDS_PROTOCOL_PCIE3, SRDS_PROTOCOL_PCIE3, \
+ SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_PCIE2, SRDS_PROTOCOL_SGMII_FM, SRDS_PROTOCOL_SGMII_FM, \
+ SRDS_PROTOCOL_AURORA, SRDS_PROTOCOL_AURORA, \
+ SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, SRDS_PROTOCOL_XAUI_FM, \
+ 0, 0, SRDS_PROTOCOL_SATA1, SRDS_PROTOCOL_SATA2} \
+}
+
+/*****************************************************************************
+ DDR INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define DDR_NUM_OF_VALID_CS 4
+
+/*****************************************************************************
+ DMA INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+#define DMA_NUM_OF_CONTROLLERS 2
+
+/*****************************************************************************
+ CPC INTEGRATION-SPECIFIC DEFINITIONS
+******************************************************************************/
+
+#define CPC_MAX_SIZE_SRAM_ERRATA_CPC4
+#define CPC_HARDWARE_FLUSH_ERRATA_CPC10
+
+
+#endif /* __PART_INTEGRATION_EXT_H */
diff --git a/sys/contrib/ncsw/inc/integrations/part_ext.h b/sys/contrib/ncsw/inc/integrations/part_ext.h
new file mode 100644
index 0000000..015db86
--- /dev/null
+++ b/sys/contrib/ncsw/inc/integrations/part_ext.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+
+ @File part_ext.h
+
+ @Description Definitions for the part (integration) module.
+*//***************************************************************************/
+
+#ifndef __PART_EXT_H
+#define __PART_EXT_H
+
+#include "std_ext.h"
+#include "part_integration_ext.h"
+
+
+#if !(defined(MPC8306) || \
+ defined(MPC8309) || \
+ defined(MPC834x) || \
+ defined(MPC836x) || \
+ defined(MPC832x) || \
+ defined(MPC837x) || \
+ defined(MPC8568) || \
+ defined(MPC8569) || \
+ defined(P1020) || \
+ defined(P1021) || \
+ defined(P1022) || \
+ defined(P1023) || \
+ defined(P2020) || \
+ defined(P2040) || \
+ defined(P2041) || \
+ defined(P3041) || \
+ defined(P4080) || \
+ defined(SC4080) || \
+ defined(P5020) || \
+ defined(MSC814x))
+#error "unable to proceed without chip-definition"
+#endif /* !(defined(MPC834x) || ... */
+
+
+/**************************************************************************//*
+ @Description Part data structure - must be contained in any integration
+ data structure.
+*//***************************************************************************/
+typedef struct t_Part
+{
+ uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
+ /**< Returns the address of the module's memory map base. */
+ e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
+ /**< Returns the module's ID according to its memory map base. */
+} t_Part;
+
+
+#endif /* __PART_EXT_H */
diff --git a/sys/contrib/ncsw/inc/math_ext.h b/sys/contrib/ncsw/inc/math_ext.h
new file mode 100644
index 0000000..95b9560
--- /dev/null
+++ b/sys/contrib/ncsw/inc/math_ext.h
@@ -0,0 +1,98 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MATH_EXT_H
+#define __MATH_EXT_H
+
+
+#if defined(NCSW_LINUX) && defined(__KERNEL__)
+#include <linux/math.h>
+
+#elif defined(__MWERKS__)
+#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
+#define HIGH(x) (*(int32_t*)&x)
+#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
+#define UHIGH(x) (*(uint32_t*)&x)
+
+static const double big = 1.0e300;
+
+/* Macro for checking if a number is a power of 2 */
+static __inline__ double ceil(double x)
+{
+ int32_t i0,i1,j0; /*- cc 020130 -*/
+ uint32_t i,j; /*- cc 020130 -*/
+ i0 = HIGH(x);
+ i1 = LOW(x);
+ j0 = ((i0>>20)&0x7ff)-0x3ff;
+ if(j0<20) {
+ if(j0<0) { /* raise inexact if x != 0 */
+ if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
+ if(i0<0) {i0=0x80000000;i1=0;}
+ else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+ }
+ } else {
+ i = (uint32_t)(0x000fffff)>>j0;
+ if(((i0&i)|i1)==0) return x; /* x is integral */
+ if(big+x>0.0) { /* raise inexact flag */
+ if(i0>0) i0 += (0x00100000)>>j0;
+ i0 &= (~i); i1=0;
+ }
+ }
+ } else if (j0>51) {
+ if(j0==0x400) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
+ } else {
+ i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
+ if((i1&i)==0) return x; /* x is integral */
+ if(big+x>0.0) { /* raise inexact flag */
+ if(i0>0) {
+ if(j0==20) i0+=1;
+ else {
+ j = (uint32_t)(i1 + (1<<(52-j0)));
+ if(j<i1) i0+=1; /* got a carry */
+ i1 = (int32_t)j;
+ }
+ }
+ i1 &= (~i);
+ }
+ }
+ HIGH(x) = i0;
+ LOW(x) = i1;
+ return x;
+}
+
+#else
+#include <math.h>
+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
+
+
+#endif /* __MATH_EXT_H */
diff --git a/sys/contrib/ncsw/inc/ncsw_ext.h b/sys/contrib/ncsw/inc/ncsw_ext.h
new file mode 100644
index 0000000..e9f059d
--- /dev/null
+++ b/sys/contrib/ncsw/inc/ncsw_ext.h
@@ -0,0 +1,430 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**************************************************************************//**
+ @File ncsw_ext.h
+
+ @Description General NetCommSw Standard Definitions
+*//***************************************************************************/
+
+#ifndef __NCSW_EXT_H
+#define __NCSW_EXT_H
+
+#include "memcpy_ext.h"
+
+
+#define WRITE_BLOCK IOMemSet32
+#define COPY_BLOCK Mem2IOCpy32
+
+#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
+#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
+
+#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
+
+
+#define WRITE_UINT8_UINT24(arg, data08, data24) WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
+#define WRITE_UINT24_UINT8(arg, data24, data08) WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
+
+/* Little-Endian access macros */
+
+#define WRITE_UINT16_LE(arg, data) \
+ WRITE_UINT16((arg), SwapUint16(data))
+
+#define WRITE_UINT32_LE(arg, data) \
+ WRITE_UINT32((arg), SwapUint32(data))
+
+#define WRITE_UINT64_LE(arg, data) \
+ WRITE_UINT64((arg), SwapUint64(data))
+
+#define GET_UINT16_LE(arg) \
+ SwapUint16(GET_UINT16(arg))
+
+#define GET_UINT32_LE(arg) \
+ SwapUint32(GET_UINT32(arg))
+
+#define GET_UINT64_LE(arg) \
+ SwapUint64(GET_UINT64(arg))
+
+/* Write and Read again macros */
+#define WRITE_UINT_SYNC(size, arg, data) \
+ do { \
+ WRITE_UINT##size((arg), (data)); \
+ CORE_MemoryBarrier(); \
+ } while (0)
+
+#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
+
+#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
+#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
+
+#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
+
+
+/*----------------------*/
+/* Miscellaneous macros */
+/*----------------------*/
+
+#define UNUSED(X) (X=X)
+
+#define KILOBYTE 0x400UL /* 1024 */
+#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
+#define GIGABYTE (KILOBYTE * MEGABYTE) /* 1024*1024*1024 */
+
+#undef NO_IRQ
+#define NO_IRQ (-1)
+#define NCSW_MASTER_ID (0)
+
+/* Macro for checking if a number is a power of 2 */
+#define POWER_OF_2(n) (!((n) & ((n)-1)))
+
+/* Macro for calculating log of base 2 */
+#define LOG2(num, log2Num) \
+ do \
+ { \
+ uint64_t tmp = (num); \
+ log2Num = 0; \
+ while (tmp > 1) \
+ { \
+ log2Num++; \
+ tmp >>= 1; \
+ } \
+ } while (0)
+
+#define NEXT_POWER_OF_2(_num, _nextPow) \
+do \
+{ \
+ if (POWER_OF_2(_num)) \
+ _nextPow = (_num); \
+ else \
+ { \
+ uint64_t tmp = (_num); \
+ _nextPow = 1; \
+ while (tmp) \
+ { \
+ _nextPow <<= 1; \
+ tmp >>= 1; \
+ } \
+ } \
+} while (0)
+
+/* Ceiling division - not the fastest way, but safer in terms of overflow */
+#define DIV_CEIL(x,y) (((x)/(y)) + ((((((x)/(y)))*(y)) == (x)) ? 0 : 1))
+
+/* Round up a number to be a multiple of a second number */
+#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
+
+/* Timing macro for converting usec units to number of ticks. */
+/* (number of usec * clock_Hz) / 1,000,000) - since */
+/* clk is in MHz units, no division needed. */
+#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
+#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
+
+/* Timing macros for converting between nsec units and number of clocks. */
+#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
+#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
+
+/* Timing macros for converting between psec units and number of clocks. */
+#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
+#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
+
+/* Min, Max macros */
+#define NCSW_MIN(a,b) ((a) < (b) ? (a) : (b))
+#define NCSW_MAX(a,b) ((a) > (b) ? (a) : (b))
+#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
+
+#define ABS(a) ((a<0)?(a*-1):a)
+
+#if !(defined(ARRAY_SIZE))
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#endif /* !defined(ARRAY_SIZE) */
+
+
+/* possible alignments */
+#define HALF_WORD_ALIGNMENT 2
+#define WORD_ALIGNMENT 4
+#define DOUBLE_WORD_ALIGNMENT 8
+#define BURST_ALIGNMENT 32
+
+#define HALF_WORD_ALIGNED 0x00000001
+#define WORD_ALIGNED 0x00000003
+#define DOUBLE_WORD_ALIGNED 0x00000007
+#define BURST_ALIGNED 0x0000001f
+#ifndef IS_ALIGNED
+#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
+#endif /* IS_ALIGNED */
+
+
+#define LAST_BUF 1
+#define FIRST_BUF 2
+#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
+#define MIDDLE_BUF 4
+
+#define ARRAY_END -1
+
+#define ILLEGAL_BASE (~0)
+
+#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
+#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
+
+
+/**************************************************************************//**
+ @Description Timers operation mode
+*//***************************************************************************/
+typedef enum e_TimerMode
+{
+ e_TIMER_MODE_INVALID = 0,
+ e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
+ after reaching the reference value. */
+ e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
+ after reaching the reference value. */
+ e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
+ after reaching the reference value. */
+} e_TimerMode;
+
+
+/**************************************************************************//**
+ @Description Enumeration (bit flags) of communication modes (Transmit,
+ receive or both).
+*//***************************************************************************/
+typedef enum e_CommMode
+{
+ e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
+ e_COMM_MODE_RX = 1, /**< Only receive communication */
+ e_COMM_MODE_TX = 2, /**< Only transmit communication */
+ e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
+} e_CommMode;
+
+/**************************************************************************//**
+ @Description General Diagnostic Mode
+*//***************************************************************************/
+typedef enum e_DiagMode
+{
+ e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
+ e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
+ e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
+ controller; e.g. IO-pins, SerDes, etc. */
+ e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
+ e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
+ e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
+ e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
+} e_DiagMode;
+
+/**************************************************************************//**
+ @Description Possible RxStore callback responses.
+*//***************************************************************************/
+typedef enum e_RxStoreResponse
+{
+ e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
+ in polling mode, start again invoking callback
+ only next time user invokes the receive routine;
+ in interrupt mode, start again invoking callback
+ only next time a receive event triggers an interrupt;
+ in all cases, received data that are pending are not
+ lost, rather, their processing is temporarily deferred;
+ in all cases, received data are processed in the order
+ in which they were received. */
+ , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
+} e_RxStoreResponse;
+
+
+/**************************************************************************//**
+ @Description General Handle
+*//***************************************************************************/
+typedef void * t_Handle; /**< handle, used as object's descriptor */
+
+/**************************************************************************//**
+ @Description MUTEX type
+*//***************************************************************************/
+typedef uint32_t t_Mutex;
+
+/**************************************************************************//**
+ @Description Error Code.
+
+ The high word of the error code is the code of the software
+ module (driver). The low word is the error type (e_ErrorType).
+ To get the values from the error code, use GET_ERROR_TYPE()
+ and GET_ERROR_MODULE().
+*//***************************************************************************/
+typedef uint32_t t_Error;
+
+/**************************************************************************//**
+ @Description General prototype of interrupt service routine (ISR).
+
+ @Param[in] handle - Optional handle of the module handling the interrupt.
+
+ @Return None
+ *//***************************************************************************/
+typedef void (t_Isr)(t_Handle handle);
+
+/**************************************************************************//**
+ @Anchor mem_attr
+
+ @Collection Memory Attributes
+
+ Various attributes of memory partitions. These values may be
+ or'ed together to create a mask of all memory attributes.
+ @{
+*//***************************************************************************/
+#define MEMORY_ATTR_CACHEABLE 0x00000001
+ /**< Memory is cacheable */
+#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
+ /**< Memory can be accessed by QUICC Engine
+ through its secondary bus interface */
+
+/* @} */
+
+
+/**************************************************************************//**
+ @Function t_GetBufFunction
+
+ @Description User callback function called by driver to get data buffer.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_BufferPool - A handle to buffer pool manager
+ @Param[out] p_BufContextHandle - Returns the user's private context that
+ should be associated with the buffer
+
+ @Return Pointer to data buffer, NULL if error
+ *//***************************************************************************/
+typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
+ t_Handle *p_BufContextHandle);
+
+/**************************************************************************//**
+ @Function t_PutBufFunction
+
+ @Description User callback function called by driver to return data buffer.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_BufferPool - A handle to buffer pool manager
+ @Param[in] p_Buffer - A pointer to buffer to return
+ @Param[in] h_BufContext - The user's private context associated with
+ the returned buffer
+
+ @Return E_OK on success; Error code otherwise
+ *//***************************************************************************/
+typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
+ uint8_t *p_Buffer,
+ t_Handle h_BufContext);
+
+/**************************************************************************//**
+ @Function t_PhysToVirt
+
+ @Description Translates a physical address to the matching virtual address.
+
+ @Param[in] addr - The physical address to translate.
+
+ @Return Virtual address.
+*//***************************************************************************/
+typedef void * t_PhysToVirt(physAddress_t addr);
+
+/**************************************************************************//**
+ @Function t_VirtToPhys
+
+ @Description Translates a virtual address to the matching physical address.
+
+ @Param[in] addr - The virtual address to translate.
+
+ @Return Physical address.
+*//***************************************************************************/
+typedef physAddress_t t_VirtToPhys(void *addr);
+
+/**************************************************************************//**
+ @Description Buffer Pool Information Structure.
+*//***************************************************************************/
+typedef struct t_BufferPoolInfo
+{
+ t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
+ t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
+ t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
+ uint16_t bufferSize; /**< Buffer size (in bytes) */
+
+ t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
+ physical addresses to virtual addresses */
+ t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
+ virtual addresses to physical addresses */
+} t_BufferPoolInfo;
+
+
+/**************************************************************************//**
+ @Description User callback function called by driver when transmit completed.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App - Application's handle, as was provided to the
+ driver by the user
+ @Param[in] queueId - Transmit queue ID
+ @Param[in] p_Data - Pointer to the data buffer
+ @Param[in] h_BufContext - The user's private context associated with
+ the given data buffer
+ @Param[in] status - Transmit status and errors
+ @Param[in] flags - Driver-dependent information
+ *//***************************************************************************/
+typedef void (t_TxConfFunction)(t_Handle h_App,
+ uint32_t queueId,
+ uint8_t *p_Data,
+ t_Handle h_BufContext,
+ uint16_t status,
+ uint32_t flags);
+
+/**************************************************************************//**
+ @Description User callback function called by driver with receive data.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_App - Application's handle, as was provided to the
+ driver by the user
+ @Param[in] queueId - Receive queue ID
+ @Param[in] p_Data - Pointer to the buffer with received data
+ @Param[in] h_BufContext - The user's private context associated with
+ the given data buffer
+ @Param[in] length - Length of received data
+ @Param[in] status - Receive status and errors
+ @Param[in] position - Position of buffer in frame
+ @Param[in] flags - Driver-dependent information
+
+ @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
+ operation for all ready data.
+ @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
+ *//***************************************************************************/
+typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
+ uint32_t queueId,
+ uint8_t *p_Data,
+ t_Handle h_BufContext,
+ uint32_t length,
+ uint16_t status,
+ uint8_t position,
+ uint32_t flags);
+
+
+#endif /* __NCSW_EXT_H */
diff --git a/sys/contrib/ncsw/inc/net_ext.h b/sys/contrib/ncsw/inc/net_ext.h
new file mode 100644
index 0000000..c41b7c9
--- /dev/null
+++ b/sys/contrib/ncsw/inc/net_ext.h
@@ -0,0 +1,388 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File net_ext.h
+
+ @Description This file contains common and general netcomm headers definitions.
+*//***************************************************************************/
+#ifndef __NET_EXT_H
+#define __NET_EXT_H
+
+#include "std_ext.h"
+
+
+typedef uint8_t headerFieldPpp_t;
+
+#define NET_HEADER_FIELD_PPP_PID (1)
+#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
+#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
+
+
+typedef uint8_t headerFieldPppoe_t;
+
+#define NET_HEADER_FIELD_PPPoE_VER (1)
+#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
+#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
+#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
+#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
+#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
+#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
+#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
+
+#define NET_HEADER_FIELD_PPPMUX_PID (1)
+#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
+#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
+#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
+
+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
+
+
+typedef uint8_t headerFieldEth_t;
+
+#define NET_HEADER_FIELD_ETH_DA (1)
+#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
+#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
+#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
+#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
+#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
+#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
+
+
+typedef uint16_t headerFieldIpv4_t;
+
+#define NET_HEADER_FIELD_IPv4_VER (1)
+#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
+#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
+#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
+#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
+#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
+#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
+#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
+#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
+#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
+#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
+#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
+#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
+#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
+#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
+#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
+
+
+typedef uint8_t headerFieldIpv6_t;
+
+#define NET_HEADER_FIELD_IPv6_VER (1)
+#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
+#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
+#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
+#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
+#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
+#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
+#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
+
+#define NET_HEADER_FIELD_ICMP_TYPE (1)
+#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
+#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
+#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
+#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
+#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
+
+#define NET_HEADER_FIELD_IGMP_VERSION (1)
+#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
+#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
+#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
+#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
+
+
+typedef uint16_t headerFieldTcp_t;
+
+#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
+#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
+#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
+#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
+#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
+#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
+#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
+#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
+#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
+#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
+#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
+#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
+
+
+typedef uint8_t headerFieldSctp_t;
+
+#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
+#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
+#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
+#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
+#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
+
+
+typedef uint8_t headerFieldDccp_t;
+
+#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
+#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
+#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
+
+
+typedef uint8_t headerFieldUdp_t;
+
+#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
+#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
+#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
+#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
+#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
+
+typedef uint8_t headerFieldUdpEncapEsp_t;
+
+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
+
+#define NET_HEADER_FIELD_IPHC_CID (1)
+#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
+#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
+#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
+#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
+#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
+
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
+
+#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
+#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
+#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
+#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
+#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
+#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
+#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
+#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
+#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
+#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
+#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
+#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
+#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
+#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
+
+#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
+#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
+
+#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
+#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
+#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
+#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
+#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
+
+
+typedef uint8_t headerFieldVlan_t;
+
+#define NET_HEADER_FIELD_VLAN_VPRI (1)
+#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
+#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
+#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
+#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
+#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
+
+#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
+ NET_HEADER_FIELD_VLAN_CFI | \
+ NET_HEADER_FIELD_VLAN_VID)
+
+
+typedef uint8_t headerFieldLlc_t;
+
+#define NET_HEADER_FIELD_LLC_DSAP (1)
+#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
+#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
+#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
+
+#define NET_HEADER_FIELD_NLPID_NLPID (1)
+#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
+
+
+typedef uint8_t headerFieldSnap_t;
+
+#define NET_HEADER_FIELD_SNAP_OUI (1)
+#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
+#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
+
+
+typedef uint8_t headerFieldLlcSnap_t;
+
+#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
+#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
+
+#define NET_HEADER_FIELD_ARP_HTYPE (1)
+#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
+#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
+#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
+#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
+#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
+#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
+#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
+#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
+#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
+
+#define NET_HEADER_FIELD_RFC2684_LLC (1)
+#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
+#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
+#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
+#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
+#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
+#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
+
+#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
+#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
+#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
+
+#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
+#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
+#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
+#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
+#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
+#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
+#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
+
+
+typedef uint8_t headerFieldGre_t;
+
+#define NET_HEADER_FIELD_GRE_TYPE (1)
+#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
+
+
+typedef uint8_t headerFieldMinencap_t;
+
+#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
+#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
+#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
+#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
+
+
+typedef uint8_t headerFieldIpsecAh_t;
+
+#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
+#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
+#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
+
+
+typedef uint8_t headerFieldIpsecEsp_t;
+
+#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
+#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
+#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
+
+
+typedef uint8_t headerFieldMpls_t;
+
+#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
+#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
+
+
+typedef uint8_t headerFieldMacsec_t;
+
+#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
+#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
+
+
+typedef enum {
+ HEADER_TYPE_NONE = 0,
+ HEADER_TYPE_PAYLOAD,
+ HEADER_TYPE_ETH,
+ HEADER_TYPE_VLAN,
+ HEADER_TYPE_IPv4,
+ HEADER_TYPE_IPv6,
+ HEADER_TYPE_TCP,
+ HEADER_TYPE_UDP,
+ HEADER_TYPE_IPHC,
+ HEADER_TYPE_SCTP,
+ HEADER_TYPE_SCTP_CHUNK_DATA,
+ HEADER_TYPE_PPPoE,
+ HEADER_TYPE_PPP,
+ HEADER_TYPE_PPPMUX,
+ HEADER_TYPE_PPPMUX_SUBFRAME,
+ HEADER_TYPE_L2TPv2,
+ HEADER_TYPE_L2TPv3_CTRL,
+ HEADER_TYPE_L2TPv3_SESS,
+ HEADER_TYPE_LLC,
+ HEADER_TYPE_LLC_SNAP,
+ HEADER_TYPE_NLPID,
+ HEADER_TYPE_SNAP,
+ HEADER_TYPE_MPLS,
+ HEADER_TYPE_IPSEC_AH,
+ HEADER_TYPE_IPSEC_ESP,
+ HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
+ HEADER_TYPE_MACSEC,
+ HEADER_TYPE_GRE,
+ HEADER_TYPE_MINENCAP,
+ HEADER_TYPE_DCCP,
+ HEADER_TYPE_ICMP,
+ HEADER_TYPE_IGMP,
+ HEADER_TYPE_ARP,
+ HEADER_TYPE_CAPWAP,
+ HEADER_TYPE_CAPWAP_DTLS,
+ HEADER_TYPE_RFC2684,
+ HEADER_TYPE_USER_DEFINED_L2,
+ HEADER_TYPE_USER_DEFINED_L3,
+ HEADER_TYPE_USER_DEFINED_L4,
+ HEADER_TYPE_USER_DEFINED_SHIM1,
+ HEADER_TYPE_USER_DEFINED_SHIM2,
+ MAX_HEADER_TYPE_COUNT
+} e_NetHeaderType;
+
+
+#endif /* __NET_EXT_H */
diff --git a/sys/contrib/ncsw/inc/std_ext.h b/sys/contrib/ncsw/inc/std_ext.h
new file mode 100644
index 0000000..4d2ba44
--- /dev/null
+++ b/sys/contrib/ncsw/inc/std_ext.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**************************************************************************//**
+
+ @File std_ext.h
+
+ @Description General Standard Definitions
+*//***************************************************************************/
+
+#ifndef __STD_EXT_H
+#define __STD_EXT_H
+
+
+#include "types_ext.h"
+#include "ncsw_ext.h"
+
+
+#endif /* __STD_EXT_H */
diff --git a/sys/contrib/ncsw/inc/stdarg_ext.h b/sys/contrib/ncsw/inc/stdarg_ext.h
new file mode 100644
index 0000000..39e46ef
--- /dev/null
+++ b/sys/contrib/ncsw/inc/stdarg_ext.h
@@ -0,0 +1,53 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __STDARG_EXT_H
+#define __STDARG_EXT_H
+
+
+#if defined(NCSW_LINUX) && defined(__KERNEL__)
+#include <stdarg.h>
+
+#elif defined(NCSW_FREEBSD)
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <machine/stdarg.h>
+
+#else
+#include <stdarg.h>
+
+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
+
+#include "std_ext.h"
+
+
+#endif /* __STDARG_EXT_H */
diff --git a/sys/contrib/ncsw/inc/stdlib_ext.h b/sys/contrib/ncsw/inc/stdlib_ext.h
new file mode 100644
index 0000000..16f2a2a
--- /dev/null
+++ b/sys/contrib/ncsw/inc/stdlib_ext.h
@@ -0,0 +1,166 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef __STDLIB_EXT_H
+#define __STDLIB_EXT_H
+
+
+#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
+#include "stdarg_ext.h"
+#include "std_ext.h"
+
+
+/**
+ * strtoul - convert a string to an uint32_t
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+uint32_t strtoul(const char *cp,char **endp,uint32_t base);
+
+/**
+ * strtol - convert a string to a int32_t
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long strtol(const char *cp,char **endp,uint32_t base);
+
+/**
+ * strtoull - convert a string to an uint64_t
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+uint64_t strtoull(const char *cp,char **endp,uint32_t base);
+
+/**
+ * strtoll - convert a string to a int64 long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long long strtoll(const char *cp,char **endp,uint32_t base);
+
+/**
+ * atoi - convert a character to a int
+ * @s: The start of the string
+ */
+int atoi(const char *s);
+
+/**
+ * strnlen - Find the length of a length-limited string
+ * @s: The string to be sized
+ * @count: The maximum number of bytes to search
+ */
+size_t strnlen(const char * s, size_t count);
+
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char * s);
+
+/**
+ * strtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ *
+ * WARNING: strtok is deprecated, use strsep instead.
+ */
+char * strtok(char * s,const char * ct);
+
+/**
+ * strncpy - Copy a length-limited, %NUL-terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @count: The maximum number of bytes to copy
+ *
+ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
+ * However, the result is not %NUL-terminated if the source exceeds
+ * @count bytes.
+ */
+char * strncpy(char * dest,const char *src,size_t count);
+
+/**
+ * strcpy - Copy a %NUL terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ */
+char * strcpy(char * dest,const char *src);
+
+/**
+ * vsscanf - Unformat a buffer into a list of arguments
+ * @buf: input buffer
+ * @fmt: format of buffer
+ * @args: arguments
+ */
+int vsscanf(const char * buf, const char * fmt, va_list args);
+
+/**
+ * vsnprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want snprintf instead.
+ */
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
+
+/**
+ * vsprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want sprintf instead.
+ */
+int vsprintf(char *buf, const char *fmt, va_list args);
+
+#elif defined(NCSW_FREEBSD)
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
+
+#include "std_ext.h"
+
+
+#endif /* __STDLIB_EXT_H */
diff --git a/sys/contrib/ncsw/inc/string_ext.h b/sys/contrib/ncsw/inc/string_ext.h
new file mode 100644
index 0000000..32c6457
--- /dev/null
+++ b/sys/contrib/ncsw/inc/string_ext.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __STRING_EXT_H
+#define __STRING_EXT_H
+
+
+#if defined(NCSW_LINUX) && defined(__KERNEL__)
+#include <linux/kernel.h>
+#include <linux/string.h>
+extern char * strtok ( char * str, const char * delimiters );
+
+#elif defined(__KERNEL__)
+#include "linux/types.h"
+#include "linux/posix_types.h"
+#include "linux/string.h"
+
+#elif defined(NCSW_FREEBSD)
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+extern char *strtok(char *str, const char *delimiters);
+
+#else
+#include <string.h>
+
+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
+
+#include "std_ext.h"
+
+
+#endif /* __STRING_EXT_H */
diff --git a/sys/contrib/ncsw/inc/types_ext.h b/sys/contrib/ncsw/inc/types_ext.h
new file mode 100644
index 0000000..03b6db4
--- /dev/null
+++ b/sys/contrib/ncsw/inc/types_ext.h
@@ -0,0 +1,114 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ /**************************************************************************//**
+ @File types_ext.h
+
+ @Description General types Standard Definitions
+*//***************************************************************************/
+
+#ifndef __TYPES_EXT_H
+#define __TYPES_EXT_H
+
+
+#if defined(NCSW_LINUX)
+#include "types_linux.h"
+
+#elif defined(NCSW_LINUX_USD)
+#include "types_linux_usd.h"
+
+#elif defined(NCSW_VXWORKS)
+#include "types_vxworks.h"
+
+#elif defined(__MWERKS__) && defined(__GNUC__) && defined(__cplusplus)
+#include "types_bb_gpp.h"
+
+#elif defined(__MWERKS__) && defined(__GNUC__)
+#include "types_bb_gcc.h"
+
+#elif defined(__ghs__)
+#include "types_ghs.h"
+
+#elif defined(NCSW_FREEBSD)
+#include "types_freebsd.h"
+
+#else
+#include "types_dflt.h"
+#endif /* defined (__ROCOO__) */
+
+
+static __inline__ void TypesChecker(void)
+{
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+#define MEM_MAP_START
+ _Packed struct strct {
+ __volatile__ int vi;
+ } _PackedType;
+#define MEM_MAP_END
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+ size_t size = 0;
+ bool tr = TRUE, fls = FALSE;
+ struct strct *p_Strct = NULL;
+ physAddress_t addr = 0x100;
+
+ tr = fls;
+ p_Strct = p_Strct;
+ size++;
+ if (tr) size++;
+
+ WRITE_UINT8(*((uint8_t*)((size_t)(addr))),
+ GET_UINT8(*((uint8_t*)((size_t)(addr)))));
+
+ WRITE_UINT8(*((uint8_t*)((size_t)(UINT8_MAX))),
+ GET_UINT8(*((uint8_t*)((size_t)(UINT8_MAX)))));
+ WRITE_UINT16(*((uint16_t*)((size_t)(UINT16_MAX))),
+ GET_UINT16(*((uint16_t*)((size_t)(UINT16_MAX)))));
+ WRITE_UINT32(*((uint32_t*)((size_t)(UINT32_MAX))),
+ GET_UINT32(*((uint32_t*)((size_t)(UINT32_MAX)))));
+ WRITE_UINT64(*((uint64_t*)((size_t)(UINT64_MAX))),
+ GET_UINT64(*((uint64_t*)((size_t)(UINT64_MAX)))));
+ WRITE_UINT8(*((uint8_t*)((size_t)(INT8_MAX))),
+ GET_UINT8(*((uint8_t*)((size_t)(INT8_MIN)))));
+ WRITE_UINT16(*((uint16_t*)((size_t)(INT16_MAX))),
+ GET_UINT16(*((uint16_t*)((size_t)(INT16_MIN)))));
+ WRITE_UINT32(*((uint32_t*)((size_t)(INT32_MAX))),
+ GET_UINT32(*((uint32_t*)((size_t)(INT32_MIN)))));
+ WRITE_UINT64(*((uint64_t*)((size_t)(INT64_MAX))),
+ GET_UINT64(*((uint64_t*)((size_t)(INT64_MIN)))));
+}
+
+
+#endif /* __TYPES_EXT_H */
diff --git a/sys/contrib/ncsw/inc/types_freebsd.h b/sys/contrib/ncsw/inc/types_freebsd.h
new file mode 100644
index 0000000..031da08
--- /dev/null
+++ b/sys/contrib/ncsw/inc/types_freebsd.h
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2011 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TYPES_FREEBSD_H_
+#define TYPES_FREEBSD_H_
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include <sys/stddef.h>
+#include <sys/types.h>
+
+#include <machine/pio.h>
+
+#if !defined(__bool_true_false_are_defined)
+typedef boolean_t bool;
+#endif
+#define TRUE 1
+#define FALSE 0
+
+typedef vm_paddr_t physAddress_t;
+
+#define _Packed
+#define _PackedType __attribute__ ((packed))
+
+/**
+ * Accessor defines.
+ * TODO: These are only stubs and have to be redefined (use bus_space
+ * facilities).
+ */
+#define GET_UINT32(arg) in32(&(arg))
+#define GET_UINT64(arg) in64(&(arg))
+
+#define _WRITE_UINT32(arg, data) out32(&(arg), (data))
+#define _WRITE_UINT64(arg, data) out64(&(arg), (data))
+
+#ifndef QE_32_BIT_ACCESS_RESTRICTION
+
+#define GET_UINT8(arg) in8(&(arg))
+#define GET_UINT16(arg) in16(&(arg))
+
+#define _WRITE_UINT8(arg, data) out8(&(arg), (data))
+#define _WRITE_UINT16(arg, data) out16(&(arg), (data))
+
+#else /* QE_32_BIT_ACCESS_RESTRICTION */
+
+#define QE_32_BIT_ADDR(_arg) (uint32_t)((uint32_t)&(_arg) & 0xFFFFFFFC)
+#define QE_32_BIT_SHIFT8(__arg) (uint32_t)((3 - ((uint32_t)&(__arg) & 0x3)) * 8)
+#define QE_32_BIT_SHIFT16(__arg) (uint32_t)((2 - ((uint32_t)&(__arg) & 0x3)) * 8)
+
+#define GET_UINT8(arg) (uint8_t)(in32(QE_32_BIT_ADDR(arg)) >> QE_32_BIT_SHIFT8(arg))
+#define GET_UINT16(arg) (uint16_t)(in32(QE_32_BIT_ADDR(arg)) >> QE_32_BIT_SHIFT16(arg))
+
+#define _WRITE_UINT8(arg, data) \
+ do \
+ { \
+ uint32_t addr = QE_32_BIT_ADDR(arg); \
+ uint32_t shift = QE_32_BIT_SHIFT8(arg); \
+ uint32_t tmp = in32(addr); \
+ tmp = (uint32_t)((tmp & ~(0x000000FF << shift)) | ((uint32_t)(data & 0x000000FF) << shift)); \
+ out32(addr, tmp); \
+ } while (0)
+
+#define _WRITE_UINT16(arg, data) \
+ do \
+ { \
+ uint32_t addr = QE_32_BIT_ADDR(arg); \
+ uint32_t shift = QE_32_BIT_SHIFT16(arg); \
+ uint32_t tmp = in32(addr); \
+ tmp = (uint32_t)((tmp & ~(0x0000FFFF << shift)) | ((uint32_t)(data & 0x0000FFFF) << shift)); \
+ out32(addr, tmp); \
+ } while (0)
+
+#endif /* QE_32_BIT_ACCESS_RESTRICTION */
+
+#define WRITE_UINT8 _WRITE_UINT8
+#define WRITE_UINT16 _WRITE_UINT16
+#define WRITE_UINT32 _WRITE_UINT32
+#define WRITE_UINT64 _WRITE_UINT64
+
+#endif /* TYPES_FREEBSD_H_ */
diff --git a/sys/contrib/ncsw/inc/xx_ext.h b/sys/contrib/ncsw/inc/xx_ext.h
new file mode 100644
index 0000000..a1f61e0
--- /dev/null
+++ b/sys/contrib/ncsw/inc/xx_ext.h
@@ -0,0 +1,938 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File xx_ext.h
+
+ @Description Prototypes, externals and typedefs for system-supplied
+ (external) routines
+*//***************************************************************************/
+
+#ifndef __XX_EXT_H
+#define __XX_EXT_H
+
+#include "std_ext.h"
+#include "part_ext.h"
+
+#if defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED)
+#include "xx_integration_ext.h"
+#endif /* defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED) */
+
+
+/**************************************************************************//**
+ @Group xx_id XX Interface (System call hooks)
+
+ @Description Prototypes, externals and typedefs for system-supplied
+ (external) routines
+
+ @{
+*//***************************************************************************/
+
+#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
+/**************************************************************************//**
+ @Function XX_EventById
+
+ @Description Event reporting routine - executed only when REPORT_EVENTS=1.
+
+ @Param[in] event - Event code (e_Event).
+ @Param[in] appId - Application identifier.
+ @Param[in] flags - Event flags.
+ @Param[in] msg - Event message.
+
+ @Return None
+*//***************************************************************************/
+void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg);
+
+#else /* not REPORT_EVENTS */
+#define XX_EventById(event, appId, flags, msg)
+#endif /* REPORT_EVENTS */
+
+
+#ifdef DEBUG_XX_MALLOC
+void * XX_MallocDebug(uint32_t size, char *fname, int line);
+
+void * XX_MallocSmartDebug(uint32_t size,
+ int memPartitionId,
+ uint32_t alignment,
+ char *fname,
+ int line);
+
+#define XX_Malloc(sz) \
+ XX_MallocDebug((sz), __FILE__, __LINE__)
+
+#define XX_MallocSmart(sz, memt, al) \
+ XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
+
+#else /* not DEBUG_XX_MALLOC */
+/**************************************************************************//**
+ @Function XX_Malloc
+
+ @Description allocates contiguous block of memory.
+
+ @Param[in] size - Number of bytes to allocate.
+
+ @Return The address of the newly allocated block on success, NULL on failure.
+*//***************************************************************************/
+void * XX_Malloc(uint32_t size);
+
+/**************************************************************************//**
+ @Function XX_MallocSmartInit
+
+ @Description Initializes SmartMalloc allocator.
+
+ @Return E_OK on success, error code otherwise.
+*//***************************************************************************/
+int XX_MallocSmartInit(void);
+
+/**************************************************************************//**
+ @Function XX_MallocSmart
+
+ @Description Allocates contiguous block of memory in a specified
+ alignment and from the specified segment.
+
+ @Param[in] size - Number of bytes to allocate.
+ @Param[in] memPartitionId - Memory partition ID; The value zero must
+ be mapped to the default heap partition.
+ @Param[in] alignment - Required memory alignment (in bytes).
+
+ @Return The address of the newly allocated block on success, NULL on failure.
+*//***************************************************************************/
+void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
+#endif /* not DEBUG_XX_MALLOC */
+
+/**************************************************************************//**
+ @Function XX_FreeSmart
+
+ @Description Frees the memory block pointed to by "p".
+ Only for memory allocated by XX_MallocSmart
+
+ @Param[in] p_Memory - pointer to the memory block.
+
+ @Return None.
+*//***************************************************************************/
+void XX_FreeSmart(void *p_Memory);
+
+/**************************************************************************//**
+ @Function XX_Free
+
+ @Description frees the memory block pointed to by "p".
+
+ @Param[in] p_Memory - pointer to the memory block.
+
+ @Return None.
+*//***************************************************************************/
+void XX_Free(void *p_Memory);
+
+#ifndef NCSW_LINUX
+/**************************************************************************//**
+ @Function XX_GetMemPartitionBase
+
+ @Description This routine gets the address of a memory segment according to
+ the memory type.
+
+ @Param[in] memPartitionId - Memory partition ID; The value zero must
+ be mapped to the default heap partition.
+
+ @Return The address of the required memory type.
+*//***************************************************************************/
+void * XX_GetMemPartitionBase(int memPartitionId);
+#endif
+
+/**************************************************************************//**
+ @Function XX_Print
+
+ @Description print a string.
+
+ @Param[in] str - string to print.
+
+ @Return None.
+*//***************************************************************************/
+void XX_Print(char *str, ...);
+
+/**************************************************************************//**
+ @Function XX_GetChar
+
+ @Description Get character from console.
+
+ @Return Character is returned on success. Zero is returned otherwise.
+*//***************************************************************************/
+char XX_GetChar(void);
+
+/**************************************************************************//**
+ @Function XX_PreallocAndBindIntr
+
+ @Description Preallocate and optionally bind it to given CPU.
+
+ @Param[in] irq - Interrupt ID (system-specific number).
+ @Param[in] cpu - CPU to bind to or -1 if iRQ should be unbound.
+
+ @Return E_OK on success; error code otherwise..
+*//***************************************************************************/
+t_Error XX_PreallocAndBindIntr(int irq, unsigned int cpu);
+
+/**************************************************************************//**
+ @Function XX_DeallocIntr
+
+ @Description Deallocate preallocated interupt.
+
+ @Param[in] irq - Interrupt ID (system-specific number).
+
+ @Return E_OK on success; error code otherwise..
+*//***************************************************************************/
+t_Error XX_DeallocIntr(int irq);
+
+/**************************************************************************//**
+ @Function XX_SetIntr
+
+ @Description Set an interrupt service routine for a specific interrupt source.
+
+ @Param[in] irq - Interrupt ID (system-specific number).
+ @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
+ @Param[in] handle - The argument for the user callback routine.
+
+ @Return E_OK on success; error code otherwise..
+*//***************************************************************************/
+t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
+
+/**************************************************************************//**
+ @Function XX_FreeIntr
+
+ @Description Free a specific interrupt and a specific callback routine.
+
+ @Param[in] irq - Interrupt ID (system-specific number).
+
+ @Return E_OK on success; error code otherwise..
+*//***************************************************************************/
+t_Error XX_FreeIntr(int irq);
+
+/**************************************************************************//**
+ @Function XX_EnableIntr
+
+ @Description Enable a specific interrupt.
+
+ @Param[in] irq - Interrupt ID (system-specific number).
+
+ @Return E_OK on success; error code otherwise..
+*//***************************************************************************/
+t_Error XX_EnableIntr(int irq);
+
+/**************************************************************************//**
+ @Function XX_DisableIntr
+
+ @Description Disable a specific interrupt.
+
+ @Param[in] irq - Interrupt ID (system-specific number).
+
+ @Return E_OK on success; error code otherwise..
+*//***************************************************************************/
+t_Error XX_DisableIntr(int irq);
+
+#if !(defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED))
+/**************************************************************************//**
+ @Function XX_DisableAllIntr
+
+ @Description Disable all interrupts by masking them at the CPU.
+
+ @Return A value that represents the interrupts state before the
+ operation, and should be passed to the matching
+ XX_RestoreAllIntr() call.
+*//***************************************************************************/
+uint32_t XX_DisableAllIntr(void);
+
+/**************************************************************************//**
+ @Function XX_RestoreAllIntr
+
+ @Description Restore previous state of interrupts level at the CPU.
+
+ @Param[in] flags - A value that represents the interrupts state to restore,
+ as returned by the matching call for XX_DisableAllIntr().
+
+ @Return None.
+*//***************************************************************************/
+void XX_RestoreAllIntr(uint32_t flags);
+#endif /* !(defined(__MWERKS__) && defined(OPTIMIZED_FOR_SPEED)) */
+
+/**************************************************************************//**
+ @Function XX_Call
+
+ @Description Call a service in another task.
+
+ Activate the routine "f" via the queue identified by "IntrManagerId". The
+ parameter to "f" is Id - the handle of the destination object
+
+ @Param[in] intrManagerId - Queue ID.
+ @Param[in] f - routine pointer.
+ @Param[in] Id - the parameter to be passed to f().
+ @Param[in] h_App - Application handle.
+ @Param[in] flags - Unused,
+
+ @Return E_OK is returned on success. E_FAIL is returned otherwise (usually an operating system level failure).
+*//***************************************************************************/
+t_Error XX_Call( uint32_t intrManagerId,
+ t_Error (* f)(t_Handle),
+ t_Handle Id,
+ t_Handle h_App,
+ uint16_t flags );
+
+/**************************************************************************//**
+ @Function XX_Exit
+
+ @Description Stop execution and report status (where it is applicable)
+
+ @Param[in] status - exit status
+*//***************************************************************************/
+void XX_Exit(int status);
+
+/*****************************************************************************/
+/* Tasklet Service Routines */
+/*****************************************************************************/
+typedef t_Handle t_TaskletHandle;
+
+/**************************************************************************//**
+ @Function XX_InitTasklet
+
+ @Description Create and initialize a tasklet object.
+
+ @Param[in] routine - A routine to be ran as a tasklet.
+ @Param[in] data - An argument to pass to the tasklet.
+
+ @Return Tasklet handle is returned on success. NULL is returned otherwise.
+*//***************************************************************************/
+t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
+
+/**************************************************************************//**
+ @Function XX_FreeTasklet
+
+ @Description Free a tasklet object.
+
+ @Param[in] h_Tasklet - A handle to a tasklet to be free.
+
+ @Return None.
+*//***************************************************************************/
+void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
+
+/**************************************************************************//**
+ @Function XX_ScheduleTask
+
+ @Description Schedule a tasklet object.
+
+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
+ @Param[in] immediate - Indicate whether to schedule this tasklet on
+ the immediate queue or on the delayed one.
+
+ @Return 0 - on success. Error code - otherwise.
+*//***************************************************************************/
+int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
+
+/**************************************************************************//**
+ @Function XX_FlushScheduledTasks
+
+ @Description Flush all tasks there are in the scheduled tasks queue.
+
+ @Return None.
+*//***************************************************************************/
+void XX_FlushScheduledTasks(void);
+
+/**************************************************************************//**
+ @Function XX_TaskletIsQueued
+
+ @Description Check if task is queued.
+
+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
+
+ @Return 1 - task is queued. 0 - otherwise.
+*//***************************************************************************/
+int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
+
+/**************************************************************************//**
+ @Function XX_SetTaskletData
+
+ @Description Set data to a scheduled task. Used to change data of already
+ scheduled task.
+
+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
+ @Param[in] data - Data to be set.
+*//***************************************************************************/
+void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
+
+/**************************************************************************//**
+ @Function XX_GetTaskletData
+
+ @Description Get the data of scheduled task.
+
+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
+
+ @Return handle to the data of the task.
+*//***************************************************************************/
+t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
+
+/**************************************************************************//**
+ @Function XX_BottomHalf
+
+ @Description Bottom half implementation, invoked by the interrupt handler.
+
+ This routine handles all bottom-half tasklets with interrupts
+ enabled.
+
+ @Return None.
+*//***************************************************************************/
+void XX_BottomHalf(void);
+
+
+/*****************************************************************************/
+/* Spinlock Service Routines */
+/*****************************************************************************/
+
+/**************************************************************************//**
+ @Function XX_InitSpinlock
+
+ @Description Creates a spinlock.
+
+ @Return Spinlock handle is returned on success; NULL otherwise.
+*//***************************************************************************/
+t_Handle XX_InitSpinlock(void);
+
+/**************************************************************************//**
+ @Function XX_FreeSpinlock
+
+ @Description Frees the memory allocated for the spinlock creation.
+
+ @Param[in] h_Spinlock - A handle to a spinlock.
+
+ @Return None.
+*//***************************************************************************/
+void XX_FreeSpinlock(t_Handle h_Spinlock);
+
+/**************************************************************************//**
+ @Function XX_LockSpinlock
+
+ @Description Locks a spinlock.
+
+ @Param[in] h_Spinlock - A handle to a spinlock.
+
+ @Return None.
+*//***************************************************************************/
+void XX_LockSpinlock(t_Handle h_Spinlock);
+
+/**************************************************************************//**
+ @Function XX_UnlockSpinlock
+
+ @Description Unlocks a spinlock.
+
+ @Param[in] h_Spinlock - A handle to a spinlock.
+
+ @Return None.
+*//***************************************************************************/
+void XX_UnlockSpinlock(t_Handle h_Spinlock);
+
+/**************************************************************************//**
+ @Function XX_LockIntrSpinlock
+
+ @Description Locks a spinlock (interrupt safe).
+
+ @Param[in] h_Spinlock - A handle to a spinlock.
+
+ @Return A value that represents the interrupts state before the
+ operation, and should be passed to the matching
+ XX_UnlockIntrSpinlock() call.
+*//***************************************************************************/
+uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
+
+/**************************************************************************//**
+ @Function XX_UnlockIntrSpinlock
+
+ @Description Unlocks a spinlock (interrupt safe).
+
+ @Param[in] h_Spinlock - A handle to a spinlock.
+ @Param[in] intrFlags - A value that represents the interrupts state to
+ restore, as returned by the matching call for
+ XX_LockIntrSpinlock().
+
+ @Return None.
+*//***************************************************************************/
+void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
+
+
+/*****************************************************************************/
+/* Timers Service Routines */
+/*****************************************************************************/
+
+/**************************************************************************//**
+ @Function XX_CurrentTime
+
+ @Description Returns current system time.
+
+ @Return Current system time (in milliseconds).
+*//***************************************************************************/
+uint32_t XX_CurrentTime(void);
+
+/**************************************************************************//**
+ @Function XX_CreateTimer
+
+ @Description Creates a timer.
+
+ @Return Timer handle is returned on success; NULL otherwise.
+*//***************************************************************************/
+t_Handle XX_CreateTimer(void);
+
+/**************************************************************************//**
+ @Function XX_FreeTimer
+
+ @Description Frees the memory allocated for the timer creation.
+
+ @Param[in] h_Timer - A handle to a timer.
+
+ @Return None.
+*//***************************************************************************/
+void XX_FreeTimer(t_Handle h_Timer);
+
+/**************************************************************************//**
+ @Function XX_StartTimer
+
+ @Description Starts a timer.
+
+ The user can select to start the timer as periodic timer or as
+ one-shot timer. The user should provide a callback routine that
+ will be called when the timer expires.
+
+ @Param[in] h_Timer - A handle to a timer.
+ @Param[in] msecs - Timer expiration period (in milliseconds).
+ @Param[in] periodic - TRUE for a periodic timer;
+ FALSE for a one-shot timer..
+ @Param[in] f_TimerExpired - A callback routine to be called when the
+ timer expires.
+ @Param[in] h_Arg - The argument to pass in the timer-expired
+ callback routine.
+
+ @Return None.
+*//***************************************************************************/
+void XX_StartTimer(t_Handle h_Timer,
+ uint32_t msecs,
+ bool periodic,
+ void (*f_TimerExpired)(t_Handle h_Arg),
+ t_Handle h_Arg);
+
+/**************************************************************************//**
+ @Function XX_StopTimer
+
+ @Description Frees the memory allocated for the timer creation.
+
+ @Param[in] h_Timer - A handle to a timer.
+
+ @Return None.
+*//***************************************************************************/
+void XX_StopTimer(t_Handle h_Timer);
+
+/**************************************************************************//**
+ @Function XX_GetExpirationTime
+
+ @Description Returns the time (in milliseconds) remaining until the
+ expiration of a timer.
+
+ @Param[in] h_Timer - A handle to a timer.
+
+ @Return The time left until the timer expires.
+*//***************************************************************************/
+uint32_t XX_GetExpirationTime(t_Handle h_Timer);
+
+/**************************************************************************//**
+ @Function XX_ModTimer
+
+ @Description Updates the expiration time of a timer.
+
+ This routine adds the given time to the current system time,
+ and sets this value as the new expiration time of the timer.
+
+ @Param[in] h_Timer - A handle to a timer.
+ @Param[in] msecs - The new interval until timer expiration
+ (in milliseconds).
+
+ @Return None.
+*//***************************************************************************/
+void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
+
+/**************************************************************************//**
+ @Function XX_TimerIsActive
+
+ @Description Checks whether a timer is active (pending) or not.
+
+ @Param[in] h_Timer - A handle to a timer.
+
+ @Return 0 - the timer is inactive; Non-zero value - the timer is active;
+*//***************************************************************************/
+int XX_TimerIsActive(t_Handle h_Timer);
+
+/**************************************************************************//**
+ @Function XX_Sleep
+
+ @Description Non-busy wait until the desired time (in milliseconds) has passed.
+
+ @Param[in] msecs - The requested sleep time (in milliseconds).
+
+ @Return None.
+
+ @Cautions This routine enables interrupts during its wait time.
+*//***************************************************************************/
+uint32_t XX_Sleep(uint32_t msecs);
+
+/**************************************************************************//**
+ @Function XX_UDelay
+
+ @Description Busy-wait until the desired time (in microseconds) has passed.
+
+ @Param[in] usecs - The requested delay time (in microseconds).
+
+ @Return None.
+
+ @Cautions It is highly unrecommended to call this routine during interrupt
+ time, because the system time may not be updated properly during
+ the delay loop. The behavior of this routine during interrupt
+ time is unexpected.
+*//***************************************************************************/
+void XX_UDelay(uint32_t usecs);
+
+
+/*****************************************************************************/
+/* Other Service Routines */
+/*****************************************************************************/
+
+/**************************************************************************//**
+ @Function XX_PhysToVirt
+
+ @Description Translates a physical address to the matching virtual address.
+
+ @Param[in] addr - The physical address to translate.
+
+ @Return Virtual address.
+*//***************************************************************************/
+void * XX_PhysToVirt(physAddress_t addr);
+
+/**************************************************************************//**
+ @Function XX_VirtToPhys
+
+ @Description Translates a virtual address to the matching physical address.
+
+ @Param[in] addr - The virtual address to translate.
+
+ @Return Physical address.
+*//***************************************************************************/
+physAddress_t XX_VirtToPhys(void *addr);
+
+/**************************************************************************//**
+ @Function XX_PortalSetInfo
+
+ @Description Save physical and virtual adresses of the portals.
+
+ @Param[in] dev - Portals device - either bman or qman.
+
+ @Return Physical, virtual addresses and size.
+*//***************************************************************************/
+void XX_PortalSetInfo(device_t dev);
+
+/**************************************************************************//**
+ @Function XX_FmanSetIntrInfo
+
+ @Description Workaround for FMan interrupt, which must be binded to one CPU
+ only.
+
+ @Param[in] irq - Interrupt number.
+
+ @Return None.
+*//***************************************************************************/
+void XX_FmanFixIntr(int irq);
+
+/**************************************************************************//**
+ @Group xx_ipc XX Inter-Partition-Communication API
+
+ @Description The following API is to be used when working with multiple
+ partitions configuration.
+
+ @{
+*//***************************************************************************/
+
+#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
+ The IPC service can use this constant to limit
+ the storage space for IPC endpoint names. */
+
+
+/**************************************************************************//**
+ @Function t_IpcMsgCompletion
+
+ @Description Callback function used upon IPC non-blocking transaction completion
+ to return message buffer to the caller and to forward reply if available.
+
+ This callback function may be attached by the source endpoint to any outgoing
+ IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
+ Upon completion of an IPC transaction (consisting of a message and an optional reply),
+ the IPC service invokes this callback routine to return the message buffer to the sender
+ and to provide the received reply, if requested.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
+ in the XX_IpcSendMessage() function; This handle is typically used to point
+ to the internal data structure of the source endpoint.
+ @Param[in] p_Msg - Pointer to original (sent) message buffer;
+ The source endpoint can free (or reuse) this buffer when message
+ completion callback is called.
+ @Param[in] p_Reply - Pointer to (received) reply buffer;
+ This pointer is the same as was provided by the source endpoint in
+ XX_IpcSendMessage().
+ @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
+ @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
+ timeout.
+
+ @Return None
+ *//***************************************************************************/
+typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
+ uint8_t *p_Msg,
+ uint8_t *p_Reply,
+ uint32_t replyLength,
+ t_Error status);
+
+/**************************************************************************//**
+ @Function t_IpcMsgHandler
+
+ @Description Callback function used as IPC message handler.
+
+ The IPC service invokes message handlers for each IPC message received.
+ The actual function pointer should be registered by each destination endpoint
+ via the XX_IpcRegisterMsgHandler() routine.
+
+ User provides this function. Driver invokes it.
+
+ @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
+ was passed in the XX_IpcRegisterMsgHandler() function; this handle is
+ typically used to point to the internal data structure of the destination
+ endpoint.
+ @Param[in] p_Msg - Pointer to message buffer with data received from peer.
+ @Param[in] msgLength - Length (in bytes) of message data.
+ @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
+ by the IPC service;
+ The reply buffer is allocated by the IPC service with size equals to the
+ replyLength parameter provided in message handler registration (see
+ XX_IpcRegisterMsgHandler() function);
+ If replyLength was initially specified as zero during message handler registration,
+ the IPC service may set this pointer to NULL and assume that a reply is not needed;
+ The IPC service is also responsible for freeing the reply buffer after the
+ reply has been sent or dismissed.
+ @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
+ [In] equals the replyLength parameter provided in message handler
+ registration (see XX_IpcRegisterMsgHandler() function), and
+ [Out] should be updated by message handler to the actual reply length; if
+ this value is set to zero, the IPC service must assume that a reply should
+ not be sent;
+ Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
+
+ @Return E_OK on success; Error code otherwise.
+ *//***************************************************************************/
+typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
+ uint8_t *p_Msg,
+ uint32_t msgLength,
+ uint8_t *p_Reply,
+ uint32_t *p_ReplyLength);
+
+/**************************************************************************//**
+ @Function XX_IpcRegisterMsgHandler
+
+ @Description IPC mailbox registration.
+
+ This function is used for registering an IPC message handler in the IPC service.
+ This function is called by each destination endpoint to indicate that it is ready
+ to handle incoming messages. The IPC service invokes the message handler upon receiving
+ a message addressed to the specified destination endpoint.
+
+ @Param[in] addr - The address name string associated with the destination endpoint;
+ This address must be unique across the IPC service domain to ensure
+ correct message routing.
+ @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
+ message; invoked by the IPC service upon receiving a message
+ addressed to the destination endpoint specified by the addr
+ parameter.
+ @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
+ to f_MsgHandler callback function.
+ @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
+ may generate; the IPC service provides the message handler with buffer
+ for reply according to the length specified here (refer also to the description
+ of #t_IpcMsgHandler callback function type);
+ This size shall be zero if the message handler never generates replies.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
+ t_IpcMsgHandler *f_MsgHandler,
+ t_Handle h_Module,
+ uint32_t replyLength);
+
+/**************************************************************************//**
+ @Function XX_IpcUnregisterMsgHandler
+
+ @Description Release IPC mailbox routine.
+
+ This function is used for unregistering an IPC message handler from the IPC service.
+ This function is called by each destination endpoint to indicate that it is no longer
+ capable of handling incoming messages.
+
+ @Param[in] addr - The address name string associated with the destination endpoint;
+ This address is the same as was used when the message handler was
+ registered via XX_IpcRegisterMsgHandler().
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
+
+/**************************************************************************//**
+ @Function XX_IpcInitSession
+
+ @Description This function is used for creating an IPC session between the source endpoint
+ and the destination endpoint.
+
+ The actual implementation and representation of a session is left for the IPC service.
+ The function returns an abstract handle to the created session. This handle shall be used
+ by the source endpoint in subsequent calls to XX_IpcSendMessage().
+ The IPC service assumes that before this function is called, no messages are sent from
+ the specified source endpoint to the specified destination endpoint.
+
+ The IPC service may use a connection-oriented approach or a connectionless approach (or both)
+ as described below.
+
+ @par Connection-Oriented Approach
+
+ The IPC service may implement a session in a connection-oriented approach - when this function is called,
+ the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
+ and a destination-to-source channel for replies. The returned handle should represent the internal
+ representation of these channels.
+
+ @par Connectionless Approach
+
+ The IPC service may implement a session in a connectionless approach - when this function is called, the
+ IPC service should not perform any particular steps, but it must store the pair of source and destination
+ addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
+ called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
+ through the connectionless medium.
+
+ @Param[in] destAddr - The address name string associated with the destination endpoint.
+ @Param[in] srcAddr - The address name string associated with the source endpoint.
+
+ @Return Abstract handle to the initialized session, or NULL on error.
+*//***************************************************************************/
+t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
+ char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
+
+/**************************************************************************//**
+ @Function XX_IpcFreeSession
+
+ @Description This function is used for terminating an existing IPC session between a source endpoint
+ and a destination endpoint.
+
+ The IPC service assumes that after this function is called, no messages shall be sent from
+ the associated source endpoint to the associated destination endpoint.
+
+ @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
+ returned by the XX_IpcInitSession() function.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error XX_IpcFreeSession(t_Handle h_Session);
+
+/**************************************************************************//**
+ @Function XX_IpcSendMessage
+
+ @Description IPC message send routine.
+
+ This function may be used by a source endpoint to send an IPC message to a destination
+ endpoint. The source endpoint cannot send a message to the destination endpoint without
+ first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
+
+ The source endpoint must provide the buffer pointer and length of the outgoing message.
+ Optionally, it may also provide a buffer for an expected reply. In the latter case, the
+ transaction is not considered complete by the IPC service until the reply has been received.
+ If the source endpoint does not provide a reply buffer, the transaction is considered
+ complete after the message has been sent. The source endpoint must keep the message (and
+ optional reply) buffers valid until the transaction is complete.
+
+ @par Non-blocking mode
+
+ The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
+ completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
+ message and an optional reply), the IPC service invokes this callback routine to return the message
+ buffer to the sender and to provide the received reply, if requested.
+
+ @par Blocking mode
+
+ The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
+ expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
+ was requested) the message has been sent.
+
+ @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
+ returned by the XX_IpcInitSession() function.
+ @Param[in] p_Msg - Pointer to message buffer to send.
+ @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
+ @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
+ fills this buffer with the received reply data;
+ In blocking mode, the reply data must be valid when the function returns;
+ In non-blocking mode, the reply data is valid when f_Completion is called;
+ If this pointer is NULL, no reply is expected.
+ @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
+ [In] specifies the maximal length (in bytes) of the reply buffer pointed by
+ p_Reply, and
+ [Out] in non-blocking mode this value is updated by the IPC service to the
+ actual reply length (in bytes).
+ @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
+ The completion callback is invoked by the IPC service upon
+ completion of the IPC transaction (consisting of a message and an optional
+ reply);
+ If this pointer is NULL, the function is expected to block until the IPC
+ transaction is complete.
+ @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
+ callback function as the first argument.
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error XX_IpcSendMessage(t_Handle h_Session,
+ uint8_t *p_Msg,
+ uint32_t msgLength,
+ uint8_t *p_Reply,
+ uint32_t *p_ReplyLength,
+ t_IpcMsgCompletion *f_Completion,
+ t_Handle h_Arg);
+
+
+/** @} */ /* end of xx_ipc group */
+/** @} */ /* end of xx_id group */
+
+/** FreeBSD Specific additions. */
+void XX_TrackInit(void);
+void XX_TrackAddress(void *addr);
+void XX_UntrackAddress(void *addr);
+
+#endif /* __XX_EXT_H */
diff --git a/sys/contrib/ncsw/integrations/P2041/module_strings.c b/sys/contrib/ncsw/integrations/P2041/module_strings.c
new file mode 100644
index 0000000..674e10c
--- /dev/null
+++ b/sys/contrib/ncsw/integrations/P2041/module_strings.c
@@ -0,0 +1,62 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Module names for debug messages */
+const char *moduleStrings[] =
+{
+ "???" /* MODULE_UNKNOWN */
+ ,"MEM" /* MODULE_ */
+ ,"MM" /* MODULE_MM */
+ ,"CORE" /* MODULE_CORE */
+ ,"P2041" /* MODULE_P2041 */
+ ,"P2041-Platform" /* MODULE_P2041_PLTFRM */
+ ,"PM" /* MODULE_PM */
+ ,"MMU" /* MODULE_MMU */
+ ,"PIC" /* MODULE_PIC */
+ ,"L3 cache (CPC)" /* MODULE_CPC */
+ ,"DUART" /* MODULE_DUART */
+ ,"SerDes" /* MODULE_SERDES */
+ ,"PIO" /* MODULE_PIO */
+ ,"QM" /* MODULE_QM */
+ ,"BM" /* MODULE_BM */
+ ,"SEC" /* MODULE_SEC */
+ ,"LAW" /* MODULE_LAW */
+ ,"LBC" /* MODULE_LBC */
+ ,"PAMU" /* MODULE_PAMU */
+ ,"FM" /* MODULE_FM */
+ ,"FM-MURAM" /* MODULE_FM_MURAM */
+ ,"FM-PCD" /* MODULE_FM_PCD */
+ ,"FM-RTC" /* MODULE_FM_RTC */
+ ,"FM-MAC" /* MODULE_FM_MAC */
+ ,"FM-Port" /* MODULE_FM_PORT */
+ ,"DPA" /* MODULE_DPA */
+};
diff --git a/sys/contrib/ncsw/integrations/P3041/fman_ctrl_code/p3041_r1.0.h b/sys/contrib/ncsw/integrations/P3041/fman_ctrl_code/p3041_r1.0.h
new file mode 100644
index 0000000..21f9115
--- /dev/null
+++ b/sys/contrib/ncsw/integrations/P3041/fman_ctrl_code/p3041_r1.0.h
@@ -0,0 +1,1801 @@
+/******************************************************************************
+
+ © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
+ All rights reserved.
+
+ This is proprietary source code of Freescale Semiconductor Inc.,
+ and its use is subject to the NetComm Device Drivers EULA.
+ The copyright notice above does not evidence any actual or intended
+ publication of such source code.
+
+ ALTERNATIVELY, redistribution and use in source and binary forms, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Freescale Semiconductor nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+
+ **************************************************************************/
+/******************************************************************************
+ @File all_img_P3041_r1.0.h
+
+ @Description U-code image for CC_HC_IM for P3041_r1.0. Image ID is: rel_101_8
+******************************************************************************/
+
+#ifndef __ALL_IMG_P3041_R1_0_H
+#define __ALL_IMG_P3041_R1_0_H
+
+#define P3041_R1_0_UC_IMG \
+{ \
+ 0xb7ff000e \
+ , 0x00650008 \
+ , 0xb7ff0021 \
+ , 0xffffffff \
+ , 0xb7ff001f \
+ , 0xffffffff \
+ , 0xb7ff003a \
+ , 0xffffffff \
+ , 0xb7ff03b7 \
+ , 0xffffffff \
+ , 0xb7ff02f3 \
+ , 0xffffffff \
+ , 0xb7ff0621 \
+ , 0xffffffff \
+ , 0x7902f800 \
+ , 0x7904f800 \
+ , 0x7906f800 \
+ , 0x7908f800 \
+ , 0x790af800 \
+ , 0x790cf800 \
+ , 0x790ef800 \
+ , 0x7910f800 \
+ , 0x7912f800 \
+ , 0x7914f800 \
+ , 0x7916f800 \
+ , 0x7918f800 \
+ , 0x791af800 \
+ , 0x791cf800 \
+ , 0x791ef800 \
+ , 0x777ff802 \
+ , 0x777ff803 \
+ , 0x777ff804 \
+ , 0x777ff806 \
+ , 0xb21f0004 \
+ , 0x7900f800 \
+ , 0x281ff800 \
+ , 0xffffffff \
+ , 0xb3ff0698 \
+ , 0xc2000001 \
+ , 0x7800f900 \
+ , 0xbc00ffff \
+ , 0xdbc0c0bd \
+ , 0xc60c3078 \
+ , 0x777ef300 \
+ , 0x7809fb00 \
+ , 0xc8024a70 \
+ , 0x7369f300 \
+ , 0x77000001 \
+ , 0xc60c3000 \
+ , 0xe9c20203 \
+ , 0x7362f300 \
+ , 0x777ef300 \
+ , 0x7800fb00 \
+ , 0x2e1f0002 \
+ , 0xffffffff \
+ , 0xebc00001 \
+ , 0x70e00101 \
+ , 0x2e3f0002 \
+ , 0xffffffff \
+ , 0xc60c3074 \
+ , 0xe3c20080 \
+ , 0x7362f300 \
+ , 0x2e1ffff9 \
+ , 0xffffffff \
+ , 0x0400d018 \
+ , 0x0614d030 \
+ , 0x0616d038 \
+ , 0x06040008 \
+ , 0x06180000 \
+ , 0xdbc411bd \
+ , 0xbc380006 \
+ , 0x93e60011 \
+ , 0xb4180001 \
+ , 0x0604c008 \
+ , 0xb3fffffb \
+ , 0x0618c000 \
+ , 0xbc180008 \
+ , 0x0610d010 \
+ , 0xb4580002 \
+ , 0xfb112400 \
+ , 0x2c3f2000 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0x1618d010 \
+ , 0x2c382000 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb14e000 \
+ , 0x0608e000 \
+ , 0x73f8c420 \
+ , 0x4d48c800 \
+ , 0x2e5f0180 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb14e000 \
+ , 0x0608e006 \
+ , 0x73f8c420 \
+ , 0x4d48c800 \
+ , 0x2e5f0178 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb15e000 \
+ , 0x0408e000 \
+ , 0x73f8c420 \
+ , 0x4c48c800 \
+ , 0x2e5f0170 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb15e400 \
+ , 0x0404e000 \
+ , 0x73f8c420 \
+ , 0x4e44c800 \
+ , 0x2e5f0168 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb15e600 \
+ , 0x0404e000 \
+ , 0x73f8c420 \
+ , 0x4e44c800 \
+ , 0x2e5f0160 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e200 \
+ , 0x0408e006 \
+ , 0x73f8c420 \
+ , 0x4c48c800 \
+ , 0x2e5f0158 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e400 \
+ , 0x0404e000 \
+ , 0x73f8c420 \
+ , 0x4ec4c800 \
+ , 0x2e5f0150 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e600 \
+ , 0x0404e000 \
+ , 0x73f8c420 \
+ , 0x4ec4c800 \
+ , 0x2e5f0148 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0408e010 \
+ , 0x73f8c420 \
+ , 0x4cc8c800 \
+ , 0x2e5f0140 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0404e001 \
+ , 0x73f8c420 \
+ , 0x4e04c800 \
+ , 0x2e5f0138 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0408e009 \
+ , 0x73f8c420 \
+ , 0x4c08c800 \
+ , 0x2e5f0130 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0408e00c \
+ , 0x73f8c420 \
+ , 0x4cc8c800 \
+ , 0x2e5f0128 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0608e00c \
+ , 0x73f8c420 \
+ , 0x4dc8c800 \
+ , 0x2e5f0120 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0404e000 \
+ , 0x73f8c420 \
+ , 0x4ec4c800 \
+ , 0x2e5f0118 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0408e006 \
+ , 0x73f8c420 \
+ , 0x4c08c800 \
+ , 0x2e5f0110 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0xebc4000f \
+ , 0xf05c4318 \
+ , 0xf8044630 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f0106 \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0xebc4000f \
+ , 0xf05c4308 \
+ , 0xf8044630 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f00fe \
+ , 0xffffffff \
+ , 0xfb17e400 \
+ , 0x0408e002 \
+ , 0x73f8c420 \
+ , 0x4c48c800 \
+ , 0x2e5f00f8 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0408e000 \
+ , 0x73f8c420 \
+ , 0x4c08c800 \
+ , 0x2e5f00f0 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0408e004 \
+ , 0x73f8c420 \
+ , 0x4cc8c800 \
+ , 0x2e5f00e8 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0408e008 \
+ , 0x73f8c420 \
+ , 0x4cc8c800 \
+ , 0x2e5f00e0 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0608e004 \
+ , 0x73f8c420 \
+ , 0x4dc8c800 \
+ , 0x2e5f00d8 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0408e010 \
+ , 0x73f8c420 \
+ , 0x4cc8c800 \
+ , 0x2e5f00d0 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0404e001 \
+ , 0x73f8c420 \
+ , 0x4e04c800 \
+ , 0x2e5f00c8 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0408e009 \
+ , 0x73f8c420 \
+ , 0x4c08c800 \
+ , 0x2e5f00c0 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0408e00c \
+ , 0x73f8c420 \
+ , 0x4cc8c800 \
+ , 0x2e5f00b8 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0608e00c \
+ , 0x73f8c420 \
+ , 0x4dc8c800 \
+ , 0x2e5f00b0 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0404e000 \
+ , 0x73f8c420 \
+ , 0x4ec4c800 \
+ , 0x2e5f00a8 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0x0408e006 \
+ , 0x73f8c420 \
+ , 0x4c08c800 \
+ , 0x2e5f00a0 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0xebc4000f \
+ , 0xf05c4318 \
+ , 0xf8044630 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f0096 \
+ , 0xffffffff \
+ , 0xfb17e200 \
+ , 0xebc4000f \
+ , 0xf05c4308 \
+ , 0xf8044630 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f008e \
+ , 0xffffffff \
+ , 0xfb17e600 \
+ , 0x0408e000 \
+ , 0x73f8c420 \
+ , 0x4c48c800 \
+ , 0x2e5f0088 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e600 \
+ , 0x0408e002 \
+ , 0x73f8c420 \
+ , 0x4c48c800 \
+ , 0x2e5f0080 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb17e600 \
+ , 0x0408e000 \
+ , 0x73f8c420 \
+ , 0x4cc8c800 \
+ , 0x2e5f0078 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xe55cff00 \
+ , 0xfb14e200 \
+ , 0xc858e230 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f006f \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xe55cff00 \
+ , 0xfb14e400 \
+ , 0xc858e230 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f0067 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xe55cff00 \
+ , 0xfb14e600 \
+ , 0xc858e230 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f005f \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xcf6443c1 \
+ , 0xd84fd3f8 \
+ , 0x73e52c14 \
+ , 0x00087820 \
+ , 0xfb04e43c \
+ , 0xd848e278 \
+ , 0xb3ff0042 \
+ , 0xc8584a30 \
+ , 0xcf6443c1 \
+ , 0xd84fd3f8 \
+ , 0x73e52c14 \
+ , 0x00087820 \
+ , 0xb3ff0040 \
+ , 0xcb08e27c \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb04e43c \
+ , 0xc858e230 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f0048 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb04e43c \
+ , 0x73e52c14 \
+ , 0xc858e230 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f003f \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0004e008 \
+ , 0xebcb0010 \
+ , 0xec240001 \
+ , 0xd0785803 \
+ , 0xb3fffe9f \
+ , 0x06040008 \
+ , 0xffffffff \
+ , 0xfb16e000 \
+ , 0x0004e007 \
+ , 0xebcb0010 \
+ , 0xec240001 \
+ , 0xd0785803 \
+ , 0xb3fffe97 \
+ , 0x06040008 \
+ , 0xffffffff \
+ , 0xd9dfd2f8 \
+ , 0xfb045c3c \
+ , 0x73e52c14 \
+ , 0xc8585a30 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f0026 \
+ , 0xffffffff \
+ , 0xd9dfd2f8 \
+ , 0xfb045c00 \
+ , 0x02005800 \
+ , 0xd9402838 \
+ , 0xb3ff0020 \
+ , 0xd8580038 \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xd9dfd2f8 \
+ , 0xfb045c3c \
+ , 0xc8585a30 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0xd9df04f8 \
+ , 0x2e5f0011 \
+ , 0xffffffff \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f0012 \
+ , 0xffffffff \
+ , 0xc8584a30 \
+ , 0x73f8c420 \
+ , 0x4808c800 \
+ , 0x2e5f000d \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0xffffffff \
+ , 0x7809fc10 \
+ , 0x0499980c \
+ , 0xb7dfffff \
+ , 0xdf594e78 \
+ , 0x1499980c \
+ , 0x06040008 \
+ , 0x06180000 \
+ , 0xdbc411bd \
+ , 0xbc38fe6d \
+ , 0x93e6fe78 \
+ , 0xb418fe68 \
+ , 0x020308d8 \
+ , 0x0204000c \
+ , 0xebc20001 \
+ , 0xf4430301 \
+ , 0xdbc020d4 \
+ , 0xf4440308 \
+ , 0xdbc2003c \
+ , 0xf0431b01 \
+ , 0x120008da \
+ , 0xca03f800 \
+ , 0x9ffff400 \
+ , 0x020610d2 \
+ , 0x02870800 \
+ , 0xb7dfffff \
+ , 0x0205000a \
+ , 0x0204000c \
+ , 0xdc252178 \
+ , 0xb41f0007 \
+ , 0x02030008 \
+ , 0xdc4328f8 \
+ , 0xd84418f8 \
+ , 0xdbc320d5 \
+ , 0xb3ff0005 \
+ , 0xca03f8c0 \
+ , 0xdc4428f8 \
+ , 0xdbc320d5 \
+ , 0xca03f8c0 \
+ , 0xdc2619b8 \
+ , 0xbc1f0005 \
+ , 0x0201000a \
+ , 0xebc00000 \
+ , 0xb3ff0004 \
+ , 0x120110d0 \
+ , 0x12870800 \
+ , 0xebc00001 \
+ , 0x9ffff400 \
+ , 0x0202000a \
+ , 0xdbc1207d \
+ , 0xca01f8c0 \
+ , 0x02000008 \
+ , 0xd8421878 \
+ , 0xdc210078 \
+ , 0xb57f0009 \
+ , 0xdc200838 \
+ , 0xbc3f0003 \
+ , 0xb3ff0005 \
+ , 0xebc00000 \
+ , 0xdc401038 \
+ , 0xdc430038 \
+ , 0xca00f800 \
+ , 0xb7ff0002 \
+ , 0xca01f800 \
+ , 0x9ffff400 \
+ , 0xebc300c0 \
+ , 0xe1c30050 \
+ , 0x0282080e \
+ , 0xb7dfffff \
+ , 0xf0421301 \
+ , 0xca02f880 \
+ , 0x1282080e \
+ , 0x02010000 \
+ , 0xbf810007 \
+ , 0xebc03020 \
+ , 0xcf811045 \
+ , 0xe1c0000c \
+ , 0xd8410078 \
+ , 0xe3c04000 \
+ , 0x73600b00 \
+ , 0x2c3f1800 \
+ , 0xffffffff \
+ , 0x020600d2 \
+ , 0xebc30004 \
+ , 0xdc2330f8 \
+ , 0xb81f0003 \
+ , 0x06040000 \
+ , 0xf0433300 \
+ , 0x120600d6 \
+ , 0x020900d0 \
+ , 0xdbc6223d \
+ , 0xd84940f8 \
+ , 0xca03f8c0 \
+ , 0x041b0800 \
+ , 0x06061000 \
+ , 0xdbc9f855 \
+ , 0xd86749f8 \
+ , 0xd8c609b8 \
+ , 0xf0400390 \
+ , 0xca862180 \
+ , 0x02011008 \
+ , 0xdc211878 \
+ , 0xbc1f000e \
+ , 0xdc4308f8 \
+ , 0xdc481879 \
+ , 0xca01f840 \
+ , 0x71e10d00 \
+ , 0x55060000 \
+ , 0x06061000 \
+ , 0xd8400839 \
+ , 0xca862180 \
+ , 0xf4430b01 \
+ , 0xca01f840 \
+ , 0x71e10d00 \
+ , 0xb3ff0006 \
+ , 0x55060000 \
+ , 0xf4480b01 \
+ , 0xca01f840 \
+ , 0x71e10d00 \
+ , 0x55060000 \
+ , 0x2e3f0059 \
+ , 0xffffffff \
+ , 0x020700d2 \
+ , 0xebc30004 \
+ , 0xdc2338f8 \
+ , 0xb81f0005 \
+ , 0x06040000 \
+ , 0xf4473304 \
+ , 0xf0433b00 \
+ , 0x120600d2 \
+ , 0x120700d6 \
+ , 0x020900d0 \
+ , 0xdbc7223d \
+ , 0xd84940f8 \
+ , 0xca03f8c0 \
+ , 0x041b0800 \
+ , 0x06061000 \
+ , 0xdbc9f855 \
+ , 0xd86749f8 \
+ , 0xd8c609b8 \
+ , 0xf0400b90 \
+ , 0xca862180 \
+ , 0x020a1008 \
+ , 0xdc2a1ab8 \
+ , 0xbc1f0010 \
+ , 0xdc435278 \
+ , 0xdc4848f9 \
+ , 0xca03f8c0 \
+ , 0x71e31d00 \
+ , 0x55260800 \
+ , 0x06061000 \
+ , 0xd8411879 \
+ , 0xca862180 \
+ , 0xf4491301 \
+ , 0xca02f880 \
+ , 0x71e21500 \
+ , 0x55260800 \
+ , 0xf0420b01 \
+ , 0xb3ff000d \
+ , 0x120100d0 \
+ , 0xf4481301 \
+ , 0xca02f880 \
+ , 0x71e21500 \
+ , 0x55260800 \
+ , 0xdc2350f8 \
+ , 0xbc3f0003 \
+ , 0xb3ff0005 \
+ , 0x121f00d0 \
+ , 0xf0420b01 \
+ , 0xd8490878 \
+ , 0x120100d0 \
+ , 0x9ffff400 \
+ , 0xebc1038c \
+ , 0xdbc040fd \
+ , 0xf0411108 \
+ , 0xdbc0401d \
+ , 0x7c01f905 \
+ , 0xdbc1607d \
+ , 0xd8420878 \
+ , 0x73630b00 \
+ , 0x7c01f905 \
+ , 0xdbc1607d \
+ , 0xd8420878 \
+ , 0x77610b00 \
+ , 0x7804fb00 \
+ , 0xdbc4805d \
+ , 0xdc210078 \
+ , 0xbc3ffff5 \
+ , 0xcdc44011 \
+ , 0x9ffff400 \
+ , 0x0400d010 \
+ , 0xebc200c0 \
+ , 0x04000004 \
+ , 0x02010000 \
+ , 0xbb610008 \
+ , 0xe1c20050 \
+ , 0xebc03020 \
+ , 0xcf811045 \
+ , 0xe1c0000c \
+ , 0xd8410078 \
+ , 0xe3c08000 \
+ , 0x73600b00 \
+ , 0x2c3f1000 \
+ , 0xffffffff \
+ , 0x0618d000 \
+ , 0x0401d010 \
+ , 0xf05a0300 \
+ , 0xa3ffff83 \
+ , 0x04020804 \
+ , 0x0618d000 \
+ , 0x0200d0d4 \
+ , 0x040cd010 \
+ , 0x0610d000 \
+ , 0xbbe00008 \
+ , 0xf05a6b90 \
+ , 0xebc00400 \
+ , 0x1200d090 \
+ , 0x0200d0d4 \
+ , 0xf5400301 \
+ , 0xb3ff0003 \
+ , 0x1200d0d4 \
+ , 0x121fd090 \
+ , 0x060a6808 \
+ , 0x040e6004 \
+ , 0xca8a8280 \
+ , 0x0200d0da \
+ , 0x1200d0dc \
+ , 0x121f6802 \
+ , 0x041b6000 \
+ , 0x0202d0d8 \
+ , 0xebc10100 \
+ , 0xdc211078 \
+ , 0xb01f0015 \
+ , 0x0400d0e4 \
+ , 0x0401d008 \
+ , 0x12016802 \
+ , 0x0401d00c \
+ , 0x02026800 \
+ , 0xcf818043 \
+ , 0xf1c10a08 \
+ , 0xd9c20878 \
+ , 0x12016800 \
+ , 0x0201d0d8 \
+ , 0xf4410b01 \
+ , 0xca01f840 \
+ , 0x71e10d00 \
+ , 0x552a0000 \
+ , 0xf05a0300 \
+ , 0xf04c0b00 \
+ , 0xa3ffff81 \
+ , 0xf04e1300 \
+ , 0x2e3fffc3 \
+ , 0xffffffff \
+ , 0x02026802 \
+ , 0xf0421201 \
+ , 0x12026802 \
+ , 0x6bfffd00 \
+ , 0x552a0000 \
+ , 0x0202d0d8 \
+ , 0xf4421201 \
+ , 0x1202d0d8 \
+ , 0x0202d0dc \
+ , 0xf4421301 \
+ , 0x1202d0dc \
+ , 0x0222d0dc \
+ , 0xbc3f0019 \
+ , 0x0201d0d6 \
+ , 0xf4410b01 \
+ , 0x1201d0d6 \
+ , 0x0221d0d6 \
+ , 0xbc3f000a \
+ , 0xa7ffff9d \
+ , 0xffffffff \
+ , 0x1400d0e4 \
+ , 0xf05a0300 \
+ , 0xf04c0b00 \
+ , 0xa3ffff66 \
+ , 0xf04e1300 \
+ , 0x2e3fffb6 \
+ , 0xffffffff \
+ , 0xf04d6b10 \
+ , 0x121f6802 \
+ , 0x121f6800 \
+ , 0x060a6808 \
+ , 0xa3ffff90 \
+ , 0xca8a8280 \
+ , 0x1400d0e4 \
+ , 0x0200d0da \
+ , 0xb3ffffc5 \
+ , 0x1200d0dc \
+ , 0xd86b0af8 \
+ , 0xa3ffff89 \
+ , 0xd8cafab8 \
+ , 0xb3ffffc0 \
+ , 0x1400d0e4 \
+ , 0x0618d000 \
+ , 0x040dd010 \
+ , 0x0402d008 \
+ , 0xf05a0b00 \
+ , 0xf04d0300 \
+ , 0x1202d0d8 \
+ , 0x040e6804 \
+ , 0xf05a8300 \
+ , 0x141cd0e4 \
+ , 0xa3fffedc \
+ , 0xf04e7b0a \
+ , 0x1200d0d2 \
+ , 0xf04e0300 \
+ , 0xf04f0b00 \
+ , 0xa3fffee2 \
+ , 0xf05a1300 \
+ , 0xdc20f838 \
+ , 0xb43f0005 \
+ , 0xf04e0300 \
+ , 0xa3ffff07 \
+ , 0xf04d0b00 \
+ , 0xb7ff0006 \
+ , 0x020180d2 \
+ , 0xa3fffef2 \
+ , 0xf04e0300 \
+ , 0x1200700a \
+ , 0x12807800 \
+ , 0xebc13000 \
+ , 0xe1c1000c \
+ , 0x7c00f801 \
+ , 0xdbc0c03d \
+ , 0xf1c00303 \
+ , 0x73600b00 \
+ , 0xebc30001 \
+ , 0xf0500300 \
+ , 0xf04d0b00 \
+ , 0xf04e1300 \
+ , 0xa3ffff06 \
+ , 0x120380d4 \
+ , 0x000600a4 \
+ , 0x000300a5 \
+ , 0x02080898 \
+ , 0x06040800 \
+ , 0xdc2619b8 \
+ , 0xf0405360 \
+ , 0xb83f003d \
+ , 0xebcb0000 \
+ , 0x101f00a4 \
+ , 0xebcb0001 \
+ , 0x041b0000 \
+ , 0x06061000 \
+ , 0xd86741f8 \
+ , 0xd8c6f9b8 \
+ , 0xca862180 \
+ , 0x0201100a \
+ , 0xdc280a38 \
+ , 0xbc1f000e \
+ , 0xdc4140b8 \
+ , 0xf4221340 \
+ , 0xb01f0006 \
+ , 0xebc10040 \
+ , 0x6b3ffd00 \
+ , 0x55065000 \
+ , 0xb3ff002b \
+ , 0x100100a5 \
+ , 0xf4422301 \
+ , 0x100200a5 \
+ , 0x71e42500 \
+ , 0xb3ff0026 \
+ , 0x55065000 \
+ , 0x02011008 \
+ , 0xdc414338 \
+ , 0xf42c6340 \
+ , 0xb01f0006 \
+ , 0xebc30040 \
+ , 0x6b3ffd00 \
+ , 0x55065000 \
+ , 0xb3ff001d \
+ , 0x100300a5 \
+ , 0x100c00a5 \
+ , 0x06081000 \
+ , 0xdc436078 \
+ , 0xca01f840 \
+ , 0xca882200 \
+ , 0xdbcc211d \
+ , 0xdbc4217d \
+ , 0xf44c2301 \
+ , 0xd84a2978 \
+ , 0x71e42500 \
+ , 0x55065000 \
+ , 0x0222100a \
+ , 0xb43f000f \
+ , 0xdc2208b8 \
+ , 0xb41f0007 \
+ , 0xf4410b01 \
+ , 0xca01f840 \
+ , 0x71e10d00 \
+ , 0x55082800 \
+ , 0xb3ff0008 \
+ , 0x100300a5 \
+ , 0x000100a5 \
+ , 0xf4422301 \
+ , 0xd8411078 \
+ , 0x100100a5 \
+ , 0x71e42500 \
+ , 0x55082800 \
+ , 0xf04b0300 \
+ , 0x9ffff400 \
+ , 0xdc20f838 \
+ , 0xb03f0004 \
+ , 0x06082000 \
+ , 0xb3ff0003 \
+ , 0xebca0000 \
+ , 0x040a2094 \
+ , 0x14012094 \
+ , 0x0005209a \
+ , 0x06061008 \
+ , 0xebcb0100 \
+ , 0xdc4b2af8 \
+ , 0xca0bfac0 \
+ , 0xca864180 \
+ , 0x02091002 \
+ , 0x041b1800 \
+ , 0xdc695a38 \
+ , 0xb17f000c \
+ , 0xd8412b38 \
+ , 0xf44b1b01 \
+ , 0xca03f8c0 \
+ , 0x71e31d00 \
+ , 0x55066000 \
+ , 0xd86759f8 \
+ , 0xd8c6f9b8 \
+ , 0x16061008 \
+ , 0x12081002 \
+ , 0xb3ff000a \
+ , 0x101f209a \
+ , 0xf4491b01 \
+ , 0xca03f8c0 \
+ , 0x71e31d00 \
+ , 0x55066000 \
+ , 0xf0431b01 \
+ , 0x121f1002 \
+ , 0xd84518b8 \
+ , 0x1002209a \
+ , 0xdc20f838 \
+ , 0xbc3f000c \
+ , 0xdc2a0ab8 \
+ , 0xb43f000a \
+ , 0xccca40a1 \
+ , 0xdbc1401d \
+ , 0xd9c200b8 \
+ , 0xebc00388 \
+ , 0x7c03f905 \
+ , 0xf0400908 \
+ , 0xdbc3603d \
+ , 0xd8410038 \
+ , 0x73620300 \
+ , 0x9ffff400 \
+ , 0x04040808 \
+ , 0xdc20f838 \
+ , 0xf0413ba0 \
+ , 0xb03f0013 \
+ , 0xe3c58000 \
+ , 0xccc04061 \
+ , 0xdbc0401d \
+ , 0xd9c100f8 \
+ , 0xebc00388 \
+ , 0x7c06f905 \
+ , 0xf0400908 \
+ , 0xdbc6603d \
+ , 0xd8410038 \
+ , 0x73630300 \
+ , 0x02011098 \
+ , 0x02002008 \
+ , 0xf0410b10 \
+ , 0xdc210078 \
+ , 0xbc3f0003 \
+ , 0xb3ff0003 \
+ , 0x121f200c \
+ , 0x1201200c \
+ , 0x04813800 \
+ , 0xb7dfffff \
+ , 0x04201090 \
+ , 0xb43f0009 \
+ , 0x14813800 \
+ , 0x7c01f801 \
+ , 0xdbc0c01d \
+ , 0x77000001 \
+ , 0x73e52901 \
+ , 0x263f003c \
+ , 0xb3ff0003 \
+ , 0x77010801 \
+ , 0x14803800 \
+ , 0x9ffff400 \
+ , 0x0618d000 \
+ , 0xccda40e1 \
+ , 0xdbda409d \
+ , 0xd9c31138 \
+ , 0x0400d010 \
+ , 0xf05a0b00 \
+ , 0xe3c58000 \
+ , 0xebc20388 \
+ , 0x7c06f905 \
+ , 0xf0421908 \
+ , 0xdbc660bd \
+ , 0xd84310b8 \
+ , 0x73641300 \
+ , 0x7c02f801 \
+ , 0xebc33000 \
+ , 0xe1c3000c \
+ , 0xdbc2c13d \
+ , 0xd9c4d0b8 \
+ , 0x048600a0 \
+ , 0xb7dfffff \
+ , 0xdc26f9b8 \
+ , 0xbc3f0006 \
+ , 0x141fd090 \
+ , 0x148200a0 \
+ , 0xf1c41303 \
+ , 0xb3ff000c \
+ , 0x73621b00 \
+ , 0x141fd090 \
+ , 0x14023090 \
+ , 0x148200a0 \
+ , 0xebc00203 \
+ , 0xd9c40038 \
+ , 0x73601b00 \
+ , 0x77631b00 \
+ , 0x7800fb00 \
+ , 0x281ff800 \
+ , 0xffffffff \
+ , 0x73e52901 \
+ , 0x04020008 \
+ , 0x0203100a \
+ , 0x0204100c \
+ , 0xdc6320f8 \
+ , 0xb43f0003 \
+ , 0x04030000 \
+ , 0xbd030003 \
+ , 0x2e3f000a \
+ , 0xffffffff \
+ , 0xa3ffff36 \
+ , 0x1204d098 \
+ , 0xdc20f838 \
+ , 0xb43f0003 \
+ , 0x2e3f002a \
+ , 0xffffffff \
+ , 0xa7ff0028 \
+ , 0xffffffff \
+ , 0x0618d000 \
+ , 0x0401d010 \
+ , 0xebc90274 \
+ , 0xf05a4300 \
+ , 0xe1c900d0 \
+ , 0x04020808 \
+ , 0x7c03f801 \
+ , 0xebc03000 \
+ , 0xe1c0000c \
+ , 0xdbc3c0fd \
+ , 0xf1c31a01 \
+ , 0x73630300 \
+ , 0x04000800 \
+ , 0xbd000009 \
+ , 0xf0481300 \
+ , 0xa3ffff96 \
+ , 0xebc00000 \
+ , 0x161f4000 \
+ , 0xf0484308 \
+ , 0x161f4000 \
+ , 0x2c3f4800 \
+ , 0xffffffff \
+ , 0x0200100a \
+ , 0x0203100c \
+ , 0xdc601838 \
+ , 0xbc3f0003 \
+ , 0x2e3fffe6 \
+ , 0xffffffff \
+ , 0xf0410300 \
+ , 0xf0480b00 \
+ , 0xa3ffff10 \
+ , 0x1203d098 \
+ , 0xdc20f838 \
+ , 0xb43f0003 \
+ , 0x2e3f0004 \
+ , 0xffffffff \
+ , 0xa7ff0002 \
+ , 0xffffffff \
+ , 0x0618d000 \
+ , 0x040ed010 \
+ , 0xebc00380 \
+ , 0xf04e1360 \
+ , 0x7c03f905 \
+ , 0xf0400908 \
+ , 0xdbc3603d \
+ , 0xd8410038 \
+ , 0x77600300 \
+ , 0x780dfb00 \
+ , 0xbc0d0003 \
+ , 0x2e3ffff5 \
+ , 0xffffffff \
+ , 0x000070a4 \
+ , 0xf04d0b00 \
+ , 0xf04e1b00 \
+ , 0xdbc02015 \
+ , 0xdbc0203d \
+ , 0xd84203f8 \
+ , 0x02007802 \
+ , 0xf04f1300 \
+ , 0xf05a2300 \
+ , 0x1400d008 \
+ , 0xebc00001 \
+ , 0xa3ffff35 \
+ , 0x101fd09a \
+ , 0x776d6903 \
+ , 0xebc00380 \
+ , 0xb3ff0010 \
+ , 0xf0408908 \
+ , 0x7c00f905 \
+ , 0xdbc0603d \
+ , 0xd8510038 \
+ , 0x77600300 \
+ , 0x780dfb00 \
+ , 0xbc0d0003 \
+ , 0x2e3f0018 \
+ , 0xffffffff \
+ , 0xf04d0b00 \
+ , 0xf04f1300 \
+ , 0xf04e1b00 \
+ , 0xf05a2300 \
+ , 0xa3ffff23 \
+ , 0xebc00000 \
+ , 0x02207802 \
+ , 0xbc3ffff1 \
+ , 0x02007800 \
+ , 0xf5400280 \
+ , 0x1200d09c \
+ , 0x000070a4 \
+ , 0xf0400310 \
+ , 0x100070a4 \
+ , 0x02007800 \
+ , 0xbe800005 \
+ , 0xf04d0300 \
+ , 0xf04e0b00 \
+ , 0xa3ffff47 \
+ , 0xf05a1300 \
+ , 0x2e3f0033 \
+ , 0xffffffff \
+ , 0x0618d000 \
+ , 0x040ed010 \
+ , 0x000070a4 \
+ , 0xf04e0b60 \
+ , 0xdbc02015 \
+ , 0xdbc0203d \
+ , 0xd84103f8 \
+ , 0xebc00380 \
+ , 0xf0408908 \
+ , 0x0020d09a \
+ , 0xb43f0009 \
+ , 0x040dd094 \
+ , 0xf04f1300 \
+ , 0xf04e1b00 \
+ , 0xf04d0b00 \
+ , 0xf05a2300 \
+ , 0xa3ffff01 \
+ , 0xebc00000 \
+ , 0xb7ff000f \
+ , 0x7c00f905 \
+ , 0xdbc0603d \
+ , 0xd8510038 \
+ , 0x77600300 \
+ , 0x780dfb00 \
+ , 0xbc0d0003 \
+ , 0x2e3fffe7 \
+ , 0xffffffff \
+ , 0xf04d0b00 \
+ , 0xf04f1300 \
+ , 0xf04e1b00 \
+ , 0xf05a2300 \
+ , 0xa3fffef2 \
+ , 0xebc00000 \
+ , 0x02207802 \
+ , 0xbc3fffe7 \
+ , 0x02007800 \
+ , 0xf5400280 \
+ , 0x1200d09c \
+ , 0x000070a4 \
+ , 0xf0400310 \
+ , 0x100070a4 \
+ , 0x02007800 \
+ , 0xbe800005 \
+ , 0xf04d0300 \
+ , 0xf04e0b00 \
+ , 0xa3ffff16 \
+ , 0xf05a1300 \
+ , 0x2e3f0002 \
+ , 0xffffffff \
+ , 0x0618d000 \
+ , 0x0400d010 \
+ , 0xebc900d0 \
+ , 0x0208d098 \
+ , 0x04020008 \
+ , 0x0606d000 \
+ , 0xf05a0b00 \
+ , 0x06041000 \
+ , 0xd8654178 \
+ , 0xe1c900d0 \
+ , 0xd8c4f938 \
+ , 0xca843100 \
+ , 0x041b0000 \
+ , 0x5224089c \
+ , 0x0203089c \
+ , 0xbe830004 \
+ , 0x141f080c \
+ , 0x2c3f4800 \
+ , 0xffffffff \
+ , 0x02031008 \
+ , 0xf0482310 \
+ , 0xdc241938 \
+ , 0xbc3f0003 \
+ , 0xb3ff0003 \
+ , 0x121f0898 \
+ , 0x12040898 \
+ , 0xa7fffe81 \
+ , 0xffffffff \
+ , 0xdc20f838 \
+ , 0xb43f0003 \
+ , 0x2e3f0004 \
+ , 0xffffffff \
+ , 0xa7ff0002 \
+ , 0xffffffff \
+ , 0x0402d010 \
+ , 0x0401d008 \
+ , 0x000010a4 \
+ , 0xf0421360 \
+ , 0xf540030f \
+ , 0xd8420038 \
+ , 0x02000002 \
+ , 0xd8410038 \
+ , 0xa3ffffa5 \
+ , 0x1400d008 \
+ , 0x04030804 \
+ , 0x04020808 \
+ , 0xebc6000f \
+ , 0x0484180c \
+ , 0xb7dfffff \
+ , 0x14040808 \
+ , 0xd9c410b8 \
+ , 0x1482180c \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0x55220800 \
+ , 0xe3c00054 \
+ , 0x2c3f0000 \
+ , 0xffffffff \
+ , 0x04030808 \
+ , 0xb603001b \
+ , 0xebc20200 \
+ , 0xcf0310c5 \
+ , 0xe1c2000c \
+ , 0xd84310b8 \
+ , 0x77621300 \
+ , 0x7804fb00 \
+ , 0xb4040005 \
+ , 0xebc20200 \
+ , 0xe1c2000c \
+ , 0x77621300 \
+ , 0x7804fb00 \
+ , 0x04060804 \
+ , 0xcf848081 \
+ , 0xcb02f8c0 \
+ , 0xebc200ff \
+ , 0xdbc218fc \
+ , 0xcf068081 \
+ , 0xcb04f940 \
+ , 0xcb03f900 \
+ , 0xcb02f880 \
+ , 0xd94428f8 \
+ , 0xdd4220b8 \
+ , 0xd9c310b8 \
+ , 0xcb02f880 \
+ , 0xf9023420 \
+ , 0x14060804 \
+ , 0x04040804 \
+ , 0xebc20090 \
+ , 0xb8240021 \
+ , 0xe1c2000c \
+ , 0xebc3008c \
+ , 0xe1c3000c \
+ , 0x73641b00 \
+ , 0xb3ff0009 \
+ , 0xebc40000 \
+ , 0x77621300 \
+ , 0x7805fb00 \
+ , 0xdbc410fd \
+ , 0xd84118f8 \
+ , 0x14051810 \
+ , 0xf0421304 \
+ , 0xf0442301 \
+ , 0xf4242310 \
+ , 0xb57ffff8 \
+ , 0xebc6004f \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0xb3ff002a \
+ , 0x55220800 \
+ , 0xebc6008c \
+ , 0xce040141 \
+ , 0xe1c6000c \
+ , 0xb3ff000f \
+ , 0xebc70000 \
+ , 0xdb5f293d \
+ , 0xebc3001f \
+ , 0xdc4320f8 \
+ , 0xcb03f8c0 \
+ , 0xdb451978 \
+ , 0xdbc710fd \
+ , 0xd84118f8 \
+ , 0xf4442310 \
+ , 0xdbc4113d \
+ , 0x04031810 \
+ , 0xd8422138 \
+ , 0x73632300 \
+ , 0xf0473b01 \
+ , 0xdc25f978 \
+ , 0xbc3ffff2 \
+ , 0x04020804 \
+ , 0x73623300 \
+ , 0x04020808 \
+ , 0xb6020011 \
+ , 0xebc60007 \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0x55220800 \
+ , 0x9ffff400 \
+ , 0x04040804 \
+ , 0xebc31100 \
+ , 0xf1441003 \
+ , 0xdbe2c09d \
+ , 0xb83f0069 \
+ , 0xe1c3000c \
+ , 0xbc240036 \
+ , 0xebc211fc \
+ , 0xe1c2000c \
+ , 0x73641300 \
+ , 0x77621300 \
+ , 0x7802fb00 \
+ , 0xbc420014 \
+ , 0xf1c41020 \
+ , 0x14020804 \
+ , 0xebc60007 \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0xb3ff00c0 \
+ , 0x55220800 \
+ , 0xb3ff0009 \
+ , 0xebc20000 \
+ , 0x77631b00 \
+ , 0x7805fb00 \
+ , 0xdbc2113d \
+ , 0xd8412138 \
+ , 0x14052010 \
+ , 0xf0431b04 \
+ , 0xf0421301 \
+ , 0xf4221315 \
+ , 0xb57ffff8 \
+ , 0xebc60063 \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0xb3ff00a4 \
+ , 0x55220800 \
+ , 0xebc211fc \
+ , 0xf1c41840 \
+ , 0xe1c2000c \
+ , 0x73631300 \
+ , 0x04060808 \
+ , 0xb3ff0010 \
+ , 0xebc20000 \
+ , 0xdb5f317d \
+ , 0xebc3001f \
+ , 0xdc4328f8 \
+ , 0xcb03f8c0 \
+ , 0xdb4619b8 \
+ , 0xdbc210fd \
+ , 0xd8411938 \
+ , 0xebc31100 \
+ , 0x04042010 \
+ , 0xdbc5117d \
+ , 0xe1c3000c \
+ , 0xd84518f8 \
+ , 0x73641b00 \
+ , 0xf0421301 \
+ , 0xdc26f9b8 \
+ , 0xbc3ffff1 \
+ , 0x04030804 \
+ , 0xebc211fc \
+ , 0xe1c2000c \
+ , 0x73631300 \
+ , 0x77621300 \
+ , 0x7802fb00 \
+ , 0xbc420085 \
+ , 0xf1c31020 \
+ , 0x14020804 \
+ , 0xebc60007 \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0xb3ff0073 \
+ , 0x55220800 \
+ , 0xf4221301 \
+ , 0xbc3f0038 \
+ , 0xbc240020 \
+ , 0xebc211fc \
+ , 0xe1c2000c \
+ , 0x73641300 \
+ , 0xb3ff0009 \
+ , 0xebc20000 \
+ , 0x77631b00 \
+ , 0x7805fb00 \
+ , 0xdbc2113d \
+ , 0xd8412138 \
+ , 0x14052010 \
+ , 0xf0431b04 \
+ , 0xf0421301 \
+ , 0xf4221308 \
+ , 0xb57ffff8 \
+ , 0xebc6002f \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0xb3ff0051 \
+ , 0x55220800 \
+ , 0xebc511fc \
+ , 0xf14422ff \
+ , 0xe1c5000c \
+ , 0xb3ff000f \
+ , 0xebc60000 \
+ , 0xdb5f20bd \
+ , 0xebc0001f \
+ , 0xdc401038 \
+ , 0xcb00f800 \
+ , 0xdb440138 \
+ , 0xdbc6103d \
+ , 0xd8410038 \
+ , 0xf4421310 \
+ , 0xdbc210bd \
+ , 0x04000010 \
+ , 0xd84310b8 \
+ , 0x73601300 \
+ , 0xf0463301 \
+ , 0xdc24f938 \
+ , 0xbc3ffff2 \
+ , 0x04000804 \
+ , 0xb3ff003a \
+ , 0x73602b00 \
+ , 0xf4221302 \
+ , 0xbc3f0037 \
+ , 0xbc240020 \
+ , 0xebc211fc \
+ , 0xe1c2000c \
+ , 0x73641300 \
+ , 0xb3ff0009 \
+ , 0xebc20000 \
+ , 0x77631b00 \
+ , 0x7805fb00 \
+ , 0xdbc2113d \
+ , 0xd8412138 \
+ , 0x14052010 \
+ , 0xf0431b04 \
+ , 0xf0421301 \
+ , 0xf4221302 \
+ , 0xb57ffff8 \
+ , 0xebc60017 \
+ , 0x041b0800 \
+ , 0xf4263307 \
+ , 0xb43f0006 \
+ , 0x04040008 \
+ , 0xf0461b01 \
+ , 0xcc0400a9 \
+ , 0xd9c218b8 \
+ , 0x14020008 \
+ , 0x04020008 \
+ , 0x06040000 \
+ , 0xcee26001 \
+ , 0xd86500f8 \
+ , 0xd8c4f8b8 \
+ , 0x71e63500 \
+ , 0xb3ff0018 \
+ , 0x55220800 \
+ , 0xebc511fc \
+ , 0xf14422ff \
+ , 0xe1c5000c \
+ , 0xb3ff000f \
+ , 0xebc60000 \
+ , 0xdb5f20bd \
+ , 0xebc0001f \
+ , 0xdc401038 \
+ , 0xcb00f800 \
+ , 0xdb440138 \
+ , 0xdbc6103d \
+ , 0xd8410038 \
+ , 0xf4421310 \
+ , 0xdbc210bd \
+ , 0x04000010 \
+ , 0xd84310b8 \
+ , 0x73601300 \
+ , 0xf0463301 \
+ , 0xdc24f938 \
+ , 0xbc3ffff2 \
+ , 0x04000804 \
+ , 0x73602b00 \
+ , 0x9ffff400 \
+ , 0xe3c00054 \
+ , 0x2c3f0000 \
+ , 0xffffffff \
+ , 0xebc00001 \
+ , 0x70e00101 \
+ , 0x2e3ffffb \
+ , 0xffffffff \
+ , 0x0618d000 \
+ , 0xec590008 \
+ , 0x0401e004 \
+ , 0x0400e008 \
+ , 0x06020808 \
+ , 0x16020008 \
+ , 0x06020800 \
+ , 0xa3fffff5 \
+ , 0x16020000 \
+ , 0x04020008 \
+ , 0x04010004 \
+ , 0xebc00001 \
+ , 0x14011000 \
+ , 0x70e00101 \
+ , 0x2e3ffff2 \
+ , 0xffffffff \
+ , 0x0618d000 \
+ , 0x0003e003 \
+ , 0xf05a0300 \
+ , 0xec230005 \
+ , 0xb81f001b \
+ , 0xf05c0b00 \
+ , 0x97430001 \
+ , 0xb7ff000a \
+ , 0xffffffff \
+ , 0xb7ff000b \
+ , 0xffffffff \
+ , 0xb7ff000c \
+ , 0xffffffff \
+ , 0xb3ff000d \
+ , 0xf0410300 \
+ , 0xb7ff000e \
+ , 0xffffffff \
+ , 0xa7fffe91 \
+ , 0xffffffff \
+ , 0xb7ff000c \
+ , 0xa7fffef6 \
+ , 0xffffffff \
+ , 0xb7ff0009 \
+ , 0xa7ffffd5 \
+ , 0xffffffff \
+ , 0xb7ff0006 \
+ , 0xa7ffffdf \
+ , 0xffffffff \
+ , 0xb7ff0003 \
+ , 0xa7fffe6b \
+ , 0xffffffff \
+ , 0xe3c00054 \
+ , 0x2c3f0000 \
+ , 0xffffffff \
+ , 0xebc23070 \
+ , 0xe1c2000c \
+ , 0x77621300 \
+ , 0x7803fb00 \
+ , 0x77631903 \
+ , 0xebc106a7 \
+ , 0xebc00018 \
+ , 0xe9c10000 \
+ , 0xe1c0000b \
+ , 0x73610300 \
+ , 0xebc00200 \
+ , 0xe1c0000b \
+ , 0xe3c18000 \
+ , 0x73610300 \
+ , 0xebc00204 \
+ , 0xe1c0000b \
+ , 0x737f0300 \
+ , 0xebc102c0 \
+ , 0xebc00028 \
+ , 0xe1c10050 \
+ , 0xe1c0000b \
+ , 0x73610300 \
+ , 0xf5430080 \
+ , 0x73601300 \
+ , 0xebc10008 \
+ , 0xe1c1000f \
+ , 0x77610b00 \
+ , 0x7800fb00 \
+ , 0xf1c00214 \
+ , 0x73600b00 \
+ , 0xe3c18100 \
+ , 0xe3c0000b \
+ , 0x73610300 \
+ , 0xc6000673 \
+ , 0x2c3ff000 \
+ , 0xffffffff \
+ , 0xebc20204 \
+ , 0xe1c2000b \
+ , 0x77621300 \
+ , 0x7801fb00 \
+ , 0xec21001f \
+ , 0xb41f002d \
+ , 0xe3c10100 \
+ , 0xe3c0000b \
+ , 0x73610300 \
+ , 0xebc00004 \
+ , 0xe1c0000b \
+ , 0x77600300 \
+ , 0x7800fb00 \
+ , 0xb4000025 \
+ , 0x77621300 \
+ , 0x7801fb00 \
+ , 0xebc00084 \
+ , 0xe1c0000f \
+ , 0x77600300 \
+ , 0x7800fb00 \
+ , 0xdc210078 \
+ , 0xbc3f001d \
+ , 0xebc0008c \
+ , 0xe1c0000f \
+ , 0x77600300 \
+ , 0x7800fb00 \
+ , 0xdc210078 \
+ , 0xbc3f0017 \
+ , 0xebc00064 \
+ , 0xe1c0000f \
+ , 0xefc10000 \
+ , 0x73610300 \
+ , 0xebc10008 \
+ , 0xe1c1000f \
+ , 0x77610b00 \
+ , 0x7800fb00 \
+ , 0xf1c00204 \
+ , 0xf5400210 \
+ , 0x73600b00 \
+ , 0xebc03070 \
+ , 0xe1c0000c \
+ , 0x737c0300 \
+ , 0xebc00200 \
+ , 0xe1c0000b \
+ , 0x737f0300 \
+ , 0xe3c00040 \
+ , 0xc60c3074 \
+ , 0x7360f300 \
+ , 0x281ff800 \
+ , 0xffffffff \
+ , 0x283ff800 \
+ , 0xffffffff \
+ , 0xebc00388 \
+ , 0xdbda409d \
+ , 0xdbda407d \
+ , 0xd9c20878 \
+ , 0xe1c0000b \
+ , 0xf05a1300 \
+ , 0x73610300 \
+ , 0x777ad103 \
+ , 0xb3ff0006 \
+ , 0xebc10000 \
+ , 0xdbc1103d \
+ , 0xd8420038 \
+ , 0x141f0000 \
+ , 0xf0410b01 \
+ , 0xf4210b40 \
+ , 0xb57ffffb \
+ , 0xebc00100 \
+ , 0x14001008 \
+ , 0x141f100c \
+ , 0xc6500010 \
+ , 0x2c3ff000 \
+ , 0xffffffff \
+ , 0xb3ff0003 \
+ , 0xebc30000 \
+ , 0x7803f900 \
+ , 0xbc03ffff \
+ , 0xebc13000 \
+ , 0xdbc3c0bd \
+ , 0xebc00203 \
+ , 0xd9c20038 \
+ , 0xe1c1000c \
+ , 0x73600b00 \
+ , 0xebc23078 \
+ , 0xe1c2000c \
+ , 0x77621300 \
+ , 0x7801fb00 \
+ , 0xdbc3803d \
+ , 0xf54109ff \
+ , 0xd9c10038 \
+ , 0x73601300 \
+ , 0x7c00f801 \
+ , 0x77031801 \
+ , 0x261fff7e \
+ , 0x77600001 \
+ , 0x9ffff400 \
+}
+
+#define P3041_R1_0_UC_IMG_INFO \
+ "U-code image for CC_HC_IM for P3041_r1.0. Image ID is: rel_101_8 \r\n" \
+ "\r\n"
+
+#endif /* __ALL_IMG_P3041_R1_0_H */
diff --git a/sys/contrib/ncsw/integrations/P3041/module_strings.c b/sys/contrib/ncsw/integrations/P3041/module_strings.c
new file mode 100644
index 0000000..4fc7bc8
--- /dev/null
+++ b/sys/contrib/ncsw/integrations/P3041/module_strings.c
@@ -0,0 +1,62 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Module names for debug messages */
+const char *moduleStrings[] =
+{
+ "???" /* MODULE_UNKNOWN */
+ ,"MEM" /* MODULE_ */
+ ,"MM" /* MODULE_MM */
+ ,"CORE" /* MODULE_CORE */
+ ,"P3041" /* MODULE_P3041 */
+ ,"P3041-Platform" /* MODULE_P3041_PLTFRM */
+ ,"PM" /* MODULE_PM */
+ ,"MMU" /* MODULE_MMU */
+ ,"PIC" /* MODULE_PIC */
+ ,"L3 cache (CPC)" /* MODULE_CPC */
+ ,"DUART" /* MODULE_DUART */
+ ,"SerDes" /* MODULE_SERDES */
+ ,"PIO" /* MODULE_PIO */
+ ,"QM" /* MODULE_QM */
+ ,"BM" /* MODULE_BM */
+ ,"SEC" /* MODULE_SEC */
+ ,"LAW" /* MODULE_LAW */
+ ,"LBC" /* MODULE_LBC */
+ ,"PAMU" /* MODULE_PAMU */
+ ,"FM" /* MODULE_FM */
+ ,"FM-MURAM" /* MODULE_FM_MURAM */
+ ,"FM-PCD" /* MODULE_FM_PCD */
+ ,"FM-RTC" /* MODULE_FM_RTC */
+ ,"FM-MAC" /* MODULE_FM_MAC */
+ ,"FM-Port" /* MODULE_FM_PORT */
+ ,"DPA" /* MODULE_DPA */
+};
diff --git a/sys/contrib/ncsw/integrations/P5020/module_strings.c b/sys/contrib/ncsw/integrations/P5020/module_strings.c
new file mode 100644
index 0000000..84509d0
--- /dev/null
+++ b/sys/contrib/ncsw/integrations/P5020/module_strings.c
@@ -0,0 +1,62 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Module names for debug messages */
+const char *moduleStrings[] =
+{
+ "???" /* MODULE_UNKNOWN */
+ ,"MEM" /* MODULE_ */
+ ,"MM" /* MODULE_MM */
+ ,"CORE" /* MODULE_CORE */
+ ,"P5020" /* MODULE_P5020 */
+ ,"P5020-Platform" /* MODULE_P5020_PLTFRM */
+ ,"PM" /* MODULE_PM */
+ ,"MMU" /* MODULE_MMU */
+ ,"PIC" /* MODULE_PIC */
+ ,"L3 cache (CPC)" /* MODULE_CPC */
+ ,"DUART" /* MODULE_DUART */
+ ,"SerDes" /* MODULE_SERDES */
+ ,"PIO" /* MODULE_PIO */
+ ,"QM" /* MODULE_QM */
+ ,"BM" /* MODULE_BM */
+ ,"SEC" /* MODULE_SEC */
+ ,"LAW" /* MODULE_LAW */
+ ,"LBC" /* MODULE_LBC */
+ ,"PAMU" /* MODULE_PAMU */
+ ,"FM" /* MODULE_FM */
+ ,"FM-MURAM" /* MODULE_FM_MURAM */
+ ,"FM-PCD" /* MODULE_FM_PCD */
+ ,"FM-RTC" /* MODULE_FM_RTC */
+ ,"FM-MAC" /* MODULE_FM_MAC */
+ ,"FM-Port" /* MODULE_FM_PORT */
+ ,"DPA" /* MODULE_DPA */
+};
diff --git a/sys/contrib/ncsw/integrations/fman_ucode.h b/sys/contrib/ncsw/integrations/fman_ucode.h
new file mode 100644
index 0000000..7dfb151
--- /dev/null
+++ b/sys/contrib/ncsw/integrations/fman_ucode.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef FMAN_UCODE_H_
+#define FMAN_UCODE_H_
+
+/**
+ * @file
+ * Wrapper header for FMan uCode.
+ *
+ * We intentionally use the same uCode from p3041_r1.0.h file as all platforms
+ * we're currently supporting uses the same version of uCode marked rel_101_8.
+ */
+
+/**
+ * Header with actual uCode rel_101_8.
+ */
+#include "P3041/fman_ctrl_code/p3041_r1.0.h"
+
+/**
+ * Generic macro.
+ */
+#define FMAN_UC_IMG P3041_R1_0_UC_IMG
+
+#endif /* FMAN_UCODE_H_ */
diff --git a/sys/contrib/ncsw/user/env/core.c b/sys/contrib/ncsw/user/env/core.c
new file mode 100644
index 0000000..7518675
--- /dev/null
+++ b/sys/contrib/ncsw/user/env/core.c
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2011 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/pcpu.h>
+
+#include <machine/pcpu.h>
+
+#include "types_ext.h"
+#include "core_ext.h"
+
+uint32_t E500_GetId()
+{
+ return PCPU_GET(cpuid);
+}
+
diff --git a/sys/contrib/ncsw/user/env/stdlib.c b/sys/contrib/ncsw/user/env/stdlib.c
new file mode 100644
index 0000000..0dbedcb
--- /dev/null
+++ b/sys/contrib/ncsw/user/env/stdlib.c
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2011 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/libkern.h>
+#include "string_ext.h"
+
+char *
+strtok(char *s, const char *ct)
+{
+ return 0;
+}
diff --git a/sys/contrib/ncsw/user/env/xx.c b/sys/contrib/ncsw/user/env/xx.c
new file mode 100644
index 0000000..0ca7bc1
--- /dev/null
+++ b/sys/contrib/ncsw/user/env/xx.c
@@ -0,0 +1,949 @@
+/*-
+ * Copyright (c) 2011 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/rman.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_page.h>
+
+#include <machine/cpufunc.h>
+#include <machine/intr_machdep.h>
+#include <machine/pmap.h>
+#include <machine/stdarg.h>
+
+#include <dev/dpaa/bman.h>
+#include <dev/dpaa/qman.h>
+#include <dev/dpaa/portals.h>
+
+#include "error_ext.h"
+#include "std_ext.h"
+#include "list_ext.h"
+#include "mm_ext.h"
+
+/* Configuration */
+
+/* Define the number of dTSEC ports active in system */
+#define MALLOCSMART_DTSEC_IN_USE 4
+
+/*
+ * Calculate malloc's pool size for dTSEC's buffers.
+ * We reserve 1MB pool for each dTSEC port.
+ */
+#define MALLOCSMART_POOL_SIZE \
+ (MALLOCSMART_DTSEC_IN_USE * 1024 * 1024)
+
+#define MALLOCSMART_SLICE_SIZE (PAGE_SIZE / 2) /* 2kB */
+
+/* Defines */
+#define MALLOCSMART_SIZE_TO_SLICE(x) \
+ (((x) + MALLOCSMART_SLICE_SIZE - 1) / MALLOCSMART_SLICE_SIZE)
+#define MALLOCSMART_SLICES \
+ MALLOCSMART_SIZE_TO_SLICE(MALLOCSMART_POOL_SIZE)
+
+/* Malloc Pool for NetCommSW */
+MALLOC_DEFINE(M_NETCOMMSW, "NetCommSW", "NetCommSW software stack");
+MALLOC_DEFINE(M_NETCOMMSW_MT, "NetCommSWTrack",
+ "NetCommSW software allocation tracker");
+
+/* MallocSmart data structures */
+static void *XX_MallocSmartPool;
+static int XX_MallocSmartMap[MALLOCSMART_SLICES];
+
+static struct mtx XX_MallocSmartLock;
+static struct mtx XX_MallocTrackLock;
+MTX_SYSINIT(XX_MallocSmartLockInit, &XX_MallocSmartLock,
+ "NetCommSW MallocSmart Lock", MTX_DEF);
+MTX_SYSINIT(XX_MallocTrackLockInit, &XX_MallocTrackLock,
+ "NetCommSW MallocTrack Lock", MTX_DEF);
+
+/* Interrupt info */
+#define XX_INTR_FLAG_PREALLOCATED (1 << 0)
+#define XX_INTR_FLAG_BOUND (1 << 1)
+#define XX_INTR_FLAG_FMAN_FIX (1 << 2)
+
+struct XX_IntrInfo {
+ driver_intr_t *handler;
+ void *arg;
+ int cpu;
+ int flags;
+ void *cookie;
+};
+
+static struct XX_IntrInfo XX_IntrInfo[INTR_VECTORS];
+/* Portal type identifiers */
+enum XX_PortalIdent{
+ BM_PORTAL = 0,
+ QM_PORTAL,
+};
+/* Structure to store portals' properties */
+struct XX_PortalInfo {
+ vm_paddr_t portal_ce_pa[2][MAXCPU];
+ vm_paddr_t portal_ci_pa[2][MAXCPU];
+ uint32_t portal_ce_size[2][MAXCPU];
+ uint32_t portal_ci_size[2][MAXCPU];
+ vm_offset_t portal_ce_va[2];
+ vm_offset_t portal_ci_va[2];
+ uint32_t portal_intr[2][MAXCPU];
+};
+
+static struct XX_PortalInfo XX_PInfo;
+
+/* The lower 9 bits, through emprical testing, tend to be 0. */
+#define XX_MALLOC_TRACK_SHIFT 9
+
+typedef struct XX_MallocTrackStruct {
+ LIST_ENTRY(XX_MallocTrackStruct) entries;
+ physAddress_t pa;
+ void *va;
+} XX_MallocTrackStruct;
+
+LIST_HEAD(XX_MallocTrackerList, XX_MallocTrackStruct) *XX_MallocTracker;
+u_long XX_MallocHashMask;
+static XX_MallocTrackStruct * XX_FindTracker(physAddress_t pa);
+
+void
+XX_Exit(int status)
+{
+
+ panic("NetCommSW: Exit called with status %i", status);
+}
+
+void
+XX_Print(char *str, ...)
+{
+ va_list ap;
+
+ va_start(ap, str);
+ vprintf(str, ap);
+ va_end(ap);
+}
+
+void *
+XX_Malloc(uint32_t size)
+{
+ void *p = (malloc(size, M_NETCOMMSW, M_NOWAIT));
+
+ return (p);
+}
+
+static int
+XX_MallocSmartMapCheck(unsigned int start, unsigned int slices)
+{
+ unsigned int i;
+
+ mtx_assert(&XX_MallocSmartLock, MA_OWNED);
+ for (i = start; i < start + slices; i++)
+ if (XX_MallocSmartMap[i])
+ return (FALSE);
+ return (TRUE);
+}
+
+static void
+XX_MallocSmartMapSet(unsigned int start, unsigned int slices)
+{
+ unsigned int i;
+
+ mtx_assert(&XX_MallocSmartLock, MA_OWNED);
+
+ for (i = start; i < start + slices; i++)
+ XX_MallocSmartMap[i] = ((i == start) ? slices : -1);
+}
+
+static void
+XX_MallocSmartMapClear(unsigned int start, unsigned int slices)
+{
+ unsigned int i;
+
+ mtx_assert(&XX_MallocSmartLock, MA_OWNED);
+
+ for (i = start; i < start + slices; i++)
+ XX_MallocSmartMap[i] = 0;
+}
+
+int
+XX_MallocSmartInit(void)
+{
+ int error;
+
+ error = E_OK;
+ mtx_lock(&XX_MallocSmartLock);
+
+ if (XX_MallocSmartPool)
+ goto out;
+
+ /* Allocate MallocSmart pool */
+ XX_MallocSmartPool = contigmalloc(MALLOCSMART_POOL_SIZE, M_NETCOMMSW,
+ M_NOWAIT, 0, 0xFFFFFFFFFull, MALLOCSMART_POOL_SIZE, 0);
+ if (!XX_MallocSmartPool) {
+ error = E_NO_MEMORY;
+ goto out;
+ }
+
+out:
+ mtx_unlock(&XX_MallocSmartLock);
+ return (error);
+}
+
+void *
+XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
+{
+ unsigned int i;
+ vm_offset_t addr;
+
+ addr = 0;
+
+ /* Convert alignment and size to number of slices */
+ alignment = MALLOCSMART_SIZE_TO_SLICE(alignment);
+ size = MALLOCSMART_SIZE_TO_SLICE(size);
+
+ /* Lock resources */
+ mtx_lock(&XX_MallocSmartLock);
+
+ /* Allocate region */
+ for (i = 0; i + size <= MALLOCSMART_SLICES; i += alignment) {
+ if (XX_MallocSmartMapCheck(i, size)) {
+ XX_MallocSmartMapSet(i, size);
+ addr = (vm_offset_t)XX_MallocSmartPool +
+ (i * MALLOCSMART_SLICE_SIZE);
+ break;
+ }
+ }
+
+ /* Unlock resources */
+ mtx_unlock(&XX_MallocSmartLock);
+
+ return ((void *)addr);
+}
+
+void
+XX_FreeSmart(void *p)
+{
+ unsigned int start, slices;
+
+ /* Calculate first slice of region */
+ start = MALLOCSMART_SIZE_TO_SLICE((vm_offset_t)(p) -
+ (vm_offset_t)XX_MallocSmartPool);
+
+ /* Lock resources */
+ mtx_lock(&XX_MallocSmartLock);
+
+ KASSERT(XX_MallocSmartMap[start] > 0,
+ ("XX_FreeSmart: Double or mid-block free!\n"));
+
+ XX_UntrackAddress(p);
+ /* Free region */
+ slices = XX_MallocSmartMap[start];
+ XX_MallocSmartMapClear(start, slices);
+
+ /* Unlock resources */
+ mtx_unlock(&XX_MallocSmartLock);
+}
+
+void
+XX_Free(void *p)
+{
+
+ if (p != NULL)
+ XX_UntrackAddress(p);
+ free(p, M_NETCOMMSW);
+}
+
+uint32_t
+XX_DisableAllIntr(void)
+{
+
+ return (intr_disable());
+}
+
+void
+XX_RestoreAllIntr(uint32_t flags)
+{
+
+ intr_restore(flags);
+}
+
+t_Error
+XX_Call(uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (E_OK);
+}
+
+static bool
+XX_IsPortalIntr(int irq)
+{
+ int cpu, type;
+ /* Check interrupt numbers of all available portals */
+ for (cpu = 0, type = 0; XX_PInfo.portal_intr[type][cpu] != 0; cpu++) {
+ if (irq == XX_PInfo.portal_intr[type][cpu]) {
+ /* Found it! */
+ return (1);
+ }
+ if (XX_PInfo.portal_intr[type][cpu + 1] == 0) {
+ type++;
+ cpu = 0;
+ }
+ }
+
+ return (0);
+}
+
+void
+XX_FmanFixIntr(int irq)
+{
+
+ XX_IntrInfo[irq].flags |= XX_INTR_FLAG_FMAN_FIX;
+}
+
+static bool
+XX_FmanNeedsIntrFix(int irq)
+{
+
+ if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_FMAN_FIX)
+ return (1);
+
+ return (0);
+}
+
+static void
+XX_Dispatch(void *arg)
+{
+ struct XX_IntrInfo *info;
+
+ info = arg;
+
+ /* Bind this thread to proper CPU when SMP has been already started. */
+ if ((info->flags & XX_INTR_FLAG_BOUND) == 0 && smp_started &&
+ info->cpu >= 0) {
+ thread_lock(curthread);
+ sched_bind(curthread, info->cpu);
+ thread_unlock(curthread);
+
+ info->flags |= XX_INTR_FLAG_BOUND;
+ }
+
+ if (info->handler == NULL) {
+ printf("%s(): IRQ handler is NULL!\n", __func__);
+ return;
+ }
+
+ info->handler(info->arg);
+}
+
+t_Error
+XX_PreallocAndBindIntr(int irq, unsigned int cpu)
+{
+ struct resource *r;
+ unsigned int inum;
+ t_Error error;
+
+ r = (struct resource *)irq;
+ inum = rman_get_start(r);
+
+ error = XX_SetIntr(irq, XX_Dispatch, &XX_IntrInfo[inum]);
+ if (error != 0)
+ return (error);
+
+ XX_IntrInfo[inum].flags = XX_INTR_FLAG_PREALLOCATED;
+ XX_IntrInfo[inum].cpu = cpu;
+
+ return (E_OK);
+}
+
+t_Error
+XX_DeallocIntr(int irq)
+{
+ struct resource *r;
+ unsigned int inum;
+
+ r = (struct resource *)irq;
+ inum = rman_get_start(r);
+
+ if ((XX_IntrInfo[inum].flags & XX_INTR_FLAG_PREALLOCATED) == 0)
+ return (E_INVALID_STATE);
+
+ XX_IntrInfo[inum].flags = 0;
+ return (XX_FreeIntr(irq));
+}
+
+t_Error
+XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
+{
+ struct device *dev;
+ struct resource *r;
+ unsigned int flags;
+ int err;
+
+ r = (struct resource *)irq;
+ dev = rman_get_device(r);
+ irq = rman_get_start(r);
+
+ /* Handle preallocated interrupts */
+ if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
+ if (XX_IntrInfo[irq].handler != NULL)
+ return (E_BUSY);
+
+ XX_IntrInfo[irq].handler = f_Isr;
+ XX_IntrInfo[irq].arg = handle;
+
+ return (E_OK);
+ }
+
+ flags = INTR_TYPE_NET | INTR_MPSAFE;
+
+ /* BMAN/QMAN Portal interrupts must be exlusive */
+ if (XX_IsPortalIntr(irq))
+ flags |= INTR_EXCL;
+
+ err = bus_setup_intr(dev, r, flags, NULL, f_Isr, handle,
+ &XX_IntrInfo[irq].cookie);
+ if (err)
+ goto finish;
+
+ /*
+ * XXX: Bind FMan IRQ to CPU0. Current interrupt subsystem directs each
+ * interrupt to all CPUs. Race between an interrupt assertion and
+ * masking may occur and interrupt handler may be called multiple times
+ * per one interrupt. FMan doesn't support such a situation. Workaround
+ * is to bind FMan interrupt to one CPU0 only.
+ */
+#ifdef SMP
+ if (XX_FmanNeedsIntrFix(irq))
+ err = powerpc_bind_intr(irq, 0);
+#endif
+finish:
+ return (err);
+}
+
+t_Error
+XX_FreeIntr(int irq)
+{
+ struct device *dev;
+ struct resource *r;
+
+ r = (struct resource *)irq;
+ dev = rman_get_device(r);
+ irq = rman_get_start(r);
+
+ /* Handle preallocated interrupts */
+ if (XX_IntrInfo[irq].flags & XX_INTR_FLAG_PREALLOCATED) {
+ if (XX_IntrInfo[irq].handler == NULL)
+ return (E_INVALID_STATE);
+
+ XX_IntrInfo[irq].handler = NULL;
+ XX_IntrInfo[irq].arg = NULL;
+
+ return (E_OK);
+ }
+
+ return (bus_teardown_intr(dev, r, XX_IntrInfo[irq].cookie));
+}
+
+t_Error
+XX_EnableIntr(int irq)
+{
+ struct resource *r;
+
+ r = (struct resource *)irq;
+ irq = rman_get_start(r);
+
+ powerpc_intr_unmask(irq);
+
+ return (E_OK);
+}
+
+t_Error
+XX_DisableIntr(int irq)
+{
+ struct resource *r;
+
+ r = (struct resource *)irq;
+ irq = rman_get_start(r);
+
+ powerpc_intr_mask(irq);
+
+ return (E_OK);
+}
+
+t_TaskletHandle
+XX_InitTasklet (void (*routine)(void *), void *data)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (NULL);
+}
+
+
+void
+XX_FreeTasklet (t_TaskletHandle h_Tasklet)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+}
+
+int
+XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (0);
+}
+
+void
+XX_FlushScheduledTasks(void)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+}
+
+int
+XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (0);
+}
+
+void
+XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+}
+
+t_Handle
+XX_GetTaskletData(t_TaskletHandle h_Tasklet)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (NULL);
+}
+
+t_Handle
+XX_InitSpinlock(void)
+{
+ struct mtx *m;
+
+ m = malloc(sizeof(*m), M_NETCOMMSW, M_NOWAIT);
+ if (!m)
+ return (0);
+
+ mtx_init(m, "NetCommSW Lock", NULL, MTX_DEF | MTX_DUPOK);
+
+ return (m);
+}
+
+void
+XX_FreeSpinlock(t_Handle h_Spinlock)
+{
+ struct mtx *m;
+
+ m = h_Spinlock;
+
+ mtx_destroy(m);
+ free(m, M_NETCOMMSW);
+}
+
+void
+XX_LockSpinlock(t_Handle h_Spinlock)
+{
+ struct mtx *m;
+
+ m = h_Spinlock;
+ mtx_lock(m);
+}
+
+void
+XX_UnlockSpinlock(t_Handle h_Spinlock)
+{
+ struct mtx *m;
+
+ m = h_Spinlock;
+ mtx_unlock(m);
+}
+
+uint32_t
+XX_LockIntrSpinlock(t_Handle h_Spinlock)
+{
+
+ XX_LockSpinlock(h_Spinlock);
+ return (0);
+}
+
+void
+XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
+{
+
+ XX_UnlockSpinlock(h_Spinlock);
+}
+
+uint32_t
+XX_CurrentTime(void)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (0);
+}
+
+
+t_Handle
+XX_CreateTimer(void)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (NULL);
+}
+
+void
+XX_FreeTimer(t_Handle h_Timer)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+}
+
+void
+XX_StartTimer(t_Handle h_Timer,
+ uint32_t msecs,
+ bool periodic,
+ void (*f_TimerExpired)(t_Handle),
+ t_Handle h_Arg)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+}
+
+uint32_t
+XX_GetExpirationTime(t_Handle h_Timer)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (0);
+}
+
+void
+XX_StopTimer(t_Handle h_Timer)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+}
+
+void
+XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+}
+
+int
+XX_TimerIsActive(t_Handle h_Timer)
+{
+ /* Not referenced */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (0);
+}
+
+uint32_t
+XX_Sleep(uint32_t msecs)
+{
+
+ XX_UDelay(1000 * msecs);
+ return (0);
+}
+
+void
+XX_UDelay(uint32_t usecs)
+{
+ DELAY(usecs);
+}
+
+t_Error
+XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
+ t_IpcMsgHandler *f_MsgHandler, t_Handle h_Module, uint32_t replyLength)
+{
+
+ /*
+ * This function returns fake E_OK status and does nothing
+ * as NetCommSW IPC is not used by FreeBSD drivers.
+ */
+ return (E_OK);
+}
+
+t_Error
+XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
+{
+ /*
+ * This function returns fake E_OK status and does nothing
+ * as NetCommSW IPC is not used by FreeBSD drivers.
+ */
+ return (E_OK);
+}
+
+
+t_Error
+XX_IpcSendMessage(t_Handle h_Session,
+ uint8_t *p_Msg, uint32_t msgLength, uint8_t *p_Reply,
+ uint32_t *p_ReplyLength, t_IpcMsgCompletion *f_Completion, t_Handle h_Arg)
+{
+
+ /* Should not be called */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (E_OK);
+}
+
+t_Handle
+XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
+ char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
+{
+
+ /* Should not be called */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (E_OK);
+}
+
+t_Error
+XX_IpcFreeSession(t_Handle h_Session)
+{
+
+ /* Should not be called */
+ printf("NetCommSW: Unimplemented function %s() called!\n", __func__);
+ return (E_OK);
+}
+
+extern void db_trace_self(void);
+physAddress_t
+XX_VirtToPhys(void *addr)
+{
+ vm_paddr_t paddr;
+ int cpu;
+
+ cpu = PCPU_GET(cpuid);
+
+ /* Handle NULL address */
+ if (addr == NULL)
+ return (-1);
+
+ /* Handle BMAN mappings */
+ if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[BM_PORTAL]) &&
+ ((vm_offset_t)addr < XX_PInfo.portal_ce_va[BM_PORTAL] +
+ XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
+ return (XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
+ (vm_offset_t)addr - XX_PInfo.portal_ce_va[BM_PORTAL]);
+
+ if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[BM_PORTAL]) &&
+ ((vm_offset_t)addr < XX_PInfo.portal_ci_va[BM_PORTAL] +
+ XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
+ return (XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
+ (vm_offset_t)addr - XX_PInfo.portal_ci_va[BM_PORTAL]);
+
+ /* Handle QMAN mappings */
+ if (((vm_offset_t)addr >= XX_PInfo.portal_ce_va[QM_PORTAL]) &&
+ ((vm_offset_t)addr < XX_PInfo.portal_ce_va[QM_PORTAL] +
+ XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
+ return (XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
+ (vm_offset_t)addr - XX_PInfo.portal_ce_va[QM_PORTAL]);
+
+ if (((vm_offset_t)addr >= XX_PInfo.portal_ci_va[QM_PORTAL]) &&
+ ((vm_offset_t)addr < XX_PInfo.portal_ci_va[QM_PORTAL] +
+ XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
+ return (XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
+ (vm_offset_t)addr - XX_PInfo.portal_ci_va[QM_PORTAL]);
+
+ paddr = pmap_kextract((vm_offset_t)addr);
+ if (!paddr)
+ printf("NetCommSW: "
+ "Unable to translate virtual address 0x%08X!\n", addr);
+ else
+ XX_TrackAddress(addr);
+
+ return (paddr);
+}
+
+void *
+XX_PhysToVirt(physAddress_t addr)
+{
+ XX_MallocTrackStruct *ts;
+ int cpu;
+
+ cpu = PCPU_GET(cpuid);
+
+ /* Handle BMAN mappings */
+ if ((addr >= XX_PInfo.portal_ce_pa[BM_PORTAL][cpu]) &&
+ (addr < XX_PInfo.portal_ce_pa[BM_PORTAL][cpu] +
+ XX_PInfo.portal_ce_size[BM_PORTAL][cpu]))
+ return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
+ (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
+
+ if ((addr >= XX_PInfo.portal_ci_pa[BM_PORTAL][cpu]) &&
+ (addr < XX_PInfo.portal_ci_pa[BM_PORTAL][cpu] +
+ XX_PInfo.portal_ci_size[BM_PORTAL][cpu]))
+ return ((void *)(XX_PInfo.portal_ci_va[BM_PORTAL] +
+ (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[BM_PORTAL][cpu])));
+
+ /* Handle QMAN mappings */
+ if ((addr >= XX_PInfo.portal_ce_pa[QM_PORTAL][cpu]) &&
+ (addr < XX_PInfo.portal_ce_pa[QM_PORTAL][cpu] +
+ XX_PInfo.portal_ce_size[QM_PORTAL][cpu]))
+ return ((void *)(XX_PInfo.portal_ce_va[QM_PORTAL] +
+ (vm_offset_t)(addr - XX_PInfo.portal_ce_pa[QM_PORTAL][cpu])));
+
+ if ((addr >= XX_PInfo.portal_ci_pa[QM_PORTAL][cpu]) &&
+ (addr < XX_PInfo.portal_ci_pa[QM_PORTAL][cpu] +
+ XX_PInfo.portal_ci_size[QM_PORTAL][cpu]))
+ return ((void *)(XX_PInfo.portal_ci_va[QM_PORTAL] +
+ (vm_offset_t)(addr - XX_PInfo.portal_ci_pa[QM_PORTAL][cpu])));
+
+ mtx_lock(&XX_MallocTrackLock);
+ ts = XX_FindTracker(addr);
+ mtx_unlock(&XX_MallocTrackLock);
+
+ if (ts != NULL)
+ return ts->va;
+
+ printf("NetCommSW: "
+ "Unable to translate physical address 0x%08llX!\n", addr);
+
+ return (NULL);
+}
+
+void
+XX_PortalSetInfo(device_t dev)
+{
+ char *dev_name;
+ struct dpaa_portals_softc *sc;
+ int i, type, len;
+
+ dev_name = malloc(sizeof(*dev_name), M_TEMP, M_WAITOK |
+ M_ZERO);
+
+ len = strlen("bman-portals");
+
+ strncpy(dev_name, device_get_name(dev), len);
+
+ if (strncmp(dev_name, "bman-portals", len) && strncmp(dev_name,
+ "qman-portals", len))
+ goto end;
+
+ if (strncmp(dev_name, "bman-portals", len) == 0)
+ type = BM_PORTAL;
+ else
+ type = QM_PORTAL;
+
+ sc = device_get_softc(dev);
+
+ for (i = 0; sc->sc_dp[i].dp_ce_pa != 0; i++) {
+ XX_PInfo.portal_ce_pa[type][i] = sc->sc_dp[i].dp_ce_pa;
+ XX_PInfo.portal_ci_pa[type][i] = sc->sc_dp[i].dp_ci_pa;
+ XX_PInfo.portal_ce_size[type][i] = sc->sc_dp[i].dp_ce_size;
+ XX_PInfo.portal_ci_size[type][i] = sc->sc_dp[i].dp_ci_size;
+ XX_PInfo.portal_intr[type][i] = sc->sc_dp[i].dp_intr_num;
+ }
+
+ XX_PInfo.portal_ce_va[type] = rman_get_bushandle(sc->sc_rres[0]);
+ XX_PInfo.portal_ci_va[type] = rman_get_bushandle(sc->sc_rres[1]);
+end:
+ free(dev_name, M_TEMP);
+}
+
+static XX_MallocTrackStruct *
+XX_FindTracker(physAddress_t pa)
+{
+ struct XX_MallocTrackerList *l;
+ XX_MallocTrackStruct *tp;
+
+ l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
+
+ LIST_FOREACH(tp, l, entries) {
+ if (tp->pa == pa)
+ return tp;
+ }
+
+ return NULL;
+}
+
+void
+XX_TrackInit(void)
+{
+ if (XX_MallocTracker == NULL) {
+ XX_MallocTracker = hashinit(64, M_NETCOMMSW_MT,
+ &XX_MallocHashMask);
+ }
+}
+
+void
+XX_TrackAddress(void *addr)
+{
+ physAddress_t pa;
+ struct XX_MallocTrackerList *l;
+ XX_MallocTrackStruct *ts;
+
+ pa = pmap_kextract((vm_offset_t)addr);
+
+ ts = malloc(sizeof(*ts), M_NETCOMMSW_MT, M_NOWAIT);
+ ts->va = addr;
+ ts->pa = pa;
+
+ l = &XX_MallocTracker[(pa >> XX_MALLOC_TRACK_SHIFT) & XX_MallocHashMask];
+
+ mtx_lock(&XX_MallocTrackLock);
+ if (XX_FindTracker(pa) != NULL)
+ free(ts, M_NETCOMMSW_MT);
+ else
+ LIST_INSERT_HEAD(l, ts, entries);
+ mtx_unlock(&XX_MallocTrackLock);
+}
+
+void
+XX_UntrackAddress(void *addr)
+{
+ physAddress_t pa;
+ XX_MallocTrackStruct *ts;
+
+ pa = pmap_kextract((vm_offset_t)addr);
+
+ KASSERT(XX_MallocTracker != NULL,
+ ("Untracking an address before it's even initialized!\n"));
+
+ mtx_lock(&XX_MallocTrackLock);
+ ts = XX_FindTracker(pa);
+ if (ts != NULL)
+ LIST_REMOVE(ts, entries);
+ mtx_unlock(&XX_MallocTrackLock);
+ free(ts, M_NETCOMMSW_MT);
+}
diff --git a/sys/dev/dpaa/bman.c b/sys/dev/dpaa/bman.c
new file mode 100644
index 0000000..02499c4
--- /dev/null
+++ b/sys/dev/dpaa/bman.c
@@ -0,0 +1,370 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/rman.h>
+#include <sys/sched.h>
+
+#include <machine/tlb.h>
+
+#include "bman.h"
+
+devclass_t bman_devclass;
+
+static struct bman_softc *bman_sc;
+
+extern t_Handle bman_portal_setup(struct bman_softc *bsc);
+
+static void
+bman_exception(t_Handle h_App, e_BmExceptions exception)
+{
+ struct bman_softc *sc;
+ const char *message;
+
+ sc = h_App;
+
+ switch (exception) {
+ case e_BM_EX_INVALID_COMMAND:
+ message = "Invalid Command Verb";
+ break;
+ case e_BM_EX_FBPR_THRESHOLD:
+ message = "FBPR pool exhaused. Consider increasing "
+ "BMAN_MAX_BUFFERS";
+ break;
+ case e_BM_EX_SINGLE_ECC:
+ message = "Single bit ECC error";
+ break;
+ case e_BM_EX_MULTI_ECC:
+ message = "Multi bit ECC error";
+ break;
+ default:
+ message = "Unknown error";
+ }
+
+ device_printf(sc->sc_dev, "BMAN Exception: %s.\n", message);
+}
+
+int
+bman_attach(device_t dev)
+{
+ struct bman_softc *sc;
+ t_BmRevisionInfo rev;
+ t_Error error;
+ t_BmParam bp;
+
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+ bman_sc = sc;
+
+ /* Check if MallocSmart allocator is ready */
+ if (XX_MallocSmartInit() != E_OK)
+ return (ENXIO);
+
+ /* Allocate resources */
+ sc->sc_rrid = 0;
+ sc->sc_rres = bus_alloc_resource(dev, SYS_RES_MEMORY,
+ &sc->sc_rrid, 0, ~0, BMAN_CCSR_SIZE, RF_ACTIVE);
+ if (sc->sc_rres == NULL)
+ return (ENXIO);
+
+ sc->sc_irid = 0;
+ sc->sc_ires = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
+ &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
+ if (sc->sc_ires == NULL)
+ goto err;
+
+ /* Initialize BMAN */
+ memset(&bp, 0, sizeof(bp));
+ bp.guestId = NCSW_MASTER_ID;
+ bp.baseAddress = rman_get_bushandle(sc->sc_rres);
+ bp.totalNumOfBuffers = BMAN_MAX_BUFFERS;
+ bp.f_Exception = bman_exception;
+ bp.h_App = sc;
+ bp.errIrq = (int)sc->sc_ires;
+ bp.partBpidBase = 0;
+ bp.partNumOfPools = BM_MAX_NUM_OF_POOLS;
+ printf("base address: %llx\n", (uint64_t)bp.baseAddress);
+
+ sc->sc_bh = BM_Config(&bp);
+ if (sc->sc_bh == NULL)
+ goto err;
+
+ /* Warn if there is less than 5% free FPBR's in pool */
+ error = BM_ConfigFbprThreshold(sc->sc_bh, (BMAN_MAX_BUFFERS / 8) / 20);
+ if (error != E_OK)
+ goto err;
+
+ error = BM_Init(sc->sc_bh);
+ if (error != E_OK)
+ goto err;
+
+ error = BM_GetRevision(sc->sc_bh, &rev);
+ if (error != E_OK)
+ goto err;
+
+ device_printf(dev, "Hardware version: %d.%d.\n",
+ rev.majorRev, rev.minorRev);
+
+ return (0);
+
+err:
+ bman_detach(dev);
+ return (ENXIO);
+}
+
+int
+bman_detach(device_t dev)
+{
+ struct bman_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->sc_bh != NULL)
+ BM_Free(sc->sc_bh);
+
+ if (sc->sc_ires != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->sc_irid, sc->sc_ires);
+
+ if (sc->sc_rres != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->sc_rrid, sc->sc_rres);
+
+ return (0);
+}
+
+int
+bman_suspend(device_t dev)
+{
+
+ return (0);
+}
+
+int
+bman_resume(device_t dev)
+{
+
+ return (0);
+}
+
+int
+bman_shutdown(device_t dev)
+{
+
+ return (0);
+}
+
+/*
+ * BMAN API
+ */
+
+t_Handle
+bman_pool_create(uint8_t *bpid, uint16_t bufferSize, uint16_t maxBuffers,
+ uint16_t minBuffers, uint16_t allocBuffers, t_GetBufFunction *f_GetBuf,
+ t_PutBufFunction *f_PutBuf, uint32_t dep_sw_entry, uint32_t dep_sw_exit,
+ uint32_t dep_hw_entry, uint32_t dep_hw_exit,
+ t_BmDepletionCallback *f_Depletion, t_Handle h_BufferPool,
+ t_PhysToVirt *f_PhysToVirt, t_VirtToPhys *f_VirtToPhys)
+{
+ uint32_t thresholds[MAX_DEPLETION_THRESHOLDS];
+ struct bman_softc *sc;
+ t_Handle pool, portal;
+ t_BmPoolParam bpp;
+ int error;
+
+ sc = bman_sc;
+ pool = NULL;
+
+ sched_pin();
+
+ portal = bman_portal_setup(sc);
+ if (portal == NULL)
+ goto err;
+
+ memset(&bpp, 0, sizeof(bpp));
+ bpp.h_Bm = sc->sc_bh;
+ bpp.h_BmPortal = portal;
+ bpp.h_App = h_BufferPool;
+ bpp.numOfBuffers = allocBuffers;
+
+ bpp.bufferPoolInfo.h_BufferPool = h_BufferPool;
+ bpp.bufferPoolInfo.f_GetBuf = f_GetBuf;
+ bpp.bufferPoolInfo.f_PutBuf = f_PutBuf;
+ bpp.bufferPoolInfo.f_PhysToVirt = f_PhysToVirt;
+ bpp.bufferPoolInfo.f_VirtToPhys = f_VirtToPhys;
+ bpp.bufferPoolInfo.bufferSize = bufferSize;
+
+ pool = BM_POOL_Config(&bpp);
+ if (pool == NULL)
+ goto err;
+
+ /*
+ * Buffer context must be disabled on FreeBSD
+ * as it could cause memory corruption.
+ */
+ BM_POOL_ConfigBuffContextMode(pool, 0);
+
+ if (minBuffers != 0 || maxBuffers != 0) {
+ error = BM_POOL_ConfigStockpile(pool, maxBuffers, minBuffers);
+ if (error != E_OK)
+ goto err;
+ }
+
+ if (f_Depletion != NULL) {
+ thresholds[BM_POOL_DEP_THRESH_SW_ENTRY] = dep_sw_entry;
+ thresholds[BM_POOL_DEP_THRESH_SW_EXIT] = dep_sw_exit;
+ thresholds[BM_POOL_DEP_THRESH_HW_ENTRY] = dep_hw_entry;
+ thresholds[BM_POOL_DEP_THRESH_HW_EXIT] = dep_hw_exit;
+ error = BM_POOL_ConfigDepletion(pool, f_Depletion, thresholds);
+ if (error != E_OK)
+ goto err;
+ }
+
+ error = BM_POOL_Init(pool);
+ if (error != E_OK)
+ goto err;
+
+ *bpid = BM_POOL_GetId(pool);
+ sc->sc_bpool_cpu[*bpid] = PCPU_GET(cpuid);
+
+ sched_unpin();
+
+ return (pool);
+
+err:
+ if (pool != NULL)
+ BM_POOL_Free(pool);
+
+ sched_unpin();
+
+ return (NULL);
+}
+
+int
+bman_pool_destroy(t_Handle pool)
+{
+ struct bman_softc *sc;
+
+ sc = bman_sc;
+ thread_lock(curthread);
+ sched_bind(curthread, sc->sc_bpool_cpu[BM_POOL_GetId(pool)]);
+ thread_unlock(curthread);
+
+ BM_POOL_Free(pool);
+
+ thread_lock(curthread);
+ sched_unbind(curthread);
+ thread_unlock(curthread);
+
+ return (0);
+}
+
+int
+bman_pool_fill(t_Handle pool, uint16_t nbufs)
+{
+ struct bman_softc *sc;
+ t_Handle portal;
+ int error;
+
+ sc = bman_sc;
+ sched_pin();
+
+ portal = bman_portal_setup(sc);
+ if (portal == NULL) {
+ sched_unpin();
+ return (EIO);
+ }
+
+ error = BM_POOL_FillBufs(pool, portal, nbufs);
+
+ sched_unpin();
+
+ return ((error == E_OK) ? 0 : EIO);
+}
+
+void *
+bman_get_buffer(t_Handle pool)
+{
+ struct bman_softc *sc;
+ t_Handle portal;
+ void *buffer;
+
+ sc = bman_sc;
+ sched_pin();
+
+ portal = bman_portal_setup(sc);
+ if (portal == NULL) {
+ sched_unpin();
+ return (NULL);
+ }
+
+ buffer = BM_POOL_GetBuf(pool, portal);
+
+ sched_unpin();
+
+ return (buffer);
+}
+
+int
+bman_put_buffer(t_Handle pool, void *buffer)
+{
+ struct bman_softc *sc;
+ t_Handle portal;
+ int error;
+
+ sc = bman_sc;
+ sched_pin();
+
+ portal = bman_portal_setup(sc);
+ if (portal == NULL) {
+ sched_unpin();
+ return (EIO);
+ }
+
+ error = BM_POOL_PutBuf(pool, portal, buffer);
+
+ sched_unpin();
+
+ return ((error == E_OK) ? 0 : EIO);
+}
+
+uint32_t
+bman_count(t_Handle pool)
+{
+
+ return (BM_POOL_GetCounter(pool, e_BM_POOL_COUNTERS_CONTENT));
+}
diff --git a/sys/dev/dpaa/bman.h b/sys/dev/dpaa/bman.h
new file mode 100644
index 0000000..449b817
--- /dev/null
+++ b/sys/dev/dpaa/bman.h
@@ -0,0 +1,204 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BMAN_H
+#define _BMAN_H
+
+#include <machine/vmparam.h>
+
+#include <contrib/ncsw/inc/Peripherals/bm_ext.h>
+
+/*
+ * BMAN Configuration
+ */
+
+/* Maximum number of buffers in all BMAN pools */
+#define BMAN_MAX_BUFFERS 4096
+
+/*
+ * Portal definitions
+ */
+#define BMAN_CE_PA(base) (base)
+#define BMAN_CI_PA(base) ((base) + 0x100000)
+
+#define BMAN_PORTAL_CE_PA(base, n) \
+ (BMAN_CE_PA(base) + ((n) * BMAN_PORTAL_CE_SIZE))
+#define BMAN_PORTAL_CI_PA(base, n) \
+ (BMAN_CI_PA(base) + ((n) * BMAN_PORTAL_CI_SIZE))
+
+#define BMAN_CCSR_SIZE 0x1000
+
+struct bman_softc {
+ device_t sc_dev; /* device handle */
+ int sc_rrid; /* register rid */
+ struct resource *sc_rres; /* register resource */
+ int sc_irid; /* interrupt rid */
+ struct resource *sc_ires; /* interrupt resource */
+
+ bool sc_regs_mapped[MAXCPU]; /* register mapping status */
+
+ t_Handle sc_bh; /* BMAN handle */
+ t_Handle sc_bph[MAXCPU]; /* BMAN portal handles */
+ vm_paddr_t sc_bp_pa; /* BMAN portals PA */
+ unsigned int sc_bpool_cpu[BM_MAX_NUM_OF_POOLS];
+};
+
+/*
+ * External API
+ */
+
+/*
+ * @brief Function to create BMAN pool.
+ *
+ * @param bpid The pointer to variable where Buffer Pool ID will be
+ * stored.
+ *
+ * @param bufferSize The size of buffers in newly created pool.
+ *
+ * @param maxBuffers The maximum number of buffers in software stockpile.
+ * Set to 0 if software stockpile should not be created.
+ *
+ * @param minBuffers The minimum number of buffers in software stockpile.
+ * Set to 0 if software stockpile should not be created.
+ *
+ * @param allocBuffers The number of buffers to preallocate during pool
+ * creation.
+ *
+ * @param f_GetBuf The buffer allocating function. Called only by
+ * bman_pool_create() and bman_pool_fill().
+ *
+ * @param f_PutBuf The buffer freeing function. Called only by
+ * bman_pool_destroy().
+ *
+ * @param dep_sw_entry The software portal depletion entry threshold.
+ * Set to 0 if depletion should not be signaled on
+ * software portal.
+ *
+ * @param dep_sw_exit The software portal depletion exit threshold.
+ * Set to 0 if depletion should not be signaled on
+ * software portal.
+ *
+ * @param dep_hw_entry The hardware portal depletion entry threshold.
+ * Set to 0 if depletion should not be signaled on
+ * hardware portal.
+ *
+ * @param dep_hw_exit The hardware portal depletion exit threshold.
+ * Set to 0 if depletion should not be signaled on
+ * hardware portal.
+ *
+ * @param f_Depletion The software portal depletion notification function.
+ * Set to NULL if depletion notification is not used.
+ *
+ * @param h_BufferPool The user provided buffer pool context passed to
+ * f_GetBuf, f_PutBuf and f_Depletion functions.
+ *
+ * @param f_PhysToVirt The PA to VA translation function. Set to NULL if
+ * default one should be used.
+ *
+ * @param f_VirtToPhys The VA to PA translation function. Set to NULL if
+ * default one should be used.
+ *
+ * @returns Handle to newly created BMAN pool or NULL on error.
+ *
+ * @cautions If pool uses software stockpile, all accesses to given
+ * pool must be protected by lock. Even if only hardware
+ * portal depletion notification is used, the caller must
+ * provide valid @p f_Depletion function.
+ */
+t_Handle bman_pool_create(uint8_t *bpid, uint16_t bufferSize,
+ uint16_t maxBuffers, uint16_t minBuffers, uint16_t allocBuffers,
+ t_GetBufFunction *f_GetBuf, t_PutBufFunction *f_PutBuf,
+ uint32_t dep_sw_entry, uint32_t dep_sw_exit, uint32_t dep_hw_entry,
+ uint32_t dep_hw_exit, t_BmDepletionCallback *f_Depletion,
+ t_Handle h_BufferPool, t_PhysToVirt *f_PhysToVirt,
+ t_VirtToPhys *f_VirtToPhys);
+
+/*
+ * @brief Fill pool with buffers.
+ *
+ * The bman_pool_fill() function fills the BMAN pool with buffers. The buffers
+ * are allocated through f_GetBuf function (see bman_pool_create() description).
+ *
+ * @param pool The BMAN pool handle.
+ * @param nbufs The number of buffers to allocate. To maximize
+ * performance this value should be multiple of 8.
+ *
+ * @returns Zero on success or error code on failure.
+ */
+int bman_pool_fill(t_Handle pool, uint16_t nbufs);
+
+/*
+ * @brief Destroy pool.
+ *
+ * The bman_pool_destroy() function destroys the BMAN pool. Buffers for pool
+ * are free through f_PutBuf function (see bman_pool_create() description).
+ *
+ * @param pool The BMAN pool handle.
+ *
+ * @returns Zero on success or error code on failure.
+ */
+int bman_pool_destroy(t_Handle pool);
+
+/*
+ * @brief Get a buffer from BMAN pool.
+ *
+ * @param pool The BMAN pool handle.
+ *
+ * @returns Pointer to the buffer or NULL if pool is empty.
+ */
+void *bman_get_buffer(t_Handle pool);
+
+/*
+ * @brief Put a buffer to BMAN pool.
+ *
+ * @param pool The BMAN pool handle.
+ * @param buffer The pointer to buffer.
+ *
+ * @returns Zero on success or error code on failure.
+ */
+int bman_put_buffer(t_Handle pool, void *buffer);
+
+/*
+ * @brief Count free buffers in given pool.
+ *
+ * @param pool The BMAN pool handle.
+ *
+ * @returns Number of free buffers in pool.
+ */
+uint32_t bman_count(t_Handle pool);
+
+/*
+ * Bus i/f
+ */
+int bman_attach(device_t dev);
+int bman_detach(device_t dev);
+int bman_suspend(device_t dev);
+int bman_resume(device_t dev);
+int bman_shutdown(device_t dev);
+
+#endif /* BMAN_H */
diff --git a/sys/dev/dpaa/bman_fdt.c b/sys/dev/dpaa/bman_fdt.c
new file mode 100644
index 0000000..63f58ad
--- /dev/null
+++ b/sys/dev/dpaa/bman_fdt.c
@@ -0,0 +1,225 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_platform.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_subr.h>
+
+#include "bman.h"
+#include "portals.h"
+
+#define FBMAN_DEVSTR "Freescale Buffer Manager"
+
+static int bman_fdt_probe(device_t);
+
+static device_method_t bman_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bman_fdt_probe),
+ DEVMETHOD(device_attach, bman_attach),
+ DEVMETHOD(device_detach, bman_detach),
+
+ DEVMETHOD(device_suspend, bman_suspend),
+ DEVMETHOD(device_resume, bman_resume),
+ DEVMETHOD(device_shutdown, bman_shutdown),
+
+ { 0, 0 }
+};
+
+static driver_t bman_driver = {
+ "bman",
+ bman_methods,
+ sizeof(struct bman_softc),
+};
+
+static devclass_t bman_devclass;
+DRIVER_MODULE(bman, simplebus, bman_driver, bman_devclass, 0, 0);
+
+static int
+bman_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,bman"))
+ return (ENXIO);
+
+ device_set_desc(dev, FBMAN_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+/*
+ * BMAN Portals
+ */
+#define BMAN_PORT_DEVSTR "Freescale Buffer Manager - Portals"
+
+static device_probe_t bman_portals_fdt_probe;
+static device_attach_t bman_portals_fdt_attach;
+
+static device_method_t bm_portals_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bman_portals_fdt_probe),
+ DEVMETHOD(device_attach, bman_portals_fdt_attach),
+ DEVMETHOD(device_detach, bman_portals_detach),
+
+ { 0, 0 }
+};
+
+static driver_t bm_portals_driver = {
+ "bman-portals",
+ bm_portals_methods,
+ sizeof(struct dpaa_portals_softc),
+};
+
+static devclass_t bm_portals_devclass;
+DRIVER_MODULE(bman_portals, ofwbus, bm_portals_driver, bm_portals_devclass, 0, 0);
+
+static void
+get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep)
+{
+
+ *addrp = 2;
+ *sizep = 1;
+ OF_getencprop(node, "#address-cells", addrp, sizeof(*addrp));
+ OF_getencprop(node, "#size-cells", sizep, sizeof(*sizep));
+}
+
+static int
+bman_portals_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "bman-portals"))
+ return (ENXIO);
+
+ device_set_desc(dev, BMAN_PORT_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+bman_portals_fdt_attach(device_t dev)
+{
+ struct dpaa_portals_softc *sc;
+ struct resource_list_entry *rle;
+ phandle_t node, child, cpu_node;
+ vm_paddr_t portal_pa;
+ vm_size_t portal_size;
+ uint32_t addr, size;
+ ihandle_t cpu;
+ int cpu_num, cpus, intr_rid;
+ struct dpaa_portals_devinfo di;
+ struct ofw_bus_devinfo ofw_di;
+
+ cpus = 0;
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+
+ node = ofw_bus_get_node(dev);
+ get_addr_props(node, &addr, &size);
+
+ /* Find portals tied to CPUs */
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ if (!fdt_is_compatible(child, "fsl,bman-portal")) {
+ continue;
+ }
+ /* Checkout related cpu */
+ if (OF_getprop(child, "cpu-handle", (void *)&cpu,
+ sizeof(cpu)) <= 0) {
+ continue;
+ }
+ /* Acquire cpu number */
+ cpu_node = OF_instance_to_package(cpu);
+ if (OF_getencprop(cpu_node, "reg", &cpu_num, sizeof(cpu_num)) <= 0) {
+ device_printf(dev, "Could not retrieve CPU number.\n");
+ return (ENXIO);
+ }
+
+ cpus++;
+
+ if (cpus > MAXCPU)
+ break;
+
+ if (ofw_bus_gen_setup_devinfo(&ofw_di, child) != 0) {
+ device_printf(dev, "could not set up devinfo\n");
+ continue;
+ }
+
+ resource_list_init(&di.di_res);
+ if (ofw_bus_reg_to_rl(dev, child, addr, size, &di.di_res)) {
+ device_printf(dev, "%s: could not process 'reg' "
+ "property\n", ofw_di.obd_name);
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+ continue;
+ }
+ if (ofw_bus_intr_to_rl(dev, child, &di.di_res, &intr_rid)) {
+ device_printf(dev, "%s: could not process "
+ "'interrupts' property\n", ofw_di.obd_name);
+ resource_list_free(&di.di_res);
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+ continue;
+ }
+ di.di_intr_rid = intr_rid;
+
+ ofw_reg_to_paddr(child, 0, &portal_pa, &portal_size, NULL);
+ rle = resource_list_find(&di.di_res, SYS_RES_MEMORY, 0);
+
+ if (sc->sc_dp_pa == 0)
+ sc->sc_dp_pa = portal_pa - rle->start;
+
+ portal_size = rle->end + 1;
+ rle = resource_list_find(&di.di_res, SYS_RES_MEMORY, 1);
+ device_printf(dev, "portal size 1: %jx\n", (uintmax_t)portal_size);
+ device_printf(dev, "portal size 2: %jx\n", (uintmax_t)rle->end + 1);
+ portal_size = ulmax(rle->end + 1, portal_size);
+ sc->sc_dp_size = ulmax(sc->sc_dp_size, portal_size);
+ device_printf(dev, "winner: %jx\n", (uintmax_t)sc->sc_dp_size);
+
+ if (dpaa_portal_alloc_res(dev, &di, cpu_num))
+ goto err;
+ }
+ device_printf(dev, "portal start: %jx, size: %jx\n", (uintmax_t)sc->sc_dp_pa, (uintmax_t)sc->sc_dp_size);
+
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+
+ return (bman_portals_attach(dev));
+err:
+ resource_list_free(&di.di_res);
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+ bman_portals_detach(dev);
+ return (ENXIO);
+}
diff --git a/sys/dev/dpaa/bman_portals.c b/sys/dev/dpaa/bman_portals.c
new file mode 100644
index 0000000..ba9997f
--- /dev/null
+++ b/sys/dev/dpaa/bman_portals.c
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_platform.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/sched.h>
+
+#include <machine/bus.h>
+#include <machine/tlb.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <powerpc/mpc85xx/mpc85xx.h>
+
+#include "bman.h"
+#include "portals.h"
+
+t_Handle bman_portal_setup(struct bman_softc *);
+
+struct dpaa_portals_softc *bp_sc;
+
+int
+bman_portals_attach(device_t dev)
+{
+ struct dpaa_portals_softc *sc;
+
+ sc = bp_sc = device_get_softc(dev);
+
+ /* Map bman portal to physical address space */
+ if (law_enable(OCP85XX_TGTIF_BMAN, sc->sc_dp_pa, sc->sc_dp_size)) {
+ bman_portals_detach(dev);
+ return (ENXIO);
+ }
+ /* Set portal properties for XX_VirtToPhys() */
+ XX_PortalSetInfo(dev);
+
+ return (bus_generic_attach(dev));
+}
+
+int
+bman_portals_detach(device_t dev)
+{
+ struct dpaa_portals_softc *sc;
+ int i;
+
+ bp_sc = NULL;
+ sc = device_get_softc(dev);
+
+ for (i = 0; i < ARRAY_SIZE(sc->sc_dp); i++) {
+ if (sc->sc_dp[i].dp_ph != NULL) {
+ thread_lock(curthread);
+ sched_bind(curthread, i);
+ thread_unlock(curthread);
+
+ BM_PORTAL_Free(sc->sc_dp[i].dp_ph);
+
+ thread_lock(curthread);
+ sched_unbind(curthread);
+ thread_unlock(curthread);
+ }
+
+ if (sc->sc_dp[i].dp_ires != NULL) {
+ XX_DeallocIntr((int)sc->sc_dp[i].dp_ires);
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->sc_dp[i].dp_irid, sc->sc_dp[i].dp_ires);
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(sc->sc_rres); i++) {
+ if (sc->sc_rres[i] != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->sc_rrid[i],
+ sc->sc_rres[i]);
+ }
+
+ return (0);
+}
+
+t_Handle
+bman_portal_setup(struct bman_softc *bsc)
+{
+ struct dpaa_portals_softc *sc;
+ t_BmPortalParam bpp;
+ t_Handle portal;
+ unsigned int cpu, p;
+
+ /* Return NULL if we're not ready or while detach */
+ if (bp_sc == NULL)
+ return (NULL);
+
+ sc = bp_sc;
+
+ sched_pin();
+ portal = NULL;
+ cpu = PCPU_GET(cpuid);
+
+ /* Check if portal is ready */
+ while (atomic_cmpset_acq_32((uint32_t *)&sc->sc_dp[cpu].dp_ph,
+ 0, -1) == 0) {
+ p = atomic_load_acq_32((uint32_t *)&sc->sc_dp[cpu].dp_ph);
+
+ /* Return if portal is already initialized */
+ if (p != 0 && p != -1) {
+ sched_unpin();
+ return ((t_Handle)p);
+ }
+
+ /* Not inititialized and "owned" by another thread */
+ thread_lock(curthread);
+ mi_switch(SW_VOL, NULL);
+ thread_unlock(curthread);
+ }
+
+ /* Map portal registers */
+ dpaa_portal_map_registers(sc);
+
+ /* Configure and initialize portal */
+ bpp.ceBaseAddress = rman_get_bushandle(sc->sc_rres[0]);
+ bpp.ciBaseAddress = rman_get_bushandle(sc->sc_rres[1]);
+ bpp.h_Bm = bsc->sc_bh;
+ bpp.swPortalId = cpu;
+ bpp.irq = (int)sc->sc_dp[cpu].dp_ires;
+
+ portal = BM_PORTAL_Config(&bpp);
+ if (portal == NULL)
+ goto err;
+
+ if (BM_PORTAL_Init(portal) != E_OK)
+ goto err;
+
+ atomic_store_rel_32((uint32_t *)&sc->sc_dp[cpu].dp_ph,
+ (uint32_t)portal);
+
+ sched_unpin();
+
+ return (portal);
+
+err:
+ if (portal != NULL)
+ BM_PORTAL_Free(portal);
+
+ atomic_store_rel_32((uint32_t *)&sc->sc_dp[cpu].dp_ph, 0);
+ sched_unpin();
+
+ return (NULL);
+}
diff --git a/sys/dev/dpaa/dpaa.c b/sys/dev/dpaa/dpaa.c
new file mode 100644
index 0000000..95c04b4
--- /dev/null
+++ b/sys/dev/dpaa/dpaa.c
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ktr.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include "opt_platform.h"
+
+static MALLOC_DEFINE(M_DPAA, "dpaa", "dpaa devices information");
+
+static int dpaa_probe(device_t dev);
+static int dpaa_attach(device_t dev);
+
+static const struct ofw_bus_devinfo *dpaa_get_devinfo(device_t bus,
+ device_t child);
+
+struct dpaa_softc {
+
+};
+
+struct dpaa_devinfo {
+ struct ofw_bus_devinfo di_ofw;
+};
+
+static device_method_t dpaa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, dpaa_probe),
+ DEVMETHOD(device_attach, dpaa_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* OFW bus interface */
+ DEVMETHOD(ofw_bus_get_devinfo, dpaa_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
+ {0, 0}
+};
+
+static driver_t dpaa_driver = {
+ "dpaa",
+ dpaa_methods,
+ sizeof(struct dpaa_softc),
+};
+
+static devclass_t dpaa_devclass;
+DRIVER_MODULE_ORDERED(dpaa, ofwbus, dpaa_driver, dpaa_devclass, 0, 0,
+ SI_ORDER_ANY);
+
+static int
+dpaa_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,dpaa"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale Data Path Acceleration Architecture");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+dpaa_attach(device_t dev)
+{
+ device_t dev_child;
+ phandle_t dt_node, dt_child, enet_node;
+ struct dpaa_devinfo *di;
+ pcell_t cell_index;
+
+ cell_index = 0;
+ /*
+ * Walk dpaa and add direct subordinates as our children.
+ */
+ dt_node = ofw_bus_get_node(dev);
+ dt_child = OF_child(dt_node);
+
+ for (; dt_child != 0; dt_child = OF_peer(dt_child)) {
+
+ /* Check and process 'status' property. */
+ if (!(fdt_is_enabled(dt_child)))
+ continue;
+
+ di = (struct dpaa_devinfo *)malloc(sizeof(*di), M_DPAA,
+ M_WAITOK | M_ZERO);
+
+ if (ofw_bus_gen_setup_devinfo(&di->di_ofw, dt_child) != 0) {
+ free(di, M_DPAA);
+ device_printf(dev, "could not set up devinfo\n");
+ continue;
+ }
+
+ /*
+ * dTSEC number from SoC is equal to number get from
+ * dts file.
+ */
+ if (OF_getprop(dt_child, "fsl,fman-mac",
+ (void *)&enet_node, sizeof(enet_node)) == -1) {
+ device_printf(dev, "Could not get fsl,fman-mac "
+ "from dts\n");
+ continue;
+ }
+
+ if ((enet_node = OF_instance_to_package(enet_node)) == -1) {
+ device_printf(dev, "Could not get enet node\n");
+ continue;
+ }
+
+ if (OF_getprop(enet_node, "cell-index",
+ (void *)&cell_index, sizeof(cell_index)) == -1) {
+ device_printf(dev, "Could not get cell-index from enet "
+ "node\n");
+ continue;
+ }
+
+ /* Add newbus device for this FDT node */
+ dev_child = device_add_child(dev, "dtsec", (int)cell_index);
+ if (dev_child == NULL) {
+ device_printf(dev, "could not add child: %s\n",
+ di->di_ofw.obd_name);
+ ofw_bus_gen_destroy_devinfo(&di->di_ofw);
+ free(di, M_DPAA);
+ continue;
+ }
+
+#ifdef DEBUG
+ device_printf(dev, "added child: %s\n\n", di->di_ofw.obd_name);
+#endif
+
+ device_set_ivars(dev_child, di);
+ }
+
+ return (bus_generic_attach(dev));
+}
+
+static const struct ofw_bus_devinfo *
+dpaa_get_devinfo(device_t bus, device_t child)
+{
+ struct dpaa_devinfo *di;
+
+ di = device_get_ivars(child);
+ return (&di->di_ofw);
+}
diff --git a/sys/dev/dpaa/fman.c b/sys/dev/dpaa/fman.c
new file mode 100644
index 0000000..3e44db8
--- /dev/null
+++ b/sys/dev/dpaa/fman.c
@@ -0,0 +1,357 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "opt_platform.h"
+
+#include <contrib/ncsw/inc/Peripherals/fm_ext.h>
+#include <contrib/ncsw/inc/Peripherals/fm_muram_ext.h>
+#include <contrib/ncsw/inc/ncsw_ext.h>
+#include <contrib/ncsw/integrations/fman_ucode.h>
+
+#include "fman.h"
+
+
+/**
+ * @group FMan private defines.
+ * @{
+ */
+enum fman_irq_enum {
+ FMAN_IRQ_NUM = 0,
+ FMAN_ERR_IRQ_NUM = 1
+};
+
+enum fman_mu_ram_map {
+ FMAN_MURAM_OFF = 0x0,
+ FMAN_MURAM_SIZE = 0x28000
+};
+
+struct fman_config {
+ device_t fman_device;
+ uintptr_t mem_base_addr;
+ int irq_num;
+ int err_irq_num;
+ uint8_t fm_id;
+ t_FmExceptionsCallback *exception_callback;
+ t_FmBusErrorCallback *bus_error_callback;
+};
+
+/**
+ * @group FMan private methods/members.
+ * @{
+ */
+/**
+ * Frame Manager firmware.
+ * We use the same firmware for both P3041 and P2041 devices.
+ */
+const uint32_t fman_firmware[] = FMAN_UC_IMG;
+const uint32_t fman_firmware_size = sizeof(fman_firmware);
+static struct fman_softc *fm_sc = NULL;
+
+static t_Handle
+fman_init(struct fman_softc *sc, struct fman_config *cfg)
+{
+ t_FmParams fm_params;
+ t_Handle muram_handle, fm_handle;
+ t_Error error;
+ t_FmRevisionInfo revision_info;
+ uint16_t clock;
+ uint32_t tmp, mod;
+
+ /* MURAM configuration */
+ muram_handle = FM_MURAM_ConfigAndInit(cfg->mem_base_addr +
+ FMAN_MURAM_OFF, FMAN_MURAM_SIZE);
+ if (muram_handle == NULL) {
+ device_printf(cfg->fman_device, "couldn't init FM MURAM module"
+ "\n");
+ return (NULL);
+ }
+ sc->muram_handle = muram_handle;
+
+ /* Fill in FM configuration */
+ fm_params.fmId = cfg->fm_id;
+ /* XXX we support only one partition thus each fman has master id */
+ fm_params.guestId = NCSW_MASTER_ID;
+
+ fm_params.baseAddr = cfg->mem_base_addr;
+ fm_params.h_FmMuram = muram_handle;
+
+ /* Get FMan clock in Hz */
+ if ((tmp = fman_get_clock(sc)) == 0)
+ return (NULL);
+
+ /* Convert FMan clock to MHz */
+ clock = (uint16_t)(tmp / 1000000);
+ mod = tmp % 1000000;
+
+ if (mod >= 500000)
+ ++clock;
+
+ fm_params.fmClkFreq = clock;
+ fm_params.f_Exception = cfg->exception_callback;
+ fm_params.f_BusError = cfg->bus_error_callback;
+ fm_params.h_App = cfg->fman_device;
+ fm_params.irq = cfg->irq_num;
+ fm_params.errIrq = cfg->err_irq_num;
+
+ fm_params.firmware.size = fman_firmware_size;
+ fm_params.firmware.p_Code = (uint32_t*)fman_firmware;
+
+ fm_handle = FM_Config(&fm_params);
+ if (fm_handle == NULL) {
+ device_printf(cfg->fman_device, "couldn't configure FM "
+ "module\n");
+ goto err;
+ }
+
+ FM_ConfigResetOnInit(fm_handle, TRUE);
+
+ error = FM_Init(fm_handle);
+ if (error != E_OK) {
+ device_printf(cfg->fman_device, "couldn't init FM module\n");
+ goto err2;
+ }
+
+ error = FM_GetRevision(fm_handle, &revision_info);
+ if (error != E_OK) {
+ device_printf(cfg->fman_device, "couldn't get FM revision\n");
+ goto err2;
+ }
+
+ device_printf(cfg->fman_device, "Hardware version: %d.%d.\n",
+ revision_info.majorRev, revision_info.minorRev);
+
+ return (fm_handle);
+
+err2:
+ FM_Free(fm_handle);
+err:
+ FM_MURAM_Free(muram_handle);
+ return (NULL);
+}
+
+static void
+fman_exception_callback(t_Handle app_handle, e_FmExceptions exception)
+{
+ struct fman_softc *sc;
+
+ sc = app_handle;
+ device_printf(sc->dev, "FMan exception occurred.\n");
+}
+
+static void
+fman_error_callback(t_Handle app_handle, e_FmPortType port_type,
+ uint8_t port_id, uint64_t addr, uint8_t tnum, uint16_t liodn)
+{
+ struct fman_softc *sc;
+
+ sc = app_handle;
+ device_printf(sc->dev, "FMan error occurred.\n");
+}
+/** @} */
+
+
+/**
+ * @group FMan driver interface.
+ * @{
+ */
+
+int
+fman_get_handle(t_Handle *fmh)
+{
+
+ if (fm_sc == NULL)
+ return (ENOMEM);
+
+ *fmh = fm_sc->fm_handle;
+
+ return (0);
+}
+
+int
+fman_get_muram_handle(t_Handle *muramh)
+{
+
+ if (fm_sc == NULL)
+ return (ENOMEM);
+
+ *muramh = fm_sc->muram_handle;
+
+ return (0);
+}
+
+int
+fman_get_bushandle(vm_offset_t *fm_base)
+{
+
+ if (fm_sc == NULL)
+ return (ENOMEM);
+
+ *fm_base = rman_get_bushandle(fm_sc->mem_res);
+
+ return (0);
+}
+
+int
+fman_attach(device_t dev)
+{
+ struct fman_softc *sc;
+ struct fman_config cfg;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+ fm_sc = sc;
+
+ /* Check if MallocSmart allocator is ready */
+ if (XX_MallocSmartInit() != E_OK) {
+ device_printf(dev, "could not initialize smart allocator.\n");
+ return (ENXIO);
+ }
+
+ XX_TrackInit();
+
+ sc->mem_rid = 0;
+ sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
+ RF_ACTIVE);
+ if (!sc->mem_res) {
+ device_printf(dev, "could not allocate memory.\n");
+ return (ENXIO);
+ }
+
+ sc->irq_rid = 0;
+ sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
+ RF_ACTIVE);
+ if (!sc->irq_res) {
+ device_printf(dev, "could not allocate interrupt.\n");
+ goto err;
+ }
+
+ /*
+ * XXX: Fix FMan interrupt. This is workaround for the issue with
+ * interrupts directed to multiple CPUs by the interrupts subsystem.
+ * Workaround is to bind the interrupt to only one CPU0.
+ */
+ XX_FmanFixIntr(rman_get_start(sc->irq_res));
+
+ sc->err_irq_rid = 1;
+ sc->err_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->err_irq_rid, RF_ACTIVE | RF_SHAREABLE);
+ if (!sc->err_irq_res) {
+ device_printf(dev, "could not allocate error interrupt.\n");
+ goto err;
+ }
+
+ /* Set FMan configuration */
+ cfg.fman_device = dev;
+ cfg.fm_id = device_get_unit(dev);
+ cfg.mem_base_addr = rman_get_bushandle(sc->mem_res);
+ cfg.irq_num = (int)sc->irq_res;
+ cfg.err_irq_num = (int)sc->err_irq_res;
+ cfg.exception_callback = fman_exception_callback;
+ cfg.bus_error_callback = fman_error_callback;
+
+ sc->fm_handle = fman_init(sc, &cfg);
+ if (sc->fm_handle == NULL) {
+ device_printf(dev, "could not be configured\n");
+ return (ENXIO);
+ }
+
+ return (bus_generic_attach(dev));
+
+err:
+ fman_detach(dev);
+ return (ENXIO);
+}
+
+int
+fman_detach(device_t dev)
+{
+ struct fman_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->muram_handle) {
+ FM_MURAM_Free(sc->muram_handle);
+ }
+
+ if (sc->fm_handle) {
+ FM_Free(sc->fm_handle);
+ }
+
+ if (sc->mem_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
+ sc->mem_res);
+ }
+
+ if (sc->irq_res) {
+ bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
+ sc->irq_res);
+ }
+
+ if (sc->irq_res) {
+ bus_release_resource(dev, SYS_RES_IRQ, sc->err_irq_rid,
+ sc->err_irq_res);
+ }
+
+ return (0);
+}
+
+int
+fman_suspend(device_t dev)
+{
+
+ return (0);
+}
+
+int
+fman_resume(device_t dev)
+{
+
+ return (0);
+}
+
+int
+fman_shutdown(device_t dev)
+{
+
+ return (0);
+}
+
+/** @} */
diff --git a/sys/dev/dpaa/fman.h b/sys/dev/dpaa/fman.h
new file mode 100644
index 0000000..5a421e0
--- /dev/null
+++ b/sys/dev/dpaa/fman.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef FMAN_H_
+#define FMAN_H_
+
+/**
+ * FMan driver instance data.
+ */
+struct fman_softc {
+ device_t dev;
+ struct resource *mem_res;
+ struct resource *irq_res;
+ struct resource *err_irq_res;
+ int mem_rid;
+ int irq_rid;
+ int err_irq_rid;
+
+ t_Handle fm_handle;
+ t_Handle muram_handle;
+};
+
+
+/**
+ * @group QMan bus interface.
+ * @{
+ */
+int fman_attach(device_t dev);
+int fman_detach(device_t dev);
+int fman_suspend(device_t dev);
+int fman_resume(device_t dev);
+int fman_shutdown(device_t dev);
+int fman_read_ivar(device_t dev, device_t child, int index,
+ uintptr_t *result);
+/** @} */
+
+uint32_t fman_get_clock(struct fman_softc *sc);
+int fman_get_handle(t_Handle *fmh);
+int fman_get_muram_handle(t_Handle *muramh);
+int fman_get_bushandle(vm_offset_t *fm_base);
+
+#endif /* FMAN_H_ */
diff --git a/sys/dev/dpaa/fman_fdt.c b/sys/dev/dpaa/fman_fdt.c
new file mode 100644
index 0000000..89c9eca
--- /dev/null
+++ b/sys/dev/dpaa/fman_fdt.c
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <contrib/ncsw/inc/ncsw_ext.h>
+#include <contrib/ncsw/inc/enet_ext.h>
+
+#include "fman.h"
+
+#define FFMAN_DEVSTR "Freescale Frame Manager"
+
+static int fman_fdt_probe(device_t dev);
+
+static device_method_t fman_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fman_fdt_probe),
+ DEVMETHOD(device_attach, fman_attach),
+ DEVMETHOD(device_detach, fman_detach),
+
+ DEVMETHOD(device_shutdown, fman_shutdown),
+ DEVMETHOD(device_suspend, fman_suspend),
+ DEVMETHOD(device_resume, fman_resume),
+
+ { 0, 0 }
+};
+
+static driver_t fman_driver = {
+ "fman",
+ fman_methods,
+ sizeof(struct fman_softc),
+};
+
+static devclass_t fman_devclass;
+EARLY_DRIVER_MODULE(fman, simplebus, fman_driver, fman_devclass, 0, 0,
+ BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
+
+
+static int
+fman_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,fman"))
+ return (ENXIO);
+
+ device_set_desc(dev, FFMAN_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+uint32_t
+fman_get_clock(struct fman_softc *sc)
+{
+ device_t dev;
+ phandle_t node;
+ pcell_t fman_clock;
+
+ dev = sc->dev;
+ node = ofw_bus_get_node(dev);
+
+ if ((OF_getprop(node, "clock-frequency", &fman_clock,
+ sizeof(fman_clock)) <= 0) || (fman_clock == 0)) {
+ device_printf(dev, "could not acquire correct frequency "
+ "from DTS\n");
+
+ return (0);
+ }
+
+ return ((uint32_t)fman_clock);
+}
+
diff --git a/sys/dev/dpaa/if_dtsec.c b/sys/dev/dpaa/if_dtsec.c
new file mode 100644
index 0000000..249d605
--- /dev/null
+++ b/sys/dev/dpaa/if_dtsec.c
@@ -0,0 +1,879 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/sockio.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_arp.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include "miibus_if.h"
+
+#include <contrib/ncsw/inc/Peripherals/fm_mac_ext.h>
+#include <contrib/ncsw/inc/Peripherals/fm_port_ext.h>
+#include <contrib/ncsw/inc/xx_ext.h>
+
+#include "fman.h"
+#include "if_dtsec.h"
+#include "if_dtsec_im.h"
+#include "if_dtsec_rm.h"
+
+
+/**
+ * @group dTSEC private defines.
+ * @{
+ */
+/**
+ * dTSEC FMan MAC exceptions info struct.
+ */
+struct dtsec_fm_mac_ex_str {
+ const int num;
+ const char *str;
+};
+
+/* XXX: Handle to FM_MAC instance of dTSEC0 */
+/* From QorIQ Data Path Acceleration Architecture Reference Manual, Rev 2, page
+ * 3-37, "The MII management hardware is shared by all dTSECs... only through
+ * the MIIM registers of dTSEC1 can external PHY's be accessed and configured."
+ */
+static t_Handle dtsec_mdio_mac_handle;
+/** @} */
+
+
+/**
+ * @group FMan MAC routines.
+ * @{
+ */
+#define DTSEC_MAC_EXCEPTIONS_END (-1)
+
+/**
+ * FMan MAC exceptions.
+ */
+static const struct dtsec_fm_mac_ex_str dtsec_fm_mac_exceptions[] = {
+ { e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO, "MDIO scan event" },
+ { e_FM_MAC_EX_10G_MDIO_CMD_CMPL, "MDIO command completion" },
+ { e_FM_MAC_EX_10G_REM_FAULT, "Remote fault" },
+ { e_FM_MAC_EX_10G_LOC_FAULT, "Local fault" },
+ { e_FM_MAC_EX_10G_1TX_ECC_ER, "Transmit frame ECC error" },
+ { e_FM_MAC_EX_10G_TX_FIFO_UNFL, "Transmit FIFO underflow" },
+ { e_FM_MAC_EX_10G_TX_FIFO_OVFL, "Receive FIFO overflow" },
+ { e_FM_MAC_EX_10G_TX_ER, "Transmit frame error" },
+ { e_FM_MAC_EX_10G_RX_FIFO_OVFL, "Receive FIFO overflow" },
+ { e_FM_MAC_EX_10G_RX_ECC_ER, "Receive frame ECC error" },
+ { e_FM_MAC_EX_10G_RX_JAB_FRM, "Receive jabber frame" },
+ { e_FM_MAC_EX_10G_RX_OVRSZ_FRM, "Receive oversized frame" },
+ { e_FM_MAC_EX_10G_RX_RUNT_FRM, "Receive runt frame" },
+ { e_FM_MAC_EX_10G_RX_FRAG_FRM, "Receive fragment frame" },
+ { e_FM_MAC_EX_10G_RX_LEN_ER, "Receive payload length error" },
+ { e_FM_MAC_EX_10G_RX_CRC_ER, "Receive CRC error" },
+ { e_FM_MAC_EX_10G_RX_ALIGN_ER, "Receive alignment error" },
+ { e_FM_MAC_EX_1G_BAB_RX, "Babbling receive error" },
+ { e_FM_MAC_EX_1G_RX_CTL, "Receive control (pause frame) interrupt" },
+ { e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET, "Graceful transmit stop "
+ "complete" },
+ { e_FM_MAC_EX_1G_BAB_TX, "Babbling transmit error" },
+ { e_FM_MAC_EX_1G_TX_CTL, "Transmit control (pause frame) interrupt" },
+ { e_FM_MAC_EX_1G_TX_ERR, "Transmit error" },
+ { e_FM_MAC_EX_1G_LATE_COL, "Late collision" },
+ { e_FM_MAC_EX_1G_COL_RET_LMT, "Collision retry limit" },
+ { e_FM_MAC_EX_1G_TX_FIFO_UNDRN, "Transmit FIFO underrun" },
+ { e_FM_MAC_EX_1G_MAG_PCKT, "Magic Packet detected when dTSEC is in "
+ "Magic Packet detection mode" },
+ { e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET, "MII management read completion" },
+ { e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET, "MII management write completion" },
+ { e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET, "Graceful receive stop "
+ "complete" },
+ { e_FM_MAC_EX_1G_TX_DATA_ERR, "Internal data error on transmit" },
+ { e_FM_MAC_EX_1G_RX_DATA_ERR, "Internal data error on receive" },
+ { e_FM_MAC_EX_1G_1588_TS_RX_ERR, "Time-Stamp Receive Error" },
+ { e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, "MIB counter overflow" },
+ { DTSEC_MAC_EXCEPTIONS_END, "" }
+};
+
+static const char *
+dtsec_fm_mac_ex_to_str(e_FmMacExceptions exception)
+{
+ int i;
+
+ for (i = 0; dtsec_fm_mac_exceptions[i].num != exception &&
+ dtsec_fm_mac_exceptions[i].num != DTSEC_MAC_EXCEPTIONS_END; ++i)
+ ;
+
+ if (dtsec_fm_mac_exceptions[i].num == DTSEC_MAC_EXCEPTIONS_END)
+ return ("<Unknown Exception>");
+
+ return (dtsec_fm_mac_exceptions[i].str);
+}
+
+static void
+dtsec_fm_mac_mdio_event_callback(t_Handle h_App,
+ e_FmMacExceptions exception)
+{
+ struct dtsec_softc *sc;
+
+ sc = h_App;
+ device_printf(sc->sc_dev, "MDIO event %i: %s.\n", exception,
+ dtsec_fm_mac_ex_to_str(exception));
+}
+
+static void
+dtsec_fm_mac_exception_callback(t_Handle app, e_FmMacExceptions exception)
+{
+ struct dtsec_softc *sc;
+
+ sc = app;
+ device_printf(sc->sc_dev, "MAC exception %i: %s.\n", exception,
+ dtsec_fm_mac_ex_to_str(exception));
+}
+
+static void
+dtsec_fm_mac_free(struct dtsec_softc *sc)
+{
+ if (sc->sc_mach == NULL)
+ return;
+
+ FM_MAC_Disable(sc->sc_mach, e_COMM_MODE_RX_AND_TX);
+ FM_MAC_Free(sc->sc_mach);
+ sc->sc_mach = NULL;
+}
+
+static int
+dtsec_fm_mac_init(struct dtsec_softc *sc, uint8_t *mac)
+{
+ t_FmMacParams params;
+ t_Error error;
+
+ memset(&params, 0, sizeof(params));
+ memcpy(&params.addr, mac, sizeof(params.addr));
+
+ params.baseAddr = sc->sc_fm_base + sc->sc_mac_mem_offset;
+ params.enetMode = sc->sc_mac_enet_mode;
+ params.macId = sc->sc_eth_id;
+ params.mdioIrq = sc->sc_mac_mdio_irq;
+ params.f_Event = dtsec_fm_mac_mdio_event_callback;
+ params.f_Exception = dtsec_fm_mac_exception_callback;
+ params.h_App = sc;
+ params.h_Fm = sc->sc_fmh;
+
+ sc->sc_mach = FM_MAC_Config(&params);
+ if (sc->sc_hidden)
+ return (0);
+ if (sc->sc_mach == NULL) {
+ device_printf(sc->sc_dev, "couldn't configure FM_MAC module.\n"
+ );
+ return (ENXIO);
+ }
+
+ error = FM_MAC_ConfigResetOnInit(sc->sc_mach, TRUE);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't enable reset on init "
+ "feature.\n");
+ dtsec_fm_mac_free(sc);
+ return (ENXIO);
+ }
+
+ /* Do not inform about pause frames */
+ error = FM_MAC_ConfigException(sc->sc_mach, e_FM_MAC_EX_1G_RX_CTL,
+ FALSE);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't disable pause frames "
+ "exception.\n");
+ dtsec_fm_mac_free(sc);
+ return (ENXIO);
+ }
+
+ error = FM_MAC_Init(sc->sc_mach);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't initialize FM_MAC module."
+ "\n");
+ dtsec_fm_mac_free(sc);
+ return (ENXIO);
+ }
+
+ return (0);
+}
+/** @} */
+
+
+/**
+ * @group FMan PORT routines.
+ * @{
+ */
+static const char *
+dtsec_fm_port_ex_to_str(e_FmPortExceptions exception)
+{
+
+ switch (exception) {
+ case e_FM_PORT_EXCEPTION_IM_BUSY:
+ return ("IM: RX busy");
+ default:
+ return ("<Unknown Exception>");
+ }
+}
+
+void
+dtsec_fm_port_rx_exception_callback(t_Handle app,
+ e_FmPortExceptions exception)
+{
+ struct dtsec_softc *sc;
+
+ sc = app;
+ device_printf(sc->sc_dev, "RX exception: %i: %s.\n", exception,
+ dtsec_fm_port_ex_to_str(exception));
+}
+
+void
+dtsec_fm_port_tx_exception_callback(t_Handle app,
+ e_FmPortExceptions exception)
+{
+ struct dtsec_softc *sc;
+
+ sc = app;
+ device_printf(sc->sc_dev, "TX exception: %i: %s.\n", exception,
+ dtsec_fm_port_ex_to_str(exception));
+}
+
+e_FmPortType
+dtsec_fm_port_rx_type(enum eth_dev_type type)
+{
+ switch (type) {
+ case ETH_DTSEC:
+ return (e_FM_PORT_TYPE_RX);
+ case ETH_10GSEC:
+ return (e_FM_PORT_TYPE_RX_10G);
+ default:
+ return (e_FM_PORT_TYPE_DUMMY);
+ }
+}
+
+e_FmPortType
+dtsec_fm_port_tx_type(enum eth_dev_type type)
+{
+
+ switch (type) {
+ case ETH_DTSEC:
+ return (e_FM_PORT_TYPE_TX);
+ case ETH_10GSEC:
+ return (e_FM_PORT_TYPE_TX_10G);
+ default:
+ return (e_FM_PORT_TYPE_DUMMY);
+ }
+}
+
+static void
+dtsec_fm_port_free_both(struct dtsec_softc *sc)
+{
+ if (sc->sc_rxph) {
+ FM_PORT_Free(sc->sc_rxph);
+ sc->sc_rxph = NULL;
+ }
+
+ if (sc->sc_txph) {
+ FM_PORT_Free(sc->sc_txph);
+ sc->sc_txph = NULL;
+ }
+}
+/** @} */
+
+
+/**
+ * @group IFnet routines.
+ * @{
+ */
+static int
+dtsec_if_enable_locked(struct dtsec_softc *sc)
+{
+ int error;
+
+ DTSEC_LOCK_ASSERT(sc);
+
+ error = FM_MAC_Enable(sc->sc_mach, e_COMM_MODE_RX_AND_TX);
+ if (error != E_OK)
+ return (EIO);
+
+ error = FM_PORT_Enable(sc->sc_rxph);
+ if (error != E_OK)
+ return (EIO);
+
+ error = FM_PORT_Enable(sc->sc_txph);
+ if (error != E_OK)
+ return (EIO);
+
+ sc->sc_ifnet->if_drv_flags |= IFF_DRV_RUNNING;
+
+ /* Refresh link state */
+ dtsec_miibus_statchg(sc->sc_dev);
+
+ return (0);
+}
+
+static int
+dtsec_if_disable_locked(struct dtsec_softc *sc)
+{
+ int error;
+
+ DTSEC_LOCK_ASSERT(sc);
+
+ error = FM_MAC_Disable(sc->sc_mach, e_COMM_MODE_RX_AND_TX);
+ if (error != E_OK)
+ return (EIO);
+
+ error = FM_PORT_Disable(sc->sc_rxph);
+ if (error != E_OK)
+ return (EIO);
+
+ error = FM_PORT_Disable(sc->sc_txph);
+ if (error != E_OK)
+ return (EIO);
+
+ sc->sc_ifnet->if_drv_flags &= ~IFF_DRV_RUNNING;
+
+ return (0);
+}
+
+static int
+dtsec_if_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
+{
+ struct dtsec_softc *sc;
+ struct ifreq *ifr;
+ int error;
+
+ sc = ifp->if_softc;
+ ifr = (struct ifreq *)data;
+ error = 0;
+
+ /* Basic functionality to achieve media status reports */
+ switch (command) {
+ case SIOCSIFFLAGS:
+ DTSEC_LOCK(sc);
+
+ if (sc->sc_ifnet->if_flags & IFF_UP)
+ error = dtsec_if_enable_locked(sc);
+ else
+ error = dtsec_if_disable_locked(sc);
+
+ DTSEC_UNLOCK(sc);
+ break;
+
+ case SIOCGIFMEDIA:
+ case SIOCSIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media,
+ command);
+ break;
+
+ default:
+ error = ether_ioctl(ifp, command, data);
+ }
+
+ return (error);
+}
+
+static void
+dtsec_if_tick(void *arg)
+{
+ struct dtsec_softc *sc;
+
+ sc = arg;
+
+ /* TODO */
+ DTSEC_LOCK(sc);
+
+ mii_tick(sc->sc_mii);
+ callout_reset(&sc->sc_tick_callout, hz, dtsec_if_tick, sc);
+
+ DTSEC_UNLOCK(sc);
+}
+
+static void
+dtsec_if_deinit_locked(struct dtsec_softc *sc)
+{
+
+ DTSEC_LOCK_ASSERT(sc);
+
+ DTSEC_UNLOCK(sc);
+ callout_drain(&sc->sc_tick_callout);
+ DTSEC_LOCK(sc);
+}
+
+static void
+dtsec_if_init_locked(struct dtsec_softc *sc)
+{
+ int error;
+
+ DTSEC_LOCK_ASSERT(sc);
+
+ /* Set MAC address */
+ error = FM_MAC_ModifyMacAddr(sc->sc_mach,
+ (t_EnetAddr *)IF_LLADDR(sc->sc_ifnet));
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't set MAC address.\n");
+ goto err;
+ }
+
+ /* Start MII polling */
+ if (sc->sc_mii)
+ callout_reset(&sc->sc_tick_callout, hz, dtsec_if_tick, sc);
+
+ if (sc->sc_ifnet->if_flags & IFF_UP) {
+ error = dtsec_if_enable_locked(sc);
+ if (error != 0)
+ goto err;
+ } else {
+ error = dtsec_if_disable_locked(sc);
+ if (error != 0)
+ goto err;
+ }
+
+ return;
+
+err:
+ dtsec_if_deinit_locked(sc);
+ device_printf(sc->sc_dev, "initialization error.\n");
+ return;
+}
+
+static void
+dtsec_if_init(void *data)
+{
+ struct dtsec_softc *sc;
+
+ sc = data;
+
+ DTSEC_LOCK(sc);
+ dtsec_if_init_locked(sc);
+ DTSEC_UNLOCK(sc);
+}
+
+static void
+dtsec_if_start(struct ifnet *ifp)
+{
+ struct dtsec_softc *sc;
+
+ sc = ifp->if_softc;
+ DTSEC_LOCK(sc);
+ sc->sc_start_locked(sc);
+ DTSEC_UNLOCK(sc);
+}
+
+static void
+dtsec_if_watchdog(struct ifnet *ifp)
+{
+ /* TODO */
+}
+/** @} */
+
+
+/**
+ * @group IFmedia routines.
+ * @{
+ */
+static int
+dtsec_ifmedia_upd(struct ifnet *ifp)
+{
+ struct dtsec_softc *sc = ifp->if_softc;
+
+ DTSEC_LOCK(sc);
+ mii_mediachg(sc->sc_mii);
+ DTSEC_UNLOCK(sc);
+
+ return (0);
+}
+
+static void
+dtsec_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct dtsec_softc *sc = ifp->if_softc;
+
+ DTSEC_LOCK(sc);
+
+ mii_pollstat(sc->sc_mii);
+
+ ifmr->ifm_active = sc->sc_mii->mii_media_active;
+ ifmr->ifm_status = sc->sc_mii->mii_media_status;
+
+ DTSEC_UNLOCK(sc);
+}
+/** @} */
+
+
+/**
+ * @group dTSEC bus interface.
+ * @{
+ */
+static void
+dtsec_configure_mode(struct dtsec_softc *sc)
+{
+ char tunable[64];
+
+ snprintf(tunable, sizeof(tunable), "%s.independent_mode",
+ device_get_nameunit(sc->sc_dev));
+
+ sc->sc_mode = DTSEC_MODE_REGULAR;
+ TUNABLE_INT_FETCH(tunable, &sc->sc_mode);
+
+ if (sc->sc_mode == DTSEC_MODE_REGULAR) {
+ sc->sc_port_rx_init = dtsec_rm_fm_port_rx_init;
+ sc->sc_port_tx_init = dtsec_rm_fm_port_tx_init;
+ sc->sc_start_locked = dtsec_rm_if_start_locked;
+ } else {
+ sc->sc_port_rx_init = dtsec_im_fm_port_rx_init;
+ sc->sc_port_tx_init = dtsec_im_fm_port_tx_init;
+ sc->sc_start_locked = dtsec_im_if_start_locked;
+ }
+
+ device_printf(sc->sc_dev, "Configured for %s mode.\n",
+ (sc->sc_mode == DTSEC_MODE_REGULAR) ? "regular" : "independent");
+}
+
+int
+dtsec_attach(device_t dev)
+{
+ struct dtsec_softc *sc;
+ int error;
+ struct ifnet *ifp;
+
+ sc = device_get_softc(dev);
+
+ sc->sc_dev = dev;
+ sc->sc_mac_mdio_irq = NO_IRQ;
+ sc->sc_eth_id = device_get_unit(dev);
+
+
+ /* Check if MallocSmart allocator is ready */
+ if (XX_MallocSmartInit() != E_OK)
+ return (ENXIO);
+
+ XX_TrackInit();
+
+ /* Init locks */
+ mtx_init(&sc->sc_lock, device_get_nameunit(dev),
+ "DTSEC Global Lock", MTX_DEF);
+
+ mtx_init(&sc->sc_mii_lock, device_get_nameunit(dev),
+ "DTSEC MII Lock", MTX_DEF);
+
+ /* Init callouts */
+ callout_init(&sc->sc_tick_callout, CALLOUT_MPSAFE);
+
+ /* Read configuraton */
+ if ((error = fman_get_handle(&sc->sc_fmh)) != 0)
+ return (error);
+
+ if ((error = fman_get_muram_handle(&sc->sc_muramh)) != 0)
+ return (error);
+
+ if ((error = fman_get_bushandle(&sc->sc_fm_base)) != 0)
+ return (error);
+
+ /* Configure working mode */
+ dtsec_configure_mode(sc);
+
+ /* If we are working in regular mode configure BMAN and QMAN */
+ if (sc->sc_mode == DTSEC_MODE_REGULAR) {
+ /* Create RX buffer pool */
+ error = dtsec_rm_pool_rx_init(sc);
+ if (error != 0)
+ return (EIO);
+
+ /* Create RX frame queue range */
+ error = dtsec_rm_fqr_rx_init(sc);
+ if (error != 0)
+ return (EIO);
+
+ /* Create frame info pool */
+ error = dtsec_rm_fi_pool_init(sc);
+ if (error != 0)
+ return (EIO);
+
+ /* Create TX frame queue range */
+ error = dtsec_rm_fqr_tx_init(sc);
+ if (error != 0)
+ return (EIO);
+ }
+
+ /* Init FMan MAC module. */
+ error = dtsec_fm_mac_init(sc, sc->sc_mac_addr);
+ if (error != 0) {
+ dtsec_detach(dev);
+ return (ENXIO);
+ }
+
+ /*
+ * XXX: All phys are connected to MDIO interface of the first dTSEC
+ * device (dTSEC0). We have to save handle to the FM_MAC instance of
+ * dTSEC0, which is used later during phy's registers accesses. Another
+ * option would be adding new property to DTS pointing to correct dTSEC
+ * instance, of which FM_MAC handle has to be used for phy's registers
+ * accesses. We did not want to add new properties to DTS, thus this
+ * quite ugly hack.
+ */
+ if (sc->sc_eth_id == 0)
+ dtsec_mdio_mac_handle = sc->sc_mach;
+ if (sc->sc_hidden)
+ return (0);
+
+ /* Init FMan TX port */
+ error = sc->sc_port_tx_init(sc, device_get_unit(sc->sc_dev));
+ if (error != 0) {
+ dtsec_detach(dev);
+ return (ENXIO);
+ }
+
+ /* Init FMan RX port */
+ error = sc->sc_port_rx_init(sc, device_get_unit(sc->sc_dev));
+ if (error != 0) {
+ dtsec_detach(dev);
+ return (ENXIO);
+ }
+
+ /* Create network interface for upper layers */
+ ifp = sc->sc_ifnet = if_alloc(IFT_ETHER);
+ if (ifp == NULL) {
+ device_printf(sc->sc_dev, "if_alloc() failed.\n");
+ dtsec_detach(dev);
+ return (ENOMEM);
+ }
+
+ ifp->if_softc = sc;
+ ifp->if_mtu = ETHERMTU; /* TODO: Configure */
+ ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST;
+ ifp->if_init = dtsec_if_init;
+ ifp->if_start = dtsec_if_start;
+ ifp->if_ioctl = dtsec_if_ioctl;
+ ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
+
+ if (sc->sc_phy_addr >= 0)
+ if_initname(ifp, device_get_name(sc->sc_dev),
+ device_get_unit(sc->sc_dev));
+ else
+ if_initname(ifp, "dtsec_phy", device_get_unit(sc->sc_dev));
+
+ /* TODO */
+#if 0
+ IFQ_SET_MAXLEN(&ifp->if_snd, TSEC_TX_NUM_DESC - 1);
+ ifp->if_snd.ifq_drv_maxlen = TSEC_TX_NUM_DESC - 1;
+ IFQ_SET_READY(&ifp->if_snd);
+#endif
+ ifp->if_capabilities = 0; /* TODO: Check */
+ ifp->if_capenable = ifp->if_capabilities;
+
+ /* Attach PHY(s) */
+ error = mii_attach(sc->sc_dev, &sc->sc_mii_dev, ifp, dtsec_ifmedia_upd,
+ dtsec_ifmedia_sts, BMSR_DEFCAPMASK, sc->sc_phy_addr,
+ MII_OFFSET_ANY, 0);
+ if (error) {
+ device_printf(sc->sc_dev, "attaching PHYs failed: %d\n", error);
+ dtsec_detach(sc->sc_dev);
+ return (error);
+ }
+ sc->sc_mii = device_get_softc(sc->sc_mii_dev);
+
+ /* Attach to stack */
+ ether_ifattach(ifp, sc->sc_mac_addr);
+
+ return (0);
+}
+
+int
+dtsec_detach(device_t dev)
+{
+ struct dtsec_softc *sc;
+ if_t ifp;
+
+ sc = device_get_softc(dev);
+ ifp = sc->sc_ifnet;
+
+ if (device_is_attached(dev)) {
+ ether_ifdetach(ifp);
+ /* Shutdown interface */
+ DTSEC_LOCK(sc);
+ dtsec_if_deinit_locked(sc);
+ DTSEC_UNLOCK(sc);
+ }
+
+ if (sc->sc_ifnet) {
+ if_free(sc->sc_ifnet);
+ sc->sc_ifnet = NULL;
+ }
+
+ if (sc->sc_mode == DTSEC_MODE_REGULAR) {
+ /* Free RX/TX FQRs */
+ dtsec_rm_fqr_rx_free(sc);
+ dtsec_rm_fqr_tx_free(sc);
+
+ /* Free frame info pool */
+ dtsec_rm_fi_pool_free(sc);
+
+ /* Free RX buffer pool */
+ dtsec_rm_pool_rx_free(sc);
+ }
+
+ dtsec_fm_mac_free(sc);
+ dtsec_fm_port_free_both(sc);
+
+ /* Destroy lock */
+ mtx_destroy(&sc->sc_lock);
+
+ return (0);
+}
+
+int
+dtsec_suspend(device_t dev)
+{
+
+ return (0);
+}
+
+int
+dtsec_resume(device_t dev)
+{
+
+ return (0);
+}
+
+int
+dtsec_shutdown(device_t dev)
+{
+
+ return (0);
+}
+/** @} */
+
+
+/**
+ * @group MII bus interface.
+ * @{
+ */
+int
+dtsec_miibus_readreg(device_t dev, int phy, int reg)
+{
+ struct dtsec_softc *sc;
+ uint16_t data;
+ t_Error error;
+
+ sc = device_get_softc(dev);
+
+ if (phy != sc->sc_phy_addr)
+ return (0xFFFF);
+
+ DTSEC_MII_LOCK(sc);
+ error = FM_MAC_MII_ReadPhyReg(dtsec_mdio_mac_handle, phy, reg, &data);
+ DTSEC_MII_UNLOCK(sc);
+ if (error != E_OK) {
+ device_printf(dev, "Error while reading from PHY (NetCommSw "
+ "error: %d)\n", error);
+ return (0xFFFF);
+ }
+
+ return ((int)data);
+}
+
+int
+dtsec_miibus_writereg(device_t dev, int phy, int reg, int value)
+{
+ struct dtsec_softc *sc;
+ t_Error error;
+
+ sc = device_get_softc(dev);
+
+ if (phy != sc->sc_phy_addr)
+ return (EINVAL);
+
+ DTSEC_MII_LOCK(sc);
+ error = FM_MAC_MII_WritePhyReg(dtsec_mdio_mac_handle, phy, reg, value);
+ DTSEC_MII_UNLOCK(sc);
+ if (error != E_OK) {
+ device_printf(dev, "Error while writing to PHY (NetCommSw "
+ "error: %d).\n", error);
+ return (EIO);
+ }
+
+ return (0);
+}
+
+void
+dtsec_miibus_statchg(device_t dev)
+{
+ struct dtsec_softc *sc;
+ e_EnetSpeed speed;
+ bool duplex;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ DTSEC_LOCK_ASSERT(sc);
+
+ duplex = ((sc->sc_mii->mii_media_active & IFM_GMASK) == IFM_FDX);
+
+ switch (IFM_SUBTYPE(sc->sc_mii->mii_media_active)) {
+ case IFM_1000_T:
+ case IFM_1000_SX:
+ speed = e_ENET_SPEED_1000;
+ break;
+
+ case IFM_100_TX:
+ speed = e_ENET_SPEED_100;
+ break;
+
+ case IFM_10_T:
+ speed = e_ENET_SPEED_10;
+ break;
+
+ default:
+ speed = e_ENET_SPEED_10;
+ }
+
+ error = FM_MAC_AdjustLink(sc->sc_mach, speed, duplex);
+ if (error != E_OK)
+ device_printf(sc->sc_dev, "error while adjusting MAC speed.\n");
+}
+/** @} */
diff --git a/sys/dev/dpaa/if_dtsec.h b/sys/dev/dpaa/if_dtsec.h
new file mode 100644
index 0000000..2e2e28f
--- /dev/null
+++ b/sys/dev/dpaa/if_dtsec.h
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef IF_DTSEC_H_
+#define IF_DTSEC_H_
+
+/**
+ * @group dTSEC common API.
+ * @{
+ */
+#define DTSEC_MODE_REGULAR 0
+#define DTSEC_MODE_INDEPENDENT 1
+
+#define DTSEC_LOCK(sc) mtx_lock(&(sc)->sc_lock)
+#define DTSEC_UNLOCK(sc) mtx_unlock(&(sc)->sc_lock)
+#define DTSEC_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_lock, MA_OWNED)
+#define DTSEC_MII_LOCK(sc) mtx_lock(&(sc)->sc_mii_lock)
+#define DTSEC_MII_UNLOCK(sc) mtx_unlock(&(sc)->sc_mii_lock)
+
+enum eth_dev_type {
+ ETH_DTSEC = 0x1,
+ ETH_10GSEC = 0x2
+};
+
+struct dtsec_softc {
+ /* XXX MII bus requires that struct ifnet is first!!! */
+ struct ifnet *sc_ifnet;
+
+ device_t sc_dev;
+ struct mtx sc_lock;
+ int sc_mode;
+
+ /* Methods */
+ int (*sc_port_rx_init)
+ (struct dtsec_softc *sc, int unit);
+ int (*sc_port_tx_init)
+ (struct dtsec_softc *sc, int unit);
+ void (*sc_start_locked)
+ (struct dtsec_softc *sc);
+
+ /* dTSEC data */
+ enum eth_dev_type sc_eth_dev_type;
+ uint8_t sc_eth_id;
+ uintptr_t sc_mac_mem_offset;
+ e_EnetMode sc_mac_enet_mode;
+ int sc_mac_mdio_irq;
+ uint8_t sc_mac_addr[6];
+ int sc_port_rx_hw_id;
+ int sc_port_tx_hw_id;
+ uint32_t sc_port_tx_qman_chan;
+ int sc_phy_addr;
+ bool sc_hidden;
+
+ /* Params from fman_bus driver */
+ vm_offset_t sc_fm_base;
+ t_Handle sc_fmh;
+ t_Handle sc_muramh;
+
+ t_Handle sc_mach;
+ t_Handle sc_rxph;
+ t_Handle sc_txph;
+
+ /* MII data */
+ struct mii_data *sc_mii;
+ device_t sc_mii_dev;
+ struct mtx sc_mii_lock;
+
+ struct callout sc_tick_callout;
+
+ /* RX Pool */
+ t_Handle sc_rx_pool;
+ uint8_t sc_rx_bpid;
+ uma_zone_t sc_rx_zone;
+ char sc_rx_zname[64];
+
+ /* RX Frame Queue */
+ t_Handle sc_rx_fqr;
+ uint32_t sc_rx_fqid;
+
+ /* TX Frame Queue */
+ t_Handle sc_tx_fqr;
+ bool sc_tx_fqr_full;
+ t_Handle sc_tx_conf_fqr;
+ uint32_t sc_tx_conf_fqid;
+
+ /* Frame Info Zone */
+ uma_zone_t sc_fi_zone;
+ char sc_fi_zname[64];
+};
+/** @} */
+
+
+/**
+ * @group dTSEC FMan PORT API.
+ * @{
+ */
+enum dtsec_fm_port_params {
+ FM_PORT_LIODN_BASE = 0,
+ FM_PORT_LIODN_OFFSET = 0,
+ FM_PORT_MEM_ID = 0,
+ FM_PORT_MEM_ATTR = MEMORY_ATTR_CACHEABLE,
+ FM_PORT_BUFFER_SIZE = MCLBYTES,
+};
+
+e_FmPortType dtsec_fm_port_rx_type(enum eth_dev_type type);
+void dtsec_fm_port_rx_exception_callback(t_Handle app,
+ e_FmPortExceptions exception);
+void dtsec_fm_port_tx_exception_callback(t_Handle app,
+ e_FmPortExceptions exception);
+e_FmPortType dtsec_fm_port_tx_type(enum eth_dev_type type);
+/** @} */
+
+
+/**
+ * @group dTSEC bus interface.
+ * @{
+ */
+int dtsec_attach(device_t dev);
+int dtsec_detach(device_t dev);
+int dtsec_suspend(device_t dev);
+int dtsec_resume(device_t dev);
+int dtsec_shutdown(device_t dev);
+int dtsec_miibus_readreg(device_t dev, int phy, int reg);
+int dtsec_miibus_writereg(device_t dev, int phy, int reg,
+ int value);
+void dtsec_miibus_statchg(device_t dev);
+/** @} */
+
+#endif /* IF_DTSEC_H_ */
diff --git a/sys/dev/dpaa/if_dtsec_fdt.c b/sys/dev/dpaa/if_dtsec_fdt.c
new file mode 100644
index 0000000..25b2cfc
--- /dev/null
+++ b/sys/dev/dpaa/if_dtsec_fdt.c
@@ -0,0 +1,215 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+
+#include <powerpc/mpc85xx/mpc85xx.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include "miibus_if.h"
+
+#include <contrib/ncsw/inc/Peripherals/fm_port_ext.h>
+#include <contrib/ncsw/inc/xx_ext.h>
+
+#include "if_dtsec.h"
+
+
+static int dtsec_fdt_probe(device_t dev);
+static int dtsec_fdt_attach(device_t dev);
+
+static device_method_t dtsec_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, dtsec_fdt_probe),
+ DEVMETHOD(device_attach, dtsec_fdt_attach),
+ DEVMETHOD(device_detach, dtsec_detach),
+
+ DEVMETHOD(device_shutdown, dtsec_shutdown),
+ DEVMETHOD(device_suspend, dtsec_suspend),
+ DEVMETHOD(device_resume, dtsec_resume),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+
+ /* MII interface */
+ DEVMETHOD(miibus_readreg, dtsec_miibus_readreg),
+ DEVMETHOD(miibus_writereg, dtsec_miibus_writereg),
+ DEVMETHOD(miibus_statchg, dtsec_miibus_statchg),
+
+ { 0, 0 }
+};
+
+static driver_t dtsec_driver = {
+ "dtsec",
+ dtsec_methods,
+ sizeof(struct dtsec_softc),
+};
+
+static devclass_t dtsec_devclass;
+DRIVER_MODULE(dtsec, dpaa, dtsec_driver, dtsec_devclass, 0, 0);
+DRIVER_MODULE(miibus, dtsec, miibus_driver, miibus_devclass, 0, 0);
+MODULE_DEPEND(dtsec, ether, 1, 1, 1);
+MODULE_DEPEND(dtsec, miibus, 1, 1, 1);
+
+static int
+dtsec_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,dpa-ethernet"))
+ return (ENXIO);
+
+ device_set_desc(dev, "Freescale Data Path Triple Speed Ethernet "
+ "Controller");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+dtsec_fdt_attach(device_t dev)
+{
+ struct dtsec_softc *sc;
+ phandle_t node, enet_node, phy_node;
+ phandle_t fman_rxtx_node[2];
+ char phy_type[6];
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+ if (OF_getprop(node, "fsl,fman-mac", (void *)&enet_node,
+ sizeof(enet_node)) == -1) {
+ device_printf(dev, "Could not load fsl,fman-mac property "
+ "from DTS\n");
+ return (ENXIO);
+ }
+
+ enet_node = OF_instance_to_package(enet_node);
+
+ if (OF_getprop(enet_node, "local-mac-address",
+ (void *)sc->sc_mac_addr, 6) == -1) {
+ if (device_get_unit(dev) != 0) {
+ device_printf(dev,
+ "Could not load local-mac-addr property "
+ "from DTS\n");
+ return (ENXIO);
+ }
+ sc->sc_hidden = true;
+ }
+
+ /* Get link speed */
+ if (fdt_is_compatible(enet_node, "fsl,fman-1g-mac") != 0)
+ sc->sc_eth_dev_type = ETH_DTSEC;
+ else if (fdt_is_compatible(enet_node, "fsl,fman-10g-mac") != 0)
+ sc->sc_eth_dev_type = ETH_10GSEC;
+ else
+ return(ENXIO);
+
+ /* Get MAC memory offset in SoC */
+ if (OF_getprop(enet_node, "reg", (void *)&sc->sc_mac_mem_offset,
+ sizeof(sc->sc_mac_mem_offset)) <= 0)
+ return (ENXIO);
+
+ /* Get PHY address */
+ if (OF_getprop(enet_node, "phy-handle", (void *)&phy_node,
+ sizeof(phy_node)) <= 0)
+ return (ENXIO);
+
+ phy_node = OF_instance_to_package(phy_node);
+
+ if (OF_getprop(phy_node, "reg", (void *)&sc->sc_phy_addr,
+ sizeof(sc->sc_phy_addr)) <= 0)
+ return (ENXIO);
+
+ /* Get PHY connection type */
+ if (OF_getprop(enet_node, "phy-connection-type", (void *)phy_type,
+ sizeof(phy_type)) <= 0)
+ return (ENXIO);
+
+ if (!strcmp(phy_type, "sgmii"))
+ sc->sc_mac_enet_mode = e_ENET_MODE_SGMII_1000;
+ else if (!strcmp(phy_type, "rgmii"))
+ sc->sc_mac_enet_mode = e_ENET_MODE_RGMII_1000;
+ else if (!strcmp(phy_type, "xgmii"))
+ /* We set 10 Gigabit mode flag however we don't support it */
+ sc->sc_mac_enet_mode = e_ENET_MODE_XGMII_10000;
+ else
+ return (ENXIO);
+
+ /* Get RX/TX port handles */
+ if (OF_getprop(enet_node, "fsl,port-handles", (void *)fman_rxtx_node,
+ sizeof(fman_rxtx_node)) <= 0)
+ return (ENXIO);
+
+ if (fman_rxtx_node[0] == 0)
+ return (ENXIO);
+
+ if (fman_rxtx_node[1] == 0)
+ return (ENXIO);
+
+ fman_rxtx_node[0] = OF_instance_to_package(fman_rxtx_node[0]);
+ fman_rxtx_node[1] = OF_instance_to_package(fman_rxtx_node[1]);
+
+ if (fdt_is_compatible(fman_rxtx_node[0], "fsl,fman-port-1g-rx") == 0)
+ return (ENXIO);
+
+ if (fdt_is_compatible(fman_rxtx_node[1], "fsl,fman-port-1g-tx") == 0)
+ return (ENXIO);
+
+ /* Get RX port HW id */
+ if (OF_getprop(fman_rxtx_node[0], "reg", (void *)&sc->sc_port_rx_hw_id,
+ sizeof(sc->sc_port_rx_hw_id)) <= 0)
+ return (ENXIO);
+
+ /* Get TX port HW id */
+ if (OF_getprop(fman_rxtx_node[1], "reg", (void *)&sc->sc_port_tx_hw_id,
+ sizeof(sc->sc_port_tx_hw_id)) <= 0)
+ return (ENXIO);
+
+ /* Get QMan channel */
+ if (OF_getprop(fman_rxtx_node[1], "fsl,qman-channel-id",
+ (void *)&sc->sc_port_tx_qman_chan,
+ sizeof(sc->sc_port_tx_qman_chan)) <= 0)
+ return (ENXIO);
+
+ return (dtsec_attach(dev));
+}
diff --git a/sys/dev/dpaa/if_dtsec_im.c b/sys/dev/dpaa/if_dtsec_im.c
new file mode 100644
index 0000000..335f489
--- /dev/null
+++ b/sys/dev/dpaa/if_dtsec_im.c
@@ -0,0 +1,262 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/sockio.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_arp.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "miibus_if.h"
+
+#include <contrib/ncsw/inc/Peripherals/fm_mac_ext.h>
+#include <contrib/ncsw/inc/Peripherals/fm_port_ext.h>
+#include <contrib/ncsw/inc/xx_ext.h>
+
+#include "fman.h"
+#include "if_dtsec.h"
+#include "if_dtsec_im.h"
+
+
+/**
+ * @group dTSEC FMan PORT routines.
+ * @{
+ */
+static e_RxStoreResponse
+dtsec_im_fm_port_rx_callback(t_Handle app, uint8_t *data, uint16_t length,
+ uint16_t status, uint8_t position, t_Handle buf_context)
+{
+ struct dtsec_softc *sc;
+ struct mbuf *m;
+
+ /* TODO STATUS / Position checking */
+ sc = app;
+
+ m = m_devget(data, length, 0, sc->sc_ifnet, NULL);
+ if (m)
+ (*sc->sc_ifnet->if_input)(sc->sc_ifnet, m);
+
+ XX_FreeSmart(data);
+
+ return (e_RX_STORE_RESPONSE_CONTINUE);
+}
+
+static void
+dtsec_im_fm_port_tx_conf_callback(t_Handle app, uint8_t *data, uint16_t status,
+ t_Handle buf_context)
+{
+
+ /* TODO: Check status */
+ XX_FreeSmart(data);
+}
+
+static uint8_t *
+dtsec_im_fm_port_rx_get_buf(t_Handle buffer_pool, t_Handle *buf_context_handle)
+{
+ struct dtsec_softc *sc;
+ uint8_t *buffer;
+
+ sc = buffer_pool;
+
+ buffer = XX_MallocSmart(FM_PORT_BUFFER_SIZE, 0, sizeof(void *));
+ if (!buffer)
+ device_printf(sc->sc_dev, "couldn't allocate RX buffer.\n");
+
+ return (buffer);
+}
+
+static t_Error
+dtsec_im_fm_port_rx_put_buf(t_Handle buffer_pool, uint8_t *buffer,
+ t_Handle buf_context)
+{
+
+ XX_FreeSmart(buffer);
+ return (E_OK);
+}
+
+int
+dtsec_im_fm_port_rx_init(struct dtsec_softc *sc, int unit)
+{
+ t_FmPortParams params;
+ t_BufferPoolInfo *pool_params;
+ t_FmPortImRxTxParams *im_params;
+ t_Error error;
+
+ memset(&params, 0, sizeof(params));
+
+ params.baseAddr = sc->sc_fm_base + sc->sc_port_rx_hw_id;
+ params.h_Fm = sc->sc_fmh;
+ params.portType = dtsec_fm_port_rx_type(sc->sc_eth_dev_type);
+ params.portId = sc->sc_eth_id;
+ params.independentModeEnable = TRUE;
+ params.liodnBase = FM_PORT_LIODN_BASE;
+ params.f_Exception = dtsec_fm_port_rx_exception_callback;
+ params.h_App = sc;
+
+ im_params = &params.specificParams.imRxTxParams;
+ im_params->h_FmMuram = sc->sc_muramh;
+ im_params->liodnOffset = FM_PORT_LIODN_OFFSET;
+ im_params->dataMemId = FM_PORT_MEM_ID;
+ im_params->dataMemAttributes = FM_PORT_MEM_ATTR;
+ im_params->f_RxStore = dtsec_im_fm_port_rx_callback;
+
+ pool_params = &params.specificParams.imRxTxParams.rxPoolParams;
+ pool_params->h_BufferPool = sc;
+ pool_params->f_GetBuf = dtsec_im_fm_port_rx_get_buf;
+ pool_params->f_PutBuf = dtsec_im_fm_port_rx_put_buf;
+ pool_params->bufferSize = FM_PORT_BUFFER_SIZE;
+
+ sc->sc_rxph = FM_PORT_Config(&params);
+ if (sc->sc_rxph == NULL) {
+ device_printf(sc->sc_dev, "couldn't configure FM Port RX.\n");
+ return (ENXIO);
+ }
+
+ error = FM_PORT_Init(sc->sc_rxph);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't initialize FM Port RX.\n");
+ FM_PORT_Free(sc->sc_rxph);
+ return (ENXIO);
+ }
+
+ if (bootverbose)
+ device_printf(sc->sc_dev, "RX hw port 0x%02x initialized.\n",
+ sc->sc_port_rx_hw_id);
+
+ return (0);
+}
+
+int
+dtsec_im_fm_port_tx_init(struct dtsec_softc *sc, int unit)
+{
+ t_FmPortParams params;
+ t_FmPortImRxTxParams *im_params;
+ t_Error error;
+
+ memset(&params, 0, sizeof(params));
+
+ params.baseAddr = sc->sc_fm_base + sc->sc_port_tx_hw_id;
+ params.h_Fm = sc->sc_fmh;
+ params.portType = dtsec_fm_port_tx_type(sc->sc_eth_dev_type);
+ params.portId = unit;
+ params.independentModeEnable = TRUE;
+ params.liodnBase = FM_PORT_LIODN_BASE;
+ params.f_Exception = dtsec_fm_port_tx_exception_callback;
+ params.h_App = sc;
+
+ im_params = &params.specificParams.imRxTxParams;
+ im_params->h_FmMuram = sc->sc_muramh;
+ im_params->liodnOffset = FM_PORT_LIODN_OFFSET;
+ im_params->dataMemId = FM_PORT_MEM_ID;
+ im_params->dataMemAttributes = FM_PORT_MEM_ATTR;
+ im_params->f_TxConf = dtsec_im_fm_port_tx_conf_callback;
+
+ sc->sc_txph = FM_PORT_Config(&params);
+ if (sc->sc_txph == NULL) {
+ device_printf(sc->sc_dev, "couldn't configure FM Port TX.\n");
+ return (ENXIO);
+ }
+
+ error = FM_PORT_Init(sc->sc_txph);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't initialize FM Port TX.\n");
+ FM_PORT_Free(sc->sc_txph);
+ return (ENXIO);
+ }
+
+ if (bootverbose)
+ device_printf(sc->sc_dev, "TX hw port 0x%02x initialized.\n",
+ sc->sc_port_tx_hw_id);
+
+ return (0);
+}
+/** @} */
+
+
+/**
+ * @group dTSEC IFnet routines.
+ * @{
+ */
+void
+dtsec_im_if_start_locked(struct dtsec_softc *sc)
+{
+ uint8_t *buffer;
+ uint16_t length;
+ struct mbuf *m;
+ int error;
+
+ DTSEC_LOCK_ASSERT(sc);
+ /* TODO: IFF_DRV_OACTIVE */
+
+ if ((sc->sc_mii->mii_media_status & IFM_ACTIVE) == 0)
+ return;
+
+ if ((sc->sc_ifnet->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING)
+ return;
+
+ while (!IFQ_DRV_IS_EMPTY(&sc->sc_ifnet->if_snd)) {
+ IFQ_DRV_DEQUEUE(&sc->sc_ifnet->if_snd, m);
+ if (m == NULL)
+ break;
+
+ length = m_length(m, NULL);
+ buffer = XX_MallocSmart(length, 0, sizeof(void *));
+ if (!buffer) {
+ m_freem(m);
+ break;
+ }
+
+ m_copydata(m, 0, length, buffer);
+ m_freem(m);
+
+ error = FM_PORT_ImTx(sc->sc_txph, buffer, length, TRUE, buffer);
+ if (error != E_OK) {
+ /* TODO: Ring full */
+ XX_FreeSmart(buffer);
+ break;
+ }
+ }
+}
+/** @} */
diff --git a/sys/dev/dpaa/if_dtsec_im.h b/sys/dev/dpaa/if_dtsec_im.h
new file mode 100644
index 0000000..922bea4
--- /dev/null
+++ b/sys/dev/dpaa/if_dtsec_im.h
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef IF_DTSEC_IM_H_
+#define IF_DTSEC_IM_H_
+
+/**
+ * @group dTSEC Independent Mode API.
+ * @{
+ */
+int dtsec_im_fm_port_tx_init(struct dtsec_softc *sc, int unit);
+int dtsec_im_fm_port_rx_init(struct dtsec_softc *sc, int unit);
+void dtsec_im_if_start_locked(struct dtsec_softc *sc);
+/** @} */
+
+#endif /* IF_DTSEC_IM_H_ */
diff --git a/sys/dev/dpaa/if_dtsec_rm.c b/sys/dev/dpaa/if_dtsec_rm.c
new file mode 100644
index 0000000..30ab326
--- /dev/null
+++ b/sys/dev/dpaa/if_dtsec_rm.c
@@ -0,0 +1,654 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/sockio.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_arp.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "miibus_if.h"
+
+#include <contrib/ncsw/inc/Peripherals/fm_mac_ext.h>
+#include <contrib/ncsw/inc/Peripherals/fm_port_ext.h>
+#include <contrib/ncsw/inc/xx_ext.h>
+
+#include "fman.h"
+#include "bman.h"
+#include "qman.h"
+#include "if_dtsec.h"
+#include "if_dtsec_rm.h"
+
+
+/**
+ * @group dTSEC RM private defines.
+ * @{
+ */
+#define DTSEC_BPOOLS_USED (1)
+#define DTSEC_MAX_TX_QUEUE_LEN 256
+
+struct dtsec_rm_frame_info {
+ struct mbuf *fi_mbuf;
+ t_DpaaSGTE fi_sgt[DPAA_NUM_OF_SG_TABLE_ENTRY];
+};
+
+enum dtsec_rm_pool_params {
+ DTSEC_RM_POOL_RX_LOW_MARK = 16,
+ DTSEC_RM_POOL_RX_HIGH_MARK = 64,
+ DTSEC_RM_POOL_RX_MAX_SIZE = 256,
+
+ DTSEC_RM_POOL_FI_LOW_MARK = 16,
+ DTSEC_RM_POOL_FI_HIGH_MARK = 64,
+ DTSEC_RM_POOL_FI_MAX_SIZE = 256,
+};
+
+enum dtsec_rm_fqr_params {
+ DTSEC_RM_FQR_RX_CHANNEL = e_QM_FQ_CHANNEL_POOL1,
+ DTSEC_RM_FQR_RX_WQ = 1,
+ DTSEC_RM_FQR_TX_CONF_CHANNEL = e_QM_FQ_CHANNEL_SWPORTAL0,
+ DTSEC_RM_FQR_TX_WQ = 1,
+ DTSEC_RM_FQR_TX_CONF_WQ = 1
+};
+/** @} */
+
+
+/**
+ * @group dTSEC Frame Info routines.
+ * @{
+ */
+void
+dtsec_rm_fi_pool_free(struct dtsec_softc *sc)
+{
+
+ if (sc->sc_fi_zone != NULL)
+ uma_zdestroy(sc->sc_fi_zone);
+}
+
+int
+dtsec_rm_fi_pool_init(struct dtsec_softc *sc)
+{
+
+ snprintf(sc->sc_fi_zname, sizeof(sc->sc_fi_zname), "%s: Frame Info",
+ device_get_nameunit(sc->sc_dev));
+
+ sc->sc_fi_zone = uma_zcreate(sc->sc_fi_zname,
+ sizeof(struct dtsec_rm_frame_info), NULL, NULL, NULL, NULL,
+ sizeof(void *), 0);
+ if (sc->sc_fi_zone == NULL)
+ return (EIO);
+
+ return (0);
+}
+
+static struct dtsec_rm_frame_info *
+dtsec_rm_fi_alloc(struct dtsec_softc *sc)
+{
+ struct dtsec_rm_frame_info *fi;
+
+ fi = uma_zalloc(sc->sc_fi_zone, M_NOWAIT);
+
+ return (fi);
+}
+
+static void
+dtsec_rm_fi_free(struct dtsec_softc *sc, struct dtsec_rm_frame_info *fi)
+{
+
+ XX_UntrackAddress(fi);
+ uma_zfree(sc->sc_fi_zone, fi);
+}
+/** @} */
+
+
+/**
+ * @group dTSEC FMan PORT routines.
+ * @{
+ */
+int
+dtsec_rm_fm_port_rx_init(struct dtsec_softc *sc, int unit)
+{
+ t_FmPortParams params;
+ t_FmPortRxParams *rx_params;
+ t_FmPortExtPools *pool_params;
+ t_Error error;
+
+ memset(&params, 0, sizeof(params));
+
+ params.baseAddr = sc->sc_fm_base + sc->sc_port_rx_hw_id;
+ params.h_Fm = sc->sc_fmh;
+ params.portType = dtsec_fm_port_rx_type(sc->sc_eth_dev_type);
+ params.portId = sc->sc_eth_id;
+ params.independentModeEnable = FALSE;
+ params.liodnBase = FM_PORT_LIODN_BASE;
+ params.f_Exception = dtsec_fm_port_rx_exception_callback;
+ params.h_App = sc;
+
+ rx_params = &params.specificParams.rxParams;
+ rx_params->errFqid = sc->sc_rx_fqid;
+ rx_params->dfltFqid = sc->sc_rx_fqid;
+ rx_params->liodnOffset = 0;
+
+ pool_params = &rx_params->extBufPools;
+ pool_params->numOfPoolsUsed = DTSEC_BPOOLS_USED;
+ pool_params->extBufPool->id = sc->sc_rx_bpid;
+ pool_params->extBufPool->size = FM_PORT_BUFFER_SIZE;
+
+ sc->sc_rxph = FM_PORT_Config(&params);
+ if (sc->sc_rxph == NULL) {
+ device_printf(sc->sc_dev, "couldn't configure FM Port RX.\n");
+ return (ENXIO);
+ }
+
+ error = FM_PORT_Init(sc->sc_rxph);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't initialize FM Port RX.\n");
+ FM_PORT_Free(sc->sc_rxph);
+ return (ENXIO);
+ }
+
+ if (bootverbose)
+ device_printf(sc->sc_dev, "RX hw port 0x%02x initialized.\n",
+ sc->sc_port_rx_hw_id);
+
+ return (0);
+}
+
+int
+dtsec_rm_fm_port_tx_init(struct dtsec_softc *sc, int unit)
+{
+ t_FmPortParams params;
+ t_FmPortNonRxParams *tx_params;
+ t_Error error;
+
+ memset(&params, 0, sizeof(params));
+
+ params.baseAddr = sc->sc_fm_base + sc->sc_port_tx_hw_id;
+ params.h_Fm = sc->sc_fmh;
+ params.portType = dtsec_fm_port_tx_type(sc->sc_eth_dev_type);
+ params.portId = sc->sc_eth_id;
+ params.independentModeEnable = FALSE;
+ params.liodnBase = FM_PORT_LIODN_BASE;
+ params.f_Exception = dtsec_fm_port_tx_exception_callback;
+ params.h_App = sc;
+
+ tx_params = &params.specificParams.nonRxParams;
+ tx_params->errFqid = sc->sc_tx_conf_fqid;
+ tx_params->dfltFqid = sc->sc_tx_conf_fqid;
+ tx_params->qmChannel = sc->sc_port_tx_qman_chan;
+#ifdef FM_OP_PARTITION_ERRATA_FMANx8
+ tx_params->opLiodnOffset = 0;
+#endif
+
+ sc->sc_txph = FM_PORT_Config(&params);
+ if (sc->sc_txph == NULL) {
+ device_printf(sc->sc_dev, "couldn't configure FM Port TX.\n");
+ return (ENXIO);
+ }
+
+ error = FM_PORT_Init(sc->sc_txph);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "couldn't initialize FM Port TX.\n");
+ FM_PORT_Free(sc->sc_txph);
+ return (ENXIO);
+ }
+
+ if (bootverbose)
+ device_printf(sc->sc_dev, "TX hw port 0x%02x initialized.\n",
+ sc->sc_port_tx_hw_id);
+
+ return (0);
+}
+/** @} */
+
+
+/**
+ * @group dTSEC buffer pools routines.
+ * @{
+ */
+static t_Error
+dtsec_rm_pool_rx_put_buffer(t_Handle h_BufferPool, uint8_t *buffer,
+ t_Handle context)
+{
+ struct dtsec_softc *sc;
+
+ sc = h_BufferPool;
+ uma_zfree(sc->sc_rx_zone, buffer);
+
+ return (E_OK);
+}
+
+static uint8_t *
+dtsec_rm_pool_rx_get_buffer(t_Handle h_BufferPool, t_Handle *context)
+{
+ struct dtsec_softc *sc;
+ uint8_t *buffer;
+
+ sc = h_BufferPool;
+ buffer = uma_zalloc(sc->sc_rx_zone, M_NOWAIT);
+
+ return (buffer);
+}
+
+static void
+dtsec_rm_pool_rx_depleted(t_Handle h_App, bool in)
+{
+ struct dtsec_softc *sc;
+ unsigned int count;
+
+ sc = h_App;
+
+ if (!in)
+ return;
+
+ while (1) {
+ count = bman_count(sc->sc_rx_pool);
+ if (count > DTSEC_RM_POOL_RX_HIGH_MARK)
+ return;
+
+ bman_pool_fill(sc->sc_rx_pool, DTSEC_RM_POOL_RX_HIGH_MARK);
+ }
+}
+
+void
+dtsec_rm_pool_rx_free(struct dtsec_softc *sc)
+{
+
+ if (sc->sc_rx_pool != NULL)
+ bman_pool_destroy(sc->sc_rx_pool);
+
+ if (sc->sc_rx_zone != NULL)
+ uma_zdestroy(sc->sc_rx_zone);
+}
+
+int
+dtsec_rm_pool_rx_init(struct dtsec_softc *sc)
+{
+
+ /* FM_PORT_BUFFER_SIZE must be less than PAGE_SIZE */
+ CTASSERT(FM_PORT_BUFFER_SIZE < PAGE_SIZE);
+
+ snprintf(sc->sc_rx_zname, sizeof(sc->sc_rx_zname), "%s: RX Buffers",
+ device_get_nameunit(sc->sc_dev));
+
+ sc->sc_rx_zone = uma_zcreate(sc->sc_rx_zname, FM_PORT_BUFFER_SIZE, NULL,
+ NULL, NULL, NULL, FM_PORT_BUFFER_SIZE, 0);
+ if (sc->sc_rx_zone == NULL)
+ return (EIO);
+
+ sc->sc_rx_pool = bman_pool_create(&sc->sc_rx_bpid, FM_PORT_BUFFER_SIZE,
+ 0, 0, DTSEC_RM_POOL_RX_MAX_SIZE, dtsec_rm_pool_rx_get_buffer,
+ dtsec_rm_pool_rx_put_buffer, DTSEC_RM_POOL_RX_LOW_MARK,
+ DTSEC_RM_POOL_RX_HIGH_MARK, 0, 0, dtsec_rm_pool_rx_depleted, sc, NULL,
+ NULL);
+ if (sc->sc_rx_pool == NULL) {
+ dtsec_rm_pool_rx_free(sc);
+ return (EIO);
+ }
+
+ return (0);
+}
+/** @} */
+
+
+/**
+ * @group dTSEC Frame Queue Range routines.
+ * @{
+ */
+static void
+dtsec_rm_fqr_mext_free(struct mbuf *m, void *buffer, void *arg)
+{
+ struct dtsec_softc *sc;
+
+ sc = arg;
+ if (bman_count(sc->sc_rx_pool) <= DTSEC_RM_POOL_RX_MAX_SIZE)
+ bman_put_buffer(sc->sc_rx_pool, buffer);
+ else
+ dtsec_rm_pool_rx_put_buffer(arg, buffer, NULL);
+}
+
+static e_RxStoreResponse
+dtsec_rm_fqr_rx_callback(t_Handle app, t_Handle fqr, t_Handle portal,
+ uint32_t fqid_off, t_DpaaFD *frame)
+{
+ struct dtsec_softc *sc;
+ struct mbuf *m;
+
+ m = NULL;
+ sc = app;
+
+ KASSERT(DPAA_FD_GET_FORMAT(frame) == e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF,
+ ("%s(): Got unsupported frame format 0x%02X!", __func__,
+ DPAA_FD_GET_FORMAT(frame)));
+
+ KASSERT(DPAA_FD_GET_OFFSET(frame) == 0,
+ ("%s(): Only offset 0 is supported!", __func__));
+
+ if (DPAA_FD_GET_STATUS(frame) != 0) {
+ device_printf(sc->sc_dev, "RX error: 0x%08X\n",
+ DPAA_FD_GET_STATUS(frame));
+ goto err;
+ }
+
+ m = m_gethdr(M_NOWAIT, MT_HEADER);
+ if (m == NULL)
+ goto err;
+
+ MEXTADD(m, DPAA_FD_GET_ADDR(frame), FM_PORT_BUFFER_SIZE,
+ dtsec_rm_fqr_mext_free, DPAA_FD_GET_ADDR(frame), sc, 0,
+ EXT_NET_DRV);
+
+ m->m_pkthdr.rcvif = sc->sc_ifnet;
+ m->m_len = DPAA_FD_GET_LENGTH(frame);
+ m_fixhdr(m);
+
+ (*sc->sc_ifnet->if_input)(sc->sc_ifnet, m);
+
+ return (e_RX_STORE_RESPONSE_CONTINUE);
+
+err:
+ bman_put_buffer(sc->sc_rx_pool, DPAA_FD_GET_ADDR(frame));
+ if (m != NULL)
+ m_freem(m);
+
+ return (e_RX_STORE_RESPONSE_CONTINUE);
+}
+
+static e_RxStoreResponse
+dtsec_rm_fqr_tx_confirm_callback(t_Handle app, t_Handle fqr, t_Handle portal,
+ uint32_t fqid_off, t_DpaaFD *frame)
+{
+ struct dtsec_rm_frame_info *fi;
+ struct dtsec_softc *sc;
+ unsigned int qlen;
+ t_DpaaSGTE *sgt0;
+
+ sc = app;
+
+ if (DPAA_FD_GET_STATUS(frame) != 0)
+ device_printf(sc->sc_dev, "TX error: 0x%08X\n",
+ DPAA_FD_GET_STATUS(frame));
+
+ /*
+ * We are storing struct dtsec_rm_frame_info in first entry
+ * of scatter-gather table.
+ */
+ sgt0 = DPAA_FD_GET_ADDR(frame);
+ fi = DPAA_SGTE_GET_ADDR(sgt0);
+
+ /* Free transmitted frame */
+ m_freem(fi->fi_mbuf);
+ dtsec_rm_fi_free(sc, fi);
+
+ qlen = qman_fqr_get_counter(sc->sc_tx_conf_fqr, 0,
+ e_QM_FQR_COUNTERS_FRAME);
+
+ if (qlen == 0) {
+ DTSEC_LOCK(sc);
+
+ if (sc->sc_tx_fqr_full) {
+ sc->sc_tx_fqr_full = 0;
+ dtsec_rm_if_start_locked(sc);
+ }
+
+ DTSEC_UNLOCK(sc);
+ }
+
+ return (e_RX_STORE_RESPONSE_CONTINUE);
+}
+
+void
+dtsec_rm_fqr_rx_free(struct dtsec_softc *sc)
+{
+
+ if (sc->sc_rx_fqr)
+ qman_fqr_free(sc->sc_rx_fqr);
+}
+
+int
+dtsec_rm_fqr_rx_init(struct dtsec_softc *sc)
+{
+ t_Error error;
+ t_Handle fqr;
+
+ /* Default Frame Queue */
+ fqr = qman_fqr_create(1, DTSEC_RM_FQR_RX_CHANNEL, DTSEC_RM_FQR_RX_WQ,
+ FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, 0);
+ if (fqr == NULL) {
+ device_printf(sc->sc_dev, "could not create default RX queue"
+ "\n");
+ return (EIO);
+ }
+
+ sc->sc_rx_fqr = fqr;
+ sc->sc_rx_fqid = qman_fqr_get_base_fqid(fqr);
+
+ error = qman_fqr_register_cb(fqr, dtsec_rm_fqr_rx_callback, sc);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "could not register RX callback\n");
+ dtsec_rm_fqr_rx_free(sc);
+ return (EIO);
+ }
+
+ return (0);
+}
+
+void
+dtsec_rm_fqr_tx_free(struct dtsec_softc *sc)
+{
+
+ if (sc->sc_tx_fqr)
+ qman_fqr_free(sc->sc_tx_fqr);
+
+ if (sc->sc_tx_conf_fqr)
+ qman_fqr_free(sc->sc_tx_conf_fqr);
+}
+
+int
+dtsec_rm_fqr_tx_init(struct dtsec_softc *sc)
+{
+ t_Error error;
+ t_Handle fqr;
+
+ /* TX Frame Queue */
+ fqr = qman_fqr_create(1, sc->sc_port_tx_qman_chan,
+ DTSEC_RM_FQR_TX_WQ, FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0, 0);
+ if (fqr == NULL) {
+ device_printf(sc->sc_dev, "could not create default TX queue"
+ "\n");
+ return (EIO);
+ }
+
+ sc->sc_tx_fqr = fqr;
+
+ /* TX Confirmation Frame Queue */
+ fqr = qman_fqr_create(1, DTSEC_RM_FQR_TX_CONF_CHANNEL,
+ DTSEC_RM_FQR_TX_CONF_WQ, FALSE, 0, FALSE, FALSE, TRUE, FALSE, 0, 0,
+ 0);
+ if (fqr == NULL) {
+ device_printf(sc->sc_dev, "could not create TX confirmation "
+ "queue\n");
+ dtsec_rm_fqr_tx_free(sc);
+ return (EIO);
+ }
+
+ sc->sc_tx_conf_fqr = fqr;
+ sc->sc_tx_conf_fqid = qman_fqr_get_base_fqid(fqr);
+
+ error = qman_fqr_register_cb(fqr, dtsec_rm_fqr_tx_confirm_callback, sc);
+ if (error != E_OK) {
+ device_printf(sc->sc_dev, "could not register TX confirmation "
+ "callback\n");
+ dtsec_rm_fqr_tx_free(sc);
+ return (EIO);
+ }
+
+ return (0);
+}
+/** @} */
+
+
+/**
+ * @group dTSEC IFnet routines.
+ * @{
+ */
+void
+dtsec_rm_if_start_locked(struct dtsec_softc *sc)
+{
+ vm_size_t dsize, psize, ssize;
+ struct dtsec_rm_frame_info *fi;
+ unsigned int qlen, i;
+ struct mbuf *m0, *m;
+ vm_offset_t vaddr;
+ vm_paddr_t paddr;
+ t_DpaaFD fd;
+
+ DTSEC_LOCK_ASSERT(sc);
+ /* TODO: IFF_DRV_OACTIVE */
+
+ if ((sc->sc_mii->mii_media_status & IFM_ACTIVE) == 0)
+ return;
+
+ if ((sc->sc_ifnet->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING)
+ return;
+
+ while (!IFQ_DRV_IS_EMPTY(&sc->sc_ifnet->if_snd)) {
+ /* Check length of the TX queue */
+ qlen = qman_fqr_get_counter(sc->sc_tx_fqr, 0,
+ e_QM_FQR_COUNTERS_FRAME);
+
+ if (qlen >= DTSEC_MAX_TX_QUEUE_LEN) {
+ sc->sc_tx_fqr_full = 1;
+ return;
+ }
+
+ fi = dtsec_rm_fi_alloc(sc);
+ if (fi == NULL)
+ return;
+
+ IFQ_DRV_DEQUEUE(&sc->sc_ifnet->if_snd, m0);
+ if (m0 == NULL) {
+ dtsec_rm_fi_free(sc, fi);
+ return;
+ }
+
+ i = 0;
+ m = m0;
+ psize = 0;
+ dsize = 0;
+ fi->fi_mbuf = m0;
+ while (m && i < DPAA_NUM_OF_SG_TABLE_ENTRY) {
+ if (m->m_len == 0)
+ continue;
+
+ /*
+ * First entry in scatter-gather table is used to keep
+ * pointer to frame info structure.
+ */
+ DPAA_SGTE_SET_ADDR(&fi->fi_sgt[i], (void *)fi);
+ DPAA_SGTE_SET_LENGTH(&fi->fi_sgt[i], 0);
+
+ DPAA_SGTE_SET_EXTENSION(&fi->fi_sgt[i], 0);
+ DPAA_SGTE_SET_FINAL(&fi->fi_sgt[i], 0);
+ DPAA_SGTE_SET_BPID(&fi->fi_sgt[i], 0);
+ DPAA_SGTE_SET_OFFSET(&fi->fi_sgt[i], 0);
+ i++;
+
+ dsize = m->m_len;
+ vaddr = (vm_offset_t)m->m_data;
+ while (dsize > 0 && i < DPAA_NUM_OF_SG_TABLE_ENTRY) {
+ paddr = XX_VirtToPhys((void *)vaddr);
+ ssize = PAGE_SIZE - (paddr & PAGE_MASK);
+ if (m->m_len < ssize)
+ ssize = m->m_len;
+
+ DPAA_SGTE_SET_ADDR(&fi->fi_sgt[i],
+ (void *)vaddr);
+ DPAA_SGTE_SET_LENGTH(&fi->fi_sgt[i], ssize);
+
+ DPAA_SGTE_SET_EXTENSION(&fi->fi_sgt[i], 0);
+ DPAA_SGTE_SET_FINAL(&fi->fi_sgt[i], 0);
+ DPAA_SGTE_SET_BPID(&fi->fi_sgt[i], 0);
+ DPAA_SGTE_SET_OFFSET(&fi->fi_sgt[i], 0);
+
+ dsize -= ssize;
+ vaddr += ssize;
+ psize += ssize;
+ i++;
+ }
+
+ if (dsize > 0)
+ break;
+
+ m = m->m_next;
+ }
+
+ /* Check if SG table was constructed properly */
+ if (m != NULL || dsize != 0) {
+ dtsec_rm_fi_free(sc, fi);
+ m_freem(m0);
+ continue;
+ }
+
+ DPAA_SGTE_SET_FINAL(&fi->fi_sgt[i-1], 1);
+
+ DPAA_FD_SET_ADDR(&fd, fi->fi_sgt);
+ DPAA_FD_SET_LENGTH(&fd, psize);
+ DPAA_FD_SET_FORMAT(&fd, e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF);
+
+ DPAA_FD_SET_DD(&fd, 0);
+ DPAA_FD_SET_PID(&fd, 0);
+ DPAA_FD_SET_BPID(&fd, 0);
+ DPAA_FD_SET_OFFSET(&fd, 0);
+ DPAA_FD_SET_STATUS(&fd, 0);
+
+ DTSEC_UNLOCK(sc);
+ if (qman_fqr_enqueue(sc->sc_tx_fqr, 0, &fd) != E_OK) {
+ dtsec_rm_fi_free(sc, fi);
+ m_freem(m0);
+ }
+ DTSEC_LOCK(sc);
+ }
+}
+/** @} */
diff --git a/sys/dev/dpaa/if_dtsec_rm.h b/sys/dev/dpaa/if_dtsec_rm.h
new file mode 100644
index 0000000..b79b44f
--- /dev/null
+++ b/sys/dev/dpaa/if_dtsec_rm.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef IF_DTSEC_RM_H_
+#define IF_DTSEC_RM_H_
+
+/**
+ * @group dTSEC Regular Mode API.
+ * @{
+ */
+int dtsec_rm_fm_port_rx_init(struct dtsec_softc *sc, int unit);
+int dtsec_rm_fm_port_tx_init(struct dtsec_softc *sc, int unit);
+
+void dtsec_rm_if_start_locked(struct dtsec_softc *sc);
+
+int dtsec_rm_pool_rx_init(struct dtsec_softc *sc);
+void dtsec_rm_pool_rx_free(struct dtsec_softc *sc);
+
+int dtsec_rm_fi_pool_init(struct dtsec_softc *sc);
+void dtsec_rm_fi_pool_free(struct dtsec_softc *sc);
+
+int dtsec_rm_fqr_rx_init(struct dtsec_softc *sc);
+int dtsec_rm_fqr_tx_init(struct dtsec_softc *sc);
+void dtsec_rm_fqr_rx_free(struct dtsec_softc *sc);
+void dtsec_rm_fqr_tx_free(struct dtsec_softc *sc);
+/** @} */
+
+#endif /* IF_DTSEC_RM_H_ */
diff --git a/sys/dev/dpaa/portals.h b/sys/dev/dpaa/portals.h
new file mode 100644
index 0000000..3f00676
--- /dev/null
+++ b/sys/dev/dpaa/portals.h
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+typedef struct dpaa_portal {
+ int dp_irid; /* interrupt rid */
+ struct resource *dp_ires; /* interrupt resource */
+
+ bool dp_regs_mapped; /* register mapping status */
+
+ t_Handle dp_ph; /* portal's handle */
+ vm_paddr_t dp_ce_pa; /* portal's CE area PA */
+ vm_paddr_t dp_ci_pa; /* portal's CI area PA */
+ uint32_t dp_ce_size; /* portal's CE area size */
+ uint32_t dp_ci_size; /* portal's CI area size */
+ uint32_t dp_intr_num; /* portal's intr. number */
+} dpaa_portal_t;
+
+struct dpaa_portals_softc {
+ device_t sc_dev; /* device handle */
+ vm_paddr_t sc_dp_pa; /* portal's PA */
+ uint32_t sc_dp_size; /* portal's size */
+ int sc_rrid[2]; /* memory rid */
+ struct resource *sc_rres[2]; /* memory resource */
+ dpaa_portal_t sc_dp[MAXCPU];
+};
+
+struct dpaa_portals_devinfo {
+ struct resource_list di_res;
+ int di_intr_rid;
+};
+
+int bman_portals_attach(device_t);
+int bman_portals_detach(device_t);
+
+int qman_portals_attach(device_t);
+int qman_portals_detach(device_t);
+
+int dpaa_portal_alloc_res(device_t, struct dpaa_portals_devinfo *, int);
+void dpaa_portal_map_registers(struct dpaa_portals_softc *);
diff --git a/sys/dev/dpaa/portals_common.c b/sys/dev/dpaa/portals_common.c
new file mode 100644
index 0000000..e540077
--- /dev/null
+++ b/sys/dev/dpaa/portals_common.c
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_platform.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/rman.h>
+#include <sys/sched.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/resource.h>
+#include <machine/tlb.h>
+
+#include <contrib/ncsw/inc/error_ext.h>
+#include <contrib/ncsw/inc/xx_ext.h>
+
+#include "portals.h"
+
+
+int
+dpaa_portal_alloc_res(device_t dev, struct dpaa_portals_devinfo *di, int cpu)
+{
+ struct dpaa_portals_softc *sc = device_get_softc(dev);
+ struct resource_list_entry *rle;
+ int err;
+ struct resource_list *res;
+
+ /* Check if MallocSmart allocator is ready */
+ if (XX_MallocSmartInit() != E_OK)
+ return (ENXIO);
+
+ res = &di->di_res;
+
+ /*
+ * Allocate memory.
+ * Reserve only one pair of CE/CI virtual memory regions
+ * for all CPUs, in order to save the space.
+ */
+ if (sc->sc_rres[0] == NULL) {
+ /* Cache enabled area */
+ rle = resource_list_find(res, SYS_RES_MEMORY, 0);
+ sc->sc_rrid[0] = 0;
+ sc->sc_rres[0] = bus_alloc_resource(dev,
+ SYS_RES_MEMORY, &sc->sc_rrid[0], rle->start + sc->sc_dp_pa,
+ rle->end + sc->sc_dp_pa, rle->count, RF_ACTIVE);
+ pmap_change_attr((vm_offset_t)rman_get_bushandle(sc->sc_rres[0]),
+ rle->count, VM_MEMATTR_CACHEABLE);
+ if (sc->sc_rres[0] == NULL) {
+ device_printf(dev, "Could not allocate memory.\n");
+ return (ENXIO);
+ }
+ /* Cache inhibited area */
+ rle = resource_list_find(res, SYS_RES_MEMORY, 1);
+ sc->sc_rrid[1] = 1;
+ sc->sc_rres[1] = bus_alloc_resource(dev,
+ SYS_RES_MEMORY, &sc->sc_rrid[1], rle->start + sc->sc_dp_pa,
+ rle->end + sc->sc_dp_pa, rle->count, RF_ACTIVE);
+ if (sc->sc_rres[1] == NULL) {
+ device_printf(dev, "Could not allocate memory.\n");
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->sc_rrid[0], sc->sc_rres[0]);
+ return (ENXIO);
+ }
+ sc->sc_dp[PCPU_GET(cpuid)].dp_regs_mapped = 1;
+ }
+ /* Acquire portal's CE_PA and CI_PA */
+ rle = resource_list_find(res, SYS_RES_MEMORY, 0);
+ sc->sc_dp[cpu].dp_ce_pa = rle->start + sc->sc_dp_pa;
+ sc->sc_dp[cpu].dp_ce_size = rle->count;
+ rle = resource_list_find(res, SYS_RES_MEMORY, 1);
+ sc->sc_dp[cpu].dp_ci_pa = rle->start + sc->sc_dp_pa;
+ sc->sc_dp[cpu].dp_ci_size = rle->count;
+
+ /* Allocate interrupts */
+ rle = resource_list_find(res, SYS_RES_IRQ, 0);
+ sc->sc_dp[cpu].dp_irid = 0;
+ sc->sc_dp[cpu].dp_ires = bus_alloc_resource(dev,
+ SYS_RES_IRQ, &sc->sc_dp[cpu].dp_irid, rle->start, rle->end,
+ rle->count, RF_ACTIVE);
+ /* Save interrupt number for later use */
+ sc->sc_dp[cpu].dp_intr_num = rle->start;
+
+ if (sc->sc_dp[cpu].dp_ires == NULL) {
+ device_printf(dev, "Could not allocate irq.\n");
+ return (ENXIO);
+ }
+
+ err = XX_PreallocAndBindIntr((int)sc->sc_dp[cpu].dp_ires, cpu);
+
+ if (err != E_OK) {
+ device_printf(dev, "Could not prealloc and bind interrupt\n");
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->sc_dp[cpu].dp_irid, sc->sc_dp[cpu].dp_ires);
+ sc->sc_dp[cpu].dp_ires = NULL;
+ return (ENXIO);
+ }
+
+#if 0
+ err = bus_generic_config_intr(dev, rle->start, di->di_intr_trig,
+ di->di_intr_pol);
+ if (err != 0) {
+ device_printf(dev, "Could not configure interrupt\n");
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->sc_dp[cpu].dp_irid, sc->sc_dp[cpu].dp_ires);
+ sc->sc_dp[cpu].dp_ires = NULL;
+ return (err);
+ }
+#endif
+
+ return (0);
+}
+
+void
+dpaa_portal_map_registers(struct dpaa_portals_softc *sc)
+{
+ unsigned int cpu;
+
+ sched_pin();
+ cpu = PCPU_GET(cpuid);
+ if (sc->sc_dp[cpu].dp_regs_mapped)
+ goto out;
+
+ tlb1_set_entry(rman_get_bushandle(sc->sc_rres[0]),
+ sc->sc_dp[cpu].dp_ce_pa, sc->sc_dp[cpu].dp_ce_size,
+ _TLB_ENTRY_MEM);
+ tlb1_set_entry(rman_get_bushandle(sc->sc_rres[1]),
+ sc->sc_dp[cpu].dp_ci_pa, sc->sc_dp[cpu].dp_ci_size,
+ _TLB_ENTRY_IO);
+
+ sc->sc_dp[cpu].dp_regs_mapped = 1;
+
+out:
+ sched_unpin();
+}
diff --git a/sys/dev/dpaa/qman.c b/sys/dev/dpaa/qman.c
new file mode 100644
index 0000000..69de8ab
--- /dev/null
+++ b/sys/dev/dpaa/qman.c
@@ -0,0 +1,555 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/rman.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <machine/tlb.h>
+
+#include "qman.h"
+#include "portals.h"
+
+extern struct dpaa_portals_softc *qp_sc;
+static struct qman_softc *qman_sc;
+
+extern t_Handle qman_portal_setup(struct qman_softc *qsc);
+
+static void
+qman_exception(t_Handle app, e_QmExceptions exception)
+{
+ struct qman_softc *sc;
+ const char *message;
+
+ sc = app;
+
+ switch (exception) {
+ case e_QM_EX_CORENET_INITIATOR_DATA:
+ message = "Initiator Data Error";
+ break;
+ case e_QM_EX_CORENET_TARGET_DATA:
+ message = "CoreNet Target Data Error";
+ break;
+ case e_QM_EX_CORENET_INVALID_TARGET_TRANSACTION:
+ message = "Invalid Target Transaction";
+ break;
+ case e_QM_EX_PFDR_THRESHOLD:
+ message = "PFDR Low Watermark Interrupt";
+ break;
+ case e_QM_EX_PFDR_ENQUEUE_BLOCKED:
+ message = "PFDR Enqueues Blocked Interrupt";
+ break;
+ case e_QM_EX_SINGLE_ECC:
+ message = "Single Bit ECC Error Interrupt";
+ break;
+ case e_QM_EX_MULTI_ECC:
+ message = "Multi Bit ECC Error Interrupt";
+ break;
+ case e_QM_EX_INVALID_COMMAND:
+ message = "Invalid Command Verb Interrupt";
+ break;
+ case e_QM_EX_DEQUEUE_DCP:
+ message = "Invalid Dequeue Direct Connect Portal Interrupt";
+ break;
+ case e_QM_EX_DEQUEUE_FQ:
+ message = "Invalid Dequeue FQ Interrupt";
+ break;
+ case e_QM_EX_DEQUEUE_SOURCE:
+ message = "Invalid Dequeue Source Interrupt";
+ break;
+ case e_QM_EX_DEQUEUE_QUEUE:
+ message = "Invalid Dequeue Queue Interrupt";
+ break;
+ case e_QM_EX_ENQUEUE_OVERFLOW:
+ message = "Invalid Enqueue Overflow Interrupt";
+ break;
+ case e_QM_EX_ENQUEUE_STATE:
+ message = "Invalid Enqueue State Interrupt";
+ break;
+ case e_QM_EX_ENQUEUE_CHANNEL:
+ message = "Invalid Enqueue Channel Interrupt";
+ break;
+ case e_QM_EX_ENQUEUE_QUEUE:
+ message = "Invalid Enqueue Queue Interrupt";
+ break;
+ case e_QM_EX_CG_STATE_CHANGE:
+ message = "CG change state notification";
+ break;
+ default:
+ message = "Unknown error";
+ }
+
+ device_printf(sc->sc_dev, "QMan Exception: %s.\n", message);
+}
+
+/**
+ * General received frame callback.
+ * This is called, when user did not register his own callback for a given
+ * frame queue range (fqr).
+ */
+e_RxStoreResponse
+qman_received_frame_callback(t_Handle app, t_Handle qm_fqr, t_Handle qm_portal,
+ uint32_t fqid_offset, t_DpaaFD *frame)
+{
+ struct qman_softc *sc;
+
+ sc = app;
+
+ device_printf(sc->sc_dev, "dummy callback for received frame.\n");
+ return (e_RX_STORE_RESPONSE_CONTINUE);
+}
+
+/**
+ * General rejected frame callback.
+ * This is called, when user did not register his own callback for a given
+ * frame queue range (fqr).
+ */
+e_RxStoreResponse
+qman_rejected_frame_callback(t_Handle app, t_Handle qm_fqr, t_Handle qm_portal,
+ uint32_t fqid_offset, t_DpaaFD *frame,
+ t_QmRejectedFrameInfo *qm_rejected_frame_info)
+{
+ struct qman_softc *sc;
+
+ sc = app;
+
+ device_printf(sc->sc_dev, "dummy callback for rejected frame.\n");
+ return (e_RX_STORE_RESPONSE_CONTINUE);
+}
+
+int
+qman_attach(device_t dev)
+{
+ struct qman_softc *sc;
+ t_QmParam qp;
+ t_Error error;
+ t_QmRevisionInfo rev;
+
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+ qman_sc = sc;
+
+ if (XX_MallocSmartInit() != E_OK) {
+ device_printf(dev, "could not initialize smart allocator.\n");
+ return (ENXIO);
+ }
+
+ sched_pin();
+
+ /* Allocate resources */
+ sc->sc_rrid = 0;
+ sc->sc_rres = bus_alloc_resource(dev, SYS_RES_MEMORY,
+ &sc->sc_rrid, 0, ~0, QMAN_CCSR_SIZE, RF_ACTIVE);
+ if (sc->sc_rres == NULL) {
+ device_printf(dev, "could not allocate memory.\n");
+ goto err;
+ }
+
+ sc->sc_irid = 0;
+ sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
+ if (sc->sc_ires == NULL) {
+ device_printf(dev, "could not allocate error interrupt.\n");
+ goto err;
+ }
+
+ if (qp_sc == NULL)
+ goto err;
+
+ dpaa_portal_map_registers(qp_sc);
+
+ /* Initialize QMan */
+ qp.guestId = NCSW_MASTER_ID;
+ qp.baseAddress = rman_get_bushandle(sc->sc_rres);
+ qp.swPortalsBaseAddress = rman_get_bushandle(qp_sc->sc_rres[0]);
+ qp.liodn = 0;
+ qp.totalNumOfFqids = QMAN_MAX_FQIDS;
+ qp.fqdMemPartitionId = NCSW_MASTER_ID;
+ qp.pfdrMemPartitionId = NCSW_MASTER_ID;
+ qp.f_Exception = qman_exception;
+ qp.h_App = sc;
+ qp.errIrq = (int)sc->sc_ires;
+ qp.partFqidBase = QMAN_FQID_BASE;
+ qp.partNumOfFqids = QMAN_MAX_FQIDS;
+ qp.partCgsBase = 0;
+ qp.partNumOfCgs = 0;
+
+ sc->sc_qh = QM_Config(&qp);
+ if (sc->sc_qh == NULL) {
+ device_printf(dev, "could not be configured\n");
+ goto err;
+ }
+
+ error = QM_Init(sc->sc_qh);
+ if (error != E_OK) {
+ device_printf(dev, "could not be initialized\n");
+ goto err;
+ }
+
+ error = QM_GetRevision(sc->sc_qh, &rev);
+ if (error != E_OK) {
+ device_printf(dev, "could not get QMan revision\n");
+ goto err;
+ }
+
+ device_printf(dev, "Hardware version: %d.%d.\n",
+ rev.majorRev, rev.minorRev);
+
+ sched_unpin();
+
+ qman_portal_setup(sc);
+
+ return (0);
+
+err:
+ sched_unpin();
+ qman_detach(dev);
+ return (ENXIO);
+}
+
+int
+qman_detach(device_t dev)
+{
+ struct qman_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (sc->sc_qh)
+ QM_Free(sc->sc_qh);
+
+ if (sc->sc_ires != NULL)
+ XX_DeallocIntr((int)sc->sc_ires);
+
+ if (sc->sc_ires != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->sc_irid, sc->sc_ires);
+
+ if (sc->sc_rres != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->sc_rrid, sc->sc_rres);
+
+ return (0);
+}
+
+int
+qman_suspend(device_t dev)
+{
+
+ return (0);
+}
+
+int
+qman_resume(device_t dev)
+{
+
+ return (0);
+}
+
+int
+qman_shutdown(device_t dev)
+{
+
+ return (0);
+}
+
+
+/**
+ * @group QMan API functions implementation.
+ * @{
+ */
+
+t_Handle
+qman_fqr_create(uint32_t fqids_num, e_QmFQChannel channel, uint8_t wq,
+ bool force_fqid, uint32_t fqid_or_align, bool init_parked,
+ bool hold_active, bool prefer_in_cache, bool congst_avoid_ena,
+ t_Handle congst_group, int8_t overhead_accounting_len,
+ uint32_t tail_drop_threshold)
+{
+ struct qman_softc *sc;
+ t_QmFqrParams fqr;
+ unsigned int cpu;
+ t_Handle fqrh, portal;
+
+ sc = qman_sc;
+
+ sched_pin();
+ cpu = PCPU_GET(cpuid);
+
+ /* Ensure we have got QMan port initialized */
+ portal = qman_portal_setup(sc);
+ if (portal == NULL) {
+ device_printf(sc->sc_dev, "could not setup QMan portal\n");
+ goto err;
+ }
+
+ fqr.h_Qm = sc->sc_qh;
+ fqr.h_QmPortal = portal;
+ fqr.initParked = init_parked;
+ fqr.holdActive = hold_active;
+ fqr.preferInCache = prefer_in_cache;
+
+ /* We do not support stashing */
+ fqr.useContextAForStash = FALSE;
+ fqr.p_ContextA = 0;
+ fqr.p_ContextB = 0;
+
+ fqr.channel = channel;
+ fqr.wq = wq;
+ fqr.shadowMode = FALSE;
+ fqr.numOfFqids = fqids_num;
+
+ /* FQID */
+ fqr.useForce = force_fqid;
+ if (force_fqid) {
+ fqr.qs.frcQ.fqid = fqid_or_align;
+ } else {
+ fqr.qs.nonFrcQs.align = fqid_or_align;
+ }
+
+ /* Congestion Avoidance */
+ fqr.congestionAvoidanceEnable = congst_avoid_ena;
+ if (congst_avoid_ena) {
+ fqr.congestionAvoidanceParams.h_QmCg = congst_group;
+ fqr.congestionAvoidanceParams.overheadAccountingLength =
+ overhead_accounting_len;
+ fqr.congestionAvoidanceParams.fqTailDropThreshold =
+ tail_drop_threshold;
+ } else {
+ fqr.congestionAvoidanceParams.h_QmCg = 0;
+ fqr.congestionAvoidanceParams.overheadAccountingLength = 0;
+ fqr.congestionAvoidanceParams.fqTailDropThreshold = 0;
+ }
+
+ fqrh = QM_FQR_Create(&fqr);
+ if (fqrh == NULL) {
+ device_printf(sc->sc_dev, "could not create Frame Queue Range"
+ "\n");
+ goto err;
+ }
+
+ sc->sc_fqr_cpu[QM_FQR_GetFqid(fqrh)] = PCPU_GET(cpuid);
+
+ sched_unpin();
+
+ return (fqrh);
+
+err:
+ sched_unpin();
+
+ return (NULL);
+}
+
+t_Error
+qman_fqr_free(t_Handle fqr)
+{
+ struct qman_softc *sc;
+ t_Error error;
+
+ sc = qman_sc;
+ thread_lock(curthread);
+ sched_bind(curthread, sc->sc_fqr_cpu[QM_FQR_GetFqid(fqr)]);
+ thread_unlock(curthread);
+
+ error = QM_FQR_Free(fqr);
+
+ thread_lock(curthread);
+ sched_unbind(curthread);
+ thread_unlock(curthread);
+
+ return (error);
+}
+
+t_Error
+qman_fqr_register_cb(t_Handle fqr, t_QmReceivedFrameCallback *callback,
+ t_Handle app)
+{
+ struct qman_softc *sc;
+ t_Error error;
+ t_Handle portal;
+
+ sc = qman_sc;
+ sched_pin();
+
+ /* Ensure we have got QMan port initialized */
+ portal = qman_portal_setup(sc);
+ if (portal == NULL) {
+ device_printf(sc->sc_dev, "could not setup QMan portal\n");
+ sched_unpin();
+ return (E_NOT_SUPPORTED);
+ }
+
+ error = QM_FQR_RegisterCB(fqr, callback, app);
+
+ sched_unpin();
+
+ return (error);
+}
+
+t_Error
+qman_fqr_enqueue(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame)
+{
+ struct qman_softc *sc;
+ t_Error error;
+ t_Handle portal;
+
+ sc = qman_sc;
+ sched_pin();
+
+ /* Ensure we have got QMan port initialized */
+ portal = qman_portal_setup(sc);
+ if (portal == NULL) {
+ device_printf(sc->sc_dev, "could not setup QMan portal\n");
+ sched_unpin();
+ return (E_NOT_SUPPORTED);
+ }
+
+ error = QM_FQR_Enqueue(fqr, portal, fqid_off, frame);
+
+ sched_unpin();
+
+ return (error);
+}
+
+uint32_t
+qman_fqr_get_counter(t_Handle fqr, uint32_t fqid_off,
+ e_QmFqrCounters counter)
+{
+ struct qman_softc *sc;
+ uint32_t val;
+ t_Handle portal;
+
+ sc = qman_sc;
+ sched_pin();
+
+ /* Ensure we have got QMan port initialized */
+ portal = qman_portal_setup(sc);
+ if (portal == NULL) {
+ device_printf(sc->sc_dev, "could not setup QMan portal\n");
+ sched_unpin();
+ return (0);
+ }
+
+ val = QM_FQR_GetCounter(fqr, portal, fqid_off, counter);
+
+ sched_unpin();
+
+ return (val);
+}
+
+t_Error
+qman_fqr_pull_frame(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame)
+{
+ struct qman_softc *sc;
+ t_Error error;
+ t_Handle portal;
+
+ sc = qman_sc;
+ sched_pin();
+
+ /* Ensure we have got QMan port initialized */
+ portal = qman_portal_setup(sc);
+ if (portal == NULL) {
+ device_printf(sc->sc_dev, "could not setup QMan portal\n");
+ sched_unpin();
+ return (E_NOT_SUPPORTED);
+ }
+
+ error = QM_FQR_PullFrame(fqr, portal, fqid_off, frame);
+
+ sched_unpin();
+
+ return (error);
+}
+
+uint32_t
+qman_fqr_get_base_fqid(t_Handle fqr)
+{
+ struct qman_softc *sc;
+ uint32_t val;
+ t_Handle portal;
+
+ sc = qman_sc;
+ sched_pin();
+
+ /* Ensure we have got QMan port initialized */
+ portal = qman_portal_setup(sc);
+ if (portal == NULL) {
+ device_printf(sc->sc_dev, "could not setup QMan portal\n");
+ sched_unpin();
+ return (0);
+ }
+
+ val = QM_FQR_GetFqid(fqr);
+
+ sched_unpin();
+
+ return (val);
+}
+
+t_Error
+qman_poll(e_QmPortalPollSource source)
+{
+ struct qman_softc *sc;
+ t_Error error;
+ t_Handle portal;
+
+ sc = qman_sc;
+ sched_pin();
+
+ /* Ensure we have got QMan port initialized */
+ portal = qman_portal_setup(sc);
+ if (portal == NULL) {
+ device_printf(sc->sc_dev, "could not setup QMan portal\n");
+ sched_unpin();
+ return (E_NOT_SUPPORTED);
+ }
+
+ error = QM_Poll(sc->sc_qh, source);
+
+ sched_unpin();
+
+ return (error);
+}
+
+/*
+ * TODO: add polling and/or congestion support.
+ */
+
+/** @} */
diff --git a/sys/dev/dpaa/qman.h b/sys/dev/dpaa/qman.h
new file mode 100644
index 0000000..97331bb
--- /dev/null
+++ b/sys/dev/dpaa/qman.h
@@ -0,0 +1,246 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _QMAN_H
+#define _QMAN_H
+
+#include <machine/vmparam.h>
+
+#include <contrib/ncsw/inc/Peripherals/qm_ext.h>
+
+
+/**
+ * @group QMan private defines/declarations
+ * @{
+ */
+/**
+ * Maximum number of frame queues in all QMans.
+ */
+#define QMAN_MAX_FQIDS 16
+
+/**
+ * Pool channel common to all software portals.
+ * @note Value of 0 reflects the e_QM_FQ_CHANNEL_POOL1 from e_QmFQChannel
+ * type used in qman_fqr_create().
+ */
+#define QMAN_COMMON_POOL_CHANNEL 0
+
+#define QMAN_FQID_BASE 1
+
+#define QMAN_CCSR_SIZE 0x1000
+
+/*
+ * Portal defines
+ */
+#define QMAN_CE_PA(base) (base)
+#define QMAN_CI_PA(base) ((base) + 0x100000)
+
+#define QMAN_PORTAL_CE_PA(base, n) \
+ (QMAN_CE_PA(base) + ((n) * QMAN_PORTAL_CE_SIZE))
+#define QMAN_PORTAL_CI_PA(base, n) \
+ (QMAN_CI_PA(base) + ((n) * QMAN_PORTAL_CI_SIZE))
+
+struct qman_softc {
+ device_t sc_dev; /* device handle */
+ int sc_rrid; /* register rid */
+ struct resource *sc_rres; /* register resource */
+ int sc_irid; /* interrupt rid */
+ struct resource *sc_ires; /* interrupt resource */
+
+ bool sc_regs_mapped[MAXCPU];
+
+ t_Handle sc_qh; /* QMAN handle */
+ t_Handle sc_qph[MAXCPU]; /* QMAN portal handles */
+ vm_paddr_t sc_qp_pa; /* QMAN portal PA */
+
+ int sc_fqr_cpu[QMAN_MAX_FQIDS];
+};
+/** @> */
+
+
+/**
+ * @group QMan bus interface
+ * @{
+ */
+int qman_attach(device_t dev);
+int qman_detach(device_t dev);
+int qman_suspend(device_t dev);
+int qman_resume(device_t dev);
+int qman_shutdown(device_t dev);
+/** @> */
+
+
+/**
+ * @group QMan API
+ * @{
+ */
+
+/**
+ * Create Frame Queue Range.
+ *
+ * @param fqids_num Number of frame queues in the range.
+ *
+ * @param channel Dedicated channel serviced by this
+ * Frame Queue Range.
+ *
+ * @param wq Work Queue Number within the channel.
+ *
+ * @param force_fqid If TRUE, fore allocation of specific
+ * FQID. Notice that there can not be two
+ * frame queues with the same ID in the
+ * system.
+ *
+ * @param fqid_or_align FQID if @force_fqid == TRUE, alignment
+ * of FQIDs entries otherwise.
+ *
+ * @param init_parked If TRUE, FQ state is initialized to
+ * "parked" state on creation. Otherwise,
+ * to "scheduled" state.
+ *
+ * @param hold_active If TRUE, the FQ may be held in the
+ * portal in "held active" state in
+ * anticipation of more frames being
+ * dequeued from it after the head frame
+ * is removed from the FQ and the dequeue
+ * response is returned. If FALSE the
+ * "held_active" state of the FQ is not
+ * allowed. This affects only on queues
+ * destined to software portals. Refer to
+ * the 6.3.4.6 of DPAA Reference Manual.
+ *
+ * @param prefer_in_cache If TRUE, prefer this FQR to be in QMan
+ * internal cache memory for all states.
+ *
+ * @param congst_avoid_ena If TRUE, enable congestion avoidance
+ * mechanism.
+ *
+ * @param congst_group A handle to the congestion group. Only
+ * relevant when @congst_avoid_ena == TRUE.
+ *
+ * @param overhead_accounting_len For each frame add this number for CG
+ * calculation (may be negative), if 0 -
+ * disable feature.
+ *
+ * @param tail_drop_threshold If not 0 - enable tail drop on this
+ * FQR.
+ *
+ * @return A handle to newly created FQR object.
+ */
+t_Handle qman_fqr_create(uint32_t fqids_num, e_QmFQChannel channel, uint8_t wq,
+ bool force_fqid, uint32_t fqid_or_align, bool init_parked,
+ bool hold_active, bool prefer_in_cache, bool congst_avoid_ena,
+ t_Handle congst_group, int8_t overhead_accounting_len,
+ uint32_t tail_drop_threshold);
+
+/**
+ * Free Frame Queue Range.
+ *
+ * @param fqr A handle to FQR to be freed.
+ * @return E_OK on success; error code otherwise.
+ */
+t_Error qman_fqr_free(t_Handle fqr);
+
+/**
+ * Register the callback function.
+ * The callback function will be called when a frame comes from this FQR.
+ *
+ * @param fqr A handle to FQR.
+ * @param callback A pointer to the callback function.
+ * @param app A pointer to the user's data.
+ * @return E_OK on success; error code otherwise.
+ */
+t_Error qman_fqr_register_cb(t_Handle fqr, t_QmReceivedFrameCallback *callback,
+ t_Handle app);
+
+/**
+ * Enqueue a frame on a given FQR.
+ *
+ * @param fqr A handle to FQR.
+ * @param fqid_off FQID offset wihin the FQR.
+ * @param frame A frame to be enqueued to the transmission.
+ * @return E_OK on success; error code otherwise.
+ */
+t_Error qman_fqr_enqueue(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame);
+
+/**
+ * Get one of the FQR counter's value.
+ *
+ * @param fqr A handle to FQR.
+ * @param fqid_off FQID offset within the FQR.
+ * @param counter The requested counter.
+ * @return Counter's current value.
+ */
+uint32_t qman_fqr_get_counter(t_Handle fqr, uint32_t fqid_off,
+ e_QmFqrCounters counter);
+
+/**
+ * Pull frame from FQR.
+ *
+ * @param fqr A handle to FQR.
+ * @param fqid_off FQID offset within the FQR.
+ * @param frame The received frame.
+ * @return E_OK on success; error code otherwise.
+ */
+t_Error qman_fqr_pull_frame(t_Handle fqr, uint32_t fqid_off, t_DpaaFD *frame);
+
+/**
+ * Get base FQID of the FQR.
+ * @param fqr A handle to FQR.
+ * @return Base FQID of the FQR.
+ */
+uint32_t qman_fqr_get_base_fqid(t_Handle fqr);
+
+/**
+ * Poll frames from QMan.
+ * This polls frames from the current software portal.
+ *
+ * @param source Type of frames to be polled.
+ * @return E_OK on success; error otherwise.
+ */
+t_Error qman_poll(e_QmPortalPollSource source);
+
+/**
+ * General received frame callback.
+ * This is called, when user did not register his own callback for a given
+ * frame queue range (fqr).
+ */
+e_RxStoreResponse qman_received_frame_callback(t_Handle app, t_Handle qm_fqr,
+ t_Handle qm_portal, uint32_t fqid_offset, t_DpaaFD *frame);
+
+/**
+ * General rejected frame callback.
+ * This is called, when user did not register his own callback for a given
+ * frame queue range (fqr).
+ */
+e_RxStoreResponse qman_rejected_frame_callback(t_Handle app, t_Handle qm_fqr,
+ t_Handle qm_portal, uint32_t fqid_offset, t_DpaaFD *frame,
+ t_QmRejectedFrameInfo *qm_rejected_frame_info);
+
+/** @} */
+
+#endif /* QMAN_H */
diff --git a/sys/dev/dpaa/qman_fdt.c b/sys/dev/dpaa/qman_fdt.c
new file mode 100644
index 0000000..4df8c05
--- /dev/null
+++ b/sys/dev/dpaa/qman_fdt.c
@@ -0,0 +1,221 @@
+/*-
+ * Copyright (c) 2011-2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_platform.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_subr.h>
+
+#include "qman.h"
+#include "portals.h"
+
+#define FBMAN_DEVSTR "Freescale Queue Manager"
+
+static int qman_fdt_probe(device_t);
+
+static device_method_t qman_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, qman_fdt_probe),
+ DEVMETHOD(device_attach, qman_attach),
+ DEVMETHOD(device_detach, qman_detach),
+
+ DEVMETHOD(device_suspend, qman_suspend),
+ DEVMETHOD(device_resume, qman_resume),
+ DEVMETHOD(device_shutdown, qman_shutdown),
+
+ { 0, 0 }
+};
+
+static driver_t qman_driver = {
+ "qman",
+ qman_methods,
+ sizeof(struct qman_softc),
+};
+
+static devclass_t qman_devclass;
+DRIVER_MODULE(qman, simplebus, qman_driver, qman_devclass, 0, 0);
+
+static int
+qman_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "fsl,qman"))
+ return (ENXIO);
+
+ device_set_desc(dev, FBMAN_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+/*
+ * BMAN Portals
+ */
+#define BMAN_PORT_DEVSTR "Freescale Queue Manager - Portals"
+
+static device_probe_t qman_portals_fdt_probe;
+static device_attach_t qman_portals_fdt_attach;
+
+static device_method_t bm_portals_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, qman_portals_fdt_probe),
+ DEVMETHOD(device_attach, qman_portals_fdt_attach),
+ DEVMETHOD(device_detach, qman_portals_detach),
+
+ { 0, 0 }
+};
+
+static driver_t bm_portals_driver = {
+ "qman-portals",
+ bm_portals_methods,
+ sizeof(struct dpaa_portals_softc),
+};
+
+static devclass_t bm_portals_devclass;
+DRIVER_MODULE(qman_portals, ofwbus, bm_portals_driver, bm_portals_devclass, 0, 0);
+
+static void
+get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep)
+{
+
+ *addrp = 2;
+ *sizep = 1;
+ OF_getencprop(node, "#address-cells", addrp, sizeof(*addrp));
+ OF_getencprop(node, "#size-cells", sizep, sizeof(*sizep));
+}
+
+static int
+qman_portals_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_is_compatible(dev, "qman-portals"))
+ return (ENXIO);
+
+ device_set_desc(dev, BMAN_PORT_DEVSTR);
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+qman_portals_fdt_attach(device_t dev)
+{
+ struct dpaa_portals_softc *sc;
+ struct resource_list_entry *rle;
+ phandle_t node, child, cpu_node;
+ vm_paddr_t portal_pa;
+ vm_size_t portal_size;
+ uint32_t addr, size;
+ ihandle_t cpu;
+ int cpu_num, cpus, intr_rid;
+ struct dpaa_portals_devinfo di;
+ struct ofw_bus_devinfo ofw_di;
+
+ cpus = 0;
+ sc = device_get_softc(dev);
+ sc->sc_dev = dev;
+
+ node = ofw_bus_get_node(dev);
+ get_addr_props(node, &addr, &size);
+
+ /* Find portals tied to CPUs */
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ if (!fdt_is_compatible(child, "fsl,qman-portal")) {
+ continue;
+ }
+ /* Checkout related cpu */
+ if (OF_getprop(child, "cpu-handle", (void *)&cpu,
+ sizeof(cpu)) <= 0) {
+ continue;
+ }
+ /* Acquire cpu number */
+ cpu_node = OF_instance_to_package(cpu);
+ if (OF_getencprop(cpu_node, "reg", &cpu_num, sizeof(cpu_num)) <= 0) {
+ device_printf(dev, "Could not retrieve CPU number.\n");
+ return (ENXIO);
+ }
+
+ cpus++;
+
+ if (cpus > MAXCPU)
+ break;
+
+ if (ofw_bus_gen_setup_devinfo(&ofw_di, child) != 0) {
+ device_printf(dev, "could not set up devinfo\n");
+ continue;
+ }
+
+ resource_list_init(&di.di_res);
+ if (ofw_bus_reg_to_rl(dev, child, addr, size, &di.di_res)) {
+ device_printf(dev, "%s: could not process 'reg' "
+ "property\n", ofw_di.obd_name);
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+ continue;
+ }
+ if (ofw_bus_intr_to_rl(dev, child, &di.di_res, &intr_rid)) {
+ device_printf(dev, "%s: could not process "
+ "'interrupts' property\n", ofw_di.obd_name);
+ resource_list_free(&di.di_res);
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+ continue;
+ }
+ di.di_intr_rid = intr_rid;
+
+ ofw_reg_to_paddr(child, 0, &portal_pa, &portal_size, NULL);
+ rle = resource_list_find(&di.di_res, SYS_RES_MEMORY, 0);
+
+ if (sc->sc_dp_pa == 0)
+ sc->sc_dp_pa = portal_pa - rle->start;
+
+ portal_size = rle->end + 1;
+ rle = resource_list_find(&di.di_res, SYS_RES_MEMORY, 1);
+ portal_size = ulmax(rle->end + 1, portal_size);
+ sc->sc_dp_size = ulmax(sc->sc_dp_size, portal_size);
+
+ if (dpaa_portal_alloc_res(dev, &di, cpu_num))
+ goto err;
+ }
+
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+
+ return (qman_portals_attach(dev));
+err:
+ resource_list_free(&di.di_res);
+ ofw_bus_gen_destroy_devinfo(&ofw_di);
+ qman_portals_detach(dev);
+ return (ENXIO);
+}
diff --git a/sys/dev/dpaa/qman_portals.c b/sys/dev/dpaa/qman_portals.c
new file mode 100644
index 0000000..8f39307
--- /dev/null
+++ b/sys/dev/dpaa/qman_portals.c
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_platform.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/sched.h>
+
+#include <machine/bus.h>
+#include <machine/tlb.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <powerpc/mpc85xx/mpc85xx.h>
+
+#include "qman.h"
+#include "portals.h"
+
+extern e_RxStoreResponse qman_received_frame_callback(t_Handle, t_Handle,
+ t_Handle, uint32_t, t_DpaaFD *);
+extern e_RxStoreResponse qman_rejected_frame_callback(t_Handle, t_Handle,
+ t_Handle, uint32_t, t_DpaaFD *, t_QmRejectedFrameInfo *);
+
+t_Handle qman_portal_setup(struct qman_softc *);
+
+struct dpaa_portals_softc *qp_sc;
+
+int
+qman_portals_attach(device_t dev)
+{
+ struct dpaa_portals_softc *sc;
+
+ sc = qp_sc = device_get_softc(dev);
+
+ /* Map bman portal to physical address space */
+ if (law_enable(OCP85XX_TGTIF_QMAN, sc->sc_dp_pa, sc->sc_dp_size)) {
+ qman_portals_detach(dev);
+ return (ENXIO);
+ }
+ /* Set portal properties for XX_VirtToPhys() */
+ XX_PortalSetInfo(dev);
+
+ return (bus_generic_attach(dev));
+}
+
+int
+qman_portals_detach(device_t dev)
+{
+ struct dpaa_portals_softc *sc;
+ int i;
+
+ qp_sc = NULL;
+ sc = device_get_softc(dev);
+
+ for (i = 0; i < ARRAY_SIZE(sc->sc_dp); i++) {
+ if (sc->sc_dp[i].dp_ph != NULL) {
+ thread_lock(curthread);
+ sched_bind(curthread, i);
+ thread_unlock(curthread);
+
+ QM_PORTAL_Free(sc->sc_dp[i].dp_ph);
+
+ thread_lock(curthread);
+ sched_unbind(curthread);
+ thread_unlock(curthread);
+ }
+
+ if (sc->sc_dp[i].dp_ires != NULL) {
+ XX_DeallocIntr((int)sc->sc_dp[i].dp_ires);
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->sc_dp[i].dp_irid, sc->sc_dp[i].dp_ires);
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(sc->sc_rres); i++) {
+ if (sc->sc_rres[i] != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->sc_rrid[i],
+ sc->sc_rres[i]);
+ }
+
+ return (0);
+}
+
+t_Handle
+qman_portal_setup(struct qman_softc *qsc)
+{
+ struct dpaa_portals_softc *sc;
+ t_QmPortalParam qpp;
+ unsigned int cpu, p;
+ t_Handle portal;
+
+ /* Return NULL if we're not ready or while detach */
+ if (qp_sc == NULL)
+ return (NULL);
+
+ sc = qp_sc;
+
+ sched_pin();
+ portal = NULL;
+ cpu = PCPU_GET(cpuid);
+
+ /* Check if portal is ready */
+ while (atomic_cmpset_acq_32((uint32_t *)&sc->sc_dp[cpu].dp_ph,
+ 0, -1) == 0) {
+ p = atomic_load_acq_32((uint32_t *)&sc->sc_dp[cpu].dp_ph);
+
+ /* Return if portal is already initialized */
+ if (p != 0 && p != -1) {
+ sched_unpin();
+ return ((t_Handle)p);
+ }
+
+ /* Not inititialized and "owned" by another thread */
+ thread_lock(curthread);
+ mi_switch(SW_VOL, NULL);
+ thread_unlock(curthread);
+ }
+
+ /* Map portal registers */
+ dpaa_portal_map_registers(sc);
+
+ /* Configure and initialize portal */
+ qpp.ceBaseAddress = rman_get_bushandle(sc->sc_rres[0]);
+ qpp.ciBaseAddress = rman_get_bushandle(sc->sc_rres[1]);
+ qpp.h_Qm = qsc->sc_qh;
+ qpp.swPortalId = cpu;
+ qpp.irq = (int)sc->sc_dp[cpu].dp_ires;
+ qpp.fdLiodnOffset = 0;
+ qpp.f_DfltFrame = qman_received_frame_callback;
+ qpp.f_RejectedFrame = qman_rejected_frame_callback;
+ qpp.h_App = qsc;
+
+ portal = QM_PORTAL_Config(&qpp);
+ if (portal == NULL)
+ goto err;
+
+ if (QM_PORTAL_Init(portal) != E_OK)
+ goto err;
+
+ if (QM_PORTAL_AddPoolChannel(portal, QMAN_COMMON_POOL_CHANNEL) != E_OK)
+ goto err;
+
+ atomic_store_rel_32((uint32_t *)&sc->sc_dp[cpu].dp_ph,
+ (uint32_t)portal);
+ sched_unpin();
+
+ return (portal);
+
+err:
+ if (portal != NULL)
+ QM_PORTAL_Free(portal);
+
+ atomic_store_rel_32((uint32_t *)&sc->sc_dp[cpu].dp_ph, 0);
+ sched_unpin();
+
+ return (NULL);
+}
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 2b883b8..54f215a 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -198,7 +198,6 @@ static void tid_flush(tlbtid_t tid);
static void tlb_print_entry(int, uint32_t, uint32_t, uint32_t, uint32_t);
-static int tlb1_set_entry(vm_offset_t, vm_paddr_t, vm_size_t, uint32_t);
static void tlb1_write_entry(unsigned int);
static int tlb1_iomapped(int, vm_paddr_t, vm_size_t, vm_offset_t *);
static vm_size_t tlb1_mapin_region(vm_offset_t, vm_paddr_t, vm_size_t);
@@ -3203,7 +3202,7 @@ size2tsize(vm_size_t size)
* Entries are created starting from index 0 (current free entry is
* kept in tlb1_idx) and are not supposed to be invalidated.
*/
-static int
+int
tlb1_set_entry(vm_offset_t va, vm_paddr_t pa, vm_size_t size,
uint32_t flags)
{
diff --git a/sys/powerpc/conf/dpaa/DPAA b/sys/powerpc/conf/dpaa/DPAA
new file mode 100644
index 0000000..e5c7e9e
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/DPAA
@@ -0,0 +1,101 @@
+#
+# Common kernel config for Freescale QorIQ DPAA development boards like the
+# P2041RDB, P3041DS and P5020DS.
+#
+# This is not standalone kernel config. Use it only for including
+# purposes.
+#
+# $FreeBSD$
+
+cpu BOOKE
+cpu BOOKE_E500
+
+machine powerpc powerpc
+#makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+makeoptions WERROR="-Werror -Wno-format -Wno-redundant-decls"
+makeoptions NO_MODULES=yes
+
+# Platform support
+options QORIQ_DPAA #Freescale SoC family
+
+options SMP #Symmetric Multi Processing
+
+#options SCHED_4BSD #4BSD scheduler
+options INET #InterNETworking
+options INET6 #IPv6 communications protocols
+options FFS #Berkeley Fast Filesystem
+options NFSCL #New Network Filesystem Client
+options SOFTUPDATES #Enable FFS soft updates support
+options PROCFS #Process filesystem (requires PSEUDOFS)
+options PSEUDOFS #Pseudo-filesystem framework
+options GEOM_PART_GPT #GUID Partition Tables.
+options GEOM_LABEL
+options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!]
+options SYSVSHM #SYSV-style shared memory
+options SYSVMSG #SYSV-style message queues
+options SYSVSEM #SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
+options NO_SWAPPING
+
+options KDB #Enable the kernel debugger
+options DDB #Support DDB
+options GDB
+
+options ALT_BREAK_TO_DEBUGGER
+options BREAK_TO_DEBUGGER
+options DIAGNOSTIC
+options INVARIANTS #Enable calls of extra sanity checking
+options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS
+
+options KTR
+options KTR_COMPILE=0xffffffff
+options KTR_MASK=KTR_PMAP
+options KTR_ENTRIES=8192
+
+options WITNESS #Enable checks to detect deadlocks and cycles
+#options WITNESS_KDB
+
+# RamFS Root
+#options GEOM_UZIP
+#options MD_ROOT
+#options MD_ROOT_SIZE=10240
+
+# Netbooting
+options BOOTP
+options BOOTP_NFSROOT
+options BOOTP_NFSV3
+options BOOTP_WIRED_TO=dtsec3
+options NFS_ROOT
+
+# Block devices
+device mmc
+device mmcsd
+device sdhci
+
+# Network devices
+device miibus # MII bus support
+device em
+
+
+# I2C support
+device iicbus
+device iic
+
+device uart
+device ehci
+device usb
+device scbus
+device da
+device umass
+device pty
+device cfi
+
+device pci
+
+# Pseudo devices
+device ether # Ethernet support
+device loop # Network loopback
+device random # Entropy device
+device bpf # Berkeley packet filter
+device md # Memory "disks"
+
diff --git a/sys/powerpc/conf/dpaa/config.dpaa b/sys/powerpc/conf/dpaa/config.dpaa
new file mode 100644
index 0000000..bc68498
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/config.dpaa
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+makeoptions DPAA_COMPILE_CMD_COMMON="${NORMAL_C} \
+ -Wno-cast-qual -Wno-unused-function -Wno-init-self -fms-extensions \
+ -include $S/contrib/ncsw/build/dflags.h \
+ -I$S/contrib/ncsw/build/ \
+ -I$S/contrib/ncsw/inc \
+ -I$S/contrib/ncsw/inc/cores \
+ -I$S/contrib/ncsw/inc/etc \
+ -I$S/contrib/ncsw/inc/Peripherals \
+ -I$S/contrib/ncsw/etc \
+ -I$S/contrib/ncsw/Peripherals/BM \
+ -I$S/contrib/ncsw/Peripherals/FM \
+ -I$S/contrib/ncsw/Peripherals/FM/HC \
+ -I$S/contrib/ncsw/Peripherals/FM/inc \
+ -I$S/contrib/ncsw/Peripherals/FM/MAC \
+ -I$S/contrib/ncsw/Peripherals/FM/Pcd \
+ -I$S/contrib/ncsw/Peripherals/FM/Port \
+ -I$S/contrib/ncsw/Peripherals/FM/Rtc \
+ -I$S/contrib/ncsw/Peripherals/QM \
+ -I$S/contrib/ncsw/inc/integrations"
diff --git a/sys/powerpc/conf/dpaa/config.p2041 b/sys/powerpc/conf/dpaa/config.p2041
new file mode 100644
index 0000000..4e7bec1
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/config.p2041
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+files "dpaa/files.dpaa"
+files "dpaa/files.p2041"
+
+include "dpaa/config.dpaa"
+
+makeoptions DPAA_COMPILE_CMD="${DPAA_COMPILE_CMD_COMMON} \
+ -I$S/contrib/ncsw/inc/integrations/P2041"
+
+device dpaa
diff --git a/sys/powerpc/conf/dpaa/config.p3041 b/sys/powerpc/conf/dpaa/config.p3041
new file mode 100644
index 0000000..9334de6
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/config.p3041
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+files "dpaa/files.dpaa"
+files "dpaa/files.p3041"
+
+include "dpaa/config.dpaa"
+
+makeoptions DPAA_COMPILE_CMD="${DPAA_COMPILE_CMD_COMMON} \
+ -I$S/contrib/ncsw/inc/integrations/P3041"
+
+device dpaa
diff --git a/sys/powerpc/conf/dpaa/config.p5020 b/sys/powerpc/conf/dpaa/config.p5020
new file mode 100644
index 0000000..28eaeba
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/config.p5020
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+files "dpaa/files.dpaa"
+files "dpaa/files.p5020"
+
+include "dpaa/config.dpaa"
+
+makeoptions DPAA_COMPILE_CMD="${DPAA_COMPILE_CMD_COMMON} \
+ -I$S/contrib/ncsw/inc/integrations/P5020"
+
+device dpaa
diff --git a/sys/powerpc/conf/dpaa/files.dpaa b/sys/powerpc/conf/dpaa/files.dpaa
new file mode 100644
index 0000000..2975838
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/files.dpaa
@@ -0,0 +1,105 @@
+# $FreeBSD$
+
+# NetCommSw drivers
+contrib/ncsw/etc/error.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/etc/list.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/etc/memcpy.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/etc/mm.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/etc/ncsw_mem.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/etc/sprint.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/BM/bm.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/BM/bman_low.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/BM/bm_pool.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/BM/bm_portal.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Rtc/fm_rtc.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Port/fm_port.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Port/fm_port_im.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Pcd/fm_cc.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Pcd/fm_kg.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Pcd/fm_manip.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Pcd/fm_pcd.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Pcd/fm_plcr.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/Pcd/fm_prs.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/MAC/dtsec.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/MAC/dtsec_mii_acc.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/MAC/fm_mac.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/MAC/tgec.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/MAC/tgec_mii_acc.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/HC/hc.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/fm_muram.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/fm_guest.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/FM/fm.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/QM/qm.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/Peripherals/QM/qm_portal_fqr.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/user/env/stdlib.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/user/env/xx.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+contrib/ncsw/user/env/core.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+
+# FreeBSD Wrappers
+dev/dpaa/dpaa.c optional dpaa fdt \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/portals_common.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/bman_portals.c optional dpaa fdt \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/bman.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/bman_fdt.c optional dpaa fdt \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/qman_portals.c optional dpaa fdt \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/qman.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/qman_fdt.c optional dpaa fdt \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/fman.c optional dpaa fdt \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/fman_fdt.c optional dpaa fdt \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/if_dtsec.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/if_dtsec_im.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/if_dtsec_rm.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/if_dtsec_fdt.c optional dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+
+# Examples
+dev/dpaa/bman-example.c optional bman_example dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
+dev/dpaa/qman-example.c optional qman_example dpaa \
+ no-depend compile-with "${DPAA_COMPILE_CMD}"
diff --git a/sys/powerpc/conf/dpaa/files.p2041 b/sys/powerpc/conf/dpaa/files.p2041
new file mode 100644
index 0000000..dfb4afc
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/files.p2041
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+contrib/ncsw/integrations/P2041/module_strings.c optional dpaa
diff --git a/sys/powerpc/conf/dpaa/files.p3041 b/sys/powerpc/conf/dpaa/files.p3041
new file mode 100644
index 0000000..89bb35c
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/files.p3041
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+contrib/ncsw/integrations/P3041/module_strings.c optional dpaa
diff --git a/sys/powerpc/conf/dpaa/files.p5020 b/sys/powerpc/conf/dpaa/files.p5020
new file mode 100644
index 0000000..b442d2e
--- /dev/null
+++ b/sys/powerpc/conf/dpaa/files.p5020
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+contrib/ncsw/integrations/P5020/module_strings.c optional dpaa
diff --git a/sys/powerpc/include/intr_machdep.h b/sys/powerpc/include/intr_machdep.h
index 32a94be..5fbf9ee 100644
--- a/sys/powerpc/include/intr_machdep.h
+++ b/sys/powerpc/include/intr_machdep.h
@@ -58,4 +58,7 @@ int powerpc_bind_intr(u_int irq, u_char cpu);
int powerpc_config_intr(int, enum intr_trigger, enum intr_polarity);
int powerpc_fw_config_intr(int irq, int sense_code);
+void powerpc_intr_mask(u_int irq);
+void powerpc_intr_unmask(u_int irq);
+
#endif /* _MACHINE_INTR_MACHDEP_H_ */
diff --git a/sys/powerpc/include/tlb.h b/sys/powerpc/include/tlb.h
index 8fb7c85..65293bf 100644
--- a/sys/powerpc/include/tlb.h
+++ b/sys/powerpc/include/tlb.h
@@ -121,11 +121,7 @@
#define KERNEL_REGION_MAX_TLB_ENTRIES 4
#define _TLB_ENTRY_IO (MAS2_I | MAS2_G)
-#ifdef SMP
#define _TLB_ENTRY_MEM (MAS2_M)
-#else
-#define _TLB_ENTRY_MEM (0)
-#endif
#if !defined(LOCORE)
typedef struct tlb_entry {
@@ -215,6 +211,7 @@ struct pmap;
void tlb_lock(uint32_t *);
void tlb_unlock(uint32_t *);
+int tlb1_set_entry(vm_offset_t, vm_paddr_t, vm_size_t, uint32_t);
#endif /* !LOCORE */
diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c
index a17d9ff..74dc4f5 100644
--- a/sys/powerpc/powerpc/intr_machdep.c
+++ b/sys/powerpc/powerpc/intr_machdep.c
@@ -615,3 +615,27 @@ stray:
if (i != NULL)
PIC_MASK(i->pic, i->intline);
}
+
+void
+powerpc_intr_mask(u_int irq)
+{
+ struct powerpc_intr *i;
+
+ i = intr_lookup(irq);
+ if (i == NULL || i->pic == NULL)
+ return;
+
+ PIC_MASK(i->pic, i->intline);
+}
+
+void
+powerpc_intr_unmask(u_int irq)
+{
+ struct powerpc_intr *i;
+
+ i = intr_lookup(irq);
+ if (i == NULL || i->pic == NULL)
+ return;
+
+ PIC_UNMASK(i->pic, i->intline);
+}
OpenPOWER on IntegriCloud